# Quickstart Guide

{% stepper %}
{% step %}

### Introduction

This guide provides instructions for deploying the Aiceberg Guardian ICAP server using Docker. This service acts as an ICAP server (RFC 3507) to inspect and protect LLM traffic flowing through an ICAP-compliant proxy (such as Squid).

### Prerequisites

* **Docker** and **Docker Compose** installed on the host machine.
* An **Aiceberg Account** with a valid `Profile ID` and `API Key`.
  {% endstep %}

{% step %}

### Environment Configuration

The service is configured via environment variables. These must be set in a `.env` file in the root directory (see `.env.example`).

#### Credentials (Required)

| Variable              | Description                                                  |
| --------------------- | ------------------------------------------------------------ |
| `AICEBERG_PROFILE_ID` | Your specific policy profile ID from the Aiceberg dashboard. |
| `AICEBERG_API_KEY`    | Your secret API key for authentication.                      |

#### Server Configuration (Optional)

| Variable                         | Default | Description                                                                           |
| -------------------------------- | ------- | ------------------------------------------------------------------------------------- |
| `AICEBERG_ENVIRONMENT`           | `prod`  | Target environment (`prod`, `stag`, `test`).                                          |
| `LLM_SHIELD_ICAP_PORT`           | `1344`  | Host port for the ICAP server. **WARNING**: If changed, you must update `squid.conf`. |
| `SQUID_PORT`                     | `3128`  | Host port for the Squid proxy.                                                        |
| `AICEBERG_LLM_SHIELD_LOG_LEVEL`  | `INFO`  | Logging verbosity (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`).                  |
| `HTTP_BODY_READ_ONLY_FOR_TARGET` | `true`  | If true, body is only read if the URL matches a known target (optimization).          |

{% hint style="warning" %}
If you change `LLM_SHIELD_ICAP_PORT` you must update your proxy configuration (for example `squid.conf`) to point at the new port.
{% endhint %}

#### Advanced Protocol Tuning (RFC/Compatibility)

Use these settings if you encounter parsing errors (e.g., with specific versions of Squid or BlueCoat).

| Variable                            | Default    | Description                                                                                                                                                  |
| ----------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ICAP_HTTP_TRANSFER_ENCODING`       | `chunked`  | Controls the encoding of the *Inner* HTTP body (the modified request payload). Options: `chunked`, `content-length`.                                         |
| `ICAP_ENCAPSULATED_MODE`            | `identity` | Controls the encoding of the *Outer* ICAP message. options: `chunked` (standard), `identity`.                                                                |
| `ICAP_ENCAPSULATED_MODE_INCLUDE_TE` | `false`    | If `true`, explicitly adds `Transfer-Encoding: chunked` to ICAP headers (required for some strict clients).                                                  |
| `ICAP_HEADER_INCLUDE_DATE`          | `false`    | If `true`, adds a `Date` header to the ICAP response.                                                                                                        |
| `HTTP_HEADER_ORIGIN_FORM`           | `false`    | If `true`, forces the modified HTTP request line to use Origin Form (relative path), e.g., `POST /v1/chat` instead of `POST https://api.openai.com/v1/chat`. |
| `ICAP_CONNECTION_KEEP_ALIVE`        | `true`     | If `true`, sends `Connection: keep-alive` in ICAP responses, maintaining persistent connections with the client (Proxy).                                     |
| {% endstep %}                       |            |                                                                                                                                                              |

{% step %}

### Docker Compose Deployment

Create a `docker-compose.yml` file with the following service definition:

{% code title="docker-compose.yml" %}

```yaml
services:
  llm_icap_shield:
    image: public.ecr.aws/n5w6j7z8/aiceberg/aiceberg_llm_shield:latest
    container_name: llm_icap_shield
    restart: always
    ports:
      - "${LLM_SHIELD_ICAP_PORT:-1344}:1344"
    environment:
      - AICEBERG_PROFILE_ID=${AICEBERG_PROFILE_ID:?AICEBERG_PROFILE_ID must be set in .env}
      - AICEBERG_API_KEY=${AICEBERG_API_KEY:?AICEBERG_API_KEY must be set in .env}
      - AICEBERG_ENVIRONMENT=prod
      # Ports (optional overrides)
      # - LLM_SHIELD_ICAP_PORT=1344
      - AICEBERG_LLM_SHIELD_LOG_LEVEL=INFO
      - HTTP_BODY_READ_ONLY_FOR_TARGET=true
      # Optional tuning
      - ICAP_HTTP_TRANSFER_ENCODING=chunked
      - ICAP_ENCAPSULATED_MODE=identity
      - ICAP_CONNECTION_KEEP_ALIVE=true
```

{% endcode %}

#### Setup Credentials

Copy the example environment file and fill in your credentials:

{% code title="Shell" %}

```bash
cp .env.example .env

# Edit .env and set AICEBERG_PROFILE_ID and AICEBERG_API_KEY
```

{% endcode %}

Start the service:

{% code title="Start service" %}

```bash
docker compose up -d
```

{% endcode %}
{% endstep %}

{% step %}

### Configuring Your Proxy (Squid Example)

Configure your ICAP client (e.g., Squid Proxy) to route traffic to the shield.

Key Settings:

* Service URL: `icap://<host-ip>:1344/reqmod` (for Request Modification)
* Methods: `REQMOD`

#### Example `squid.conf` Snippet

{% code title="squid.conf" %}

```squid
icap_enable on
icap_service_failure_limit -1
icap_preview_enable off
icap_persistent_connections on

# Define the service
icap_service llm_req reqmod_precache icap://llm_icap_shield:1344/reqmod bypass=0 version=1.0

# Define Access Control (send only LLM traffic)
acl llm_domains dstdomain chatgpt.com
adaption_access llm_req allow llm_domains
adaption_access llm_req deny all
```

{% endcode %}
{% endstep %}

{% step %}

### Troubleshooting

If you encounter `ERR_ICAP_FAILURE` or blank pages, check the logs:

{% code title="View container logs" %}

```bash
docker logs llm_icap_shield
```

{% endcode %}

<details>

<summary>Parsing Errors (500)</summary>

Try switching `ICAP_ENCAPSULATED_MODE` to `chunked` or toggling `HTTP_HEADER_ORIGIN_FORM` depending on your proxy version.

</details>

<details>

<summary>Connection Resets</summary>

Ensure `icap_persistent_connections` matches between Squid and the Shield (default behavior handles both).

</details>
{% endstep %}
{% endstepper %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aiceberg.ai/developers/guardian-via-icap/getting-started/quickstart-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
