Air-gapped clusters
This guide walks you through installing a private pool in a Kubernetes cluster that has no general internet access.
You need no inbound rules. The Operator in your cluster connects out to the Cequence control plane, and the control plane never connects in. Besides that one outbound connection, which can go through your HTTP proxy, the cluster pulls every image from your own registry.
A fully disconnected cluster, with no path at all to the Cequence control plane, is not supported.
Before you start
You need:
| What | Details |
|---|---|
| A pool | Created in the portal. See Create a pool. |
| An internal container registry | For example Artifactory, Harbor, Amazon ECR, Azure Container Registry, or Google Artifact Registry, reachable from your cluster's nodes. |
| A workstation | A machine that can reach your cluster's API server, your internal registry, and the internet hosts listed in Step 2. You run every command in this guide from it. |
| Tools on the workstation | The AI Gateway CLI, kubectl, jq, and crane (or skopeo). |
Step 1: Allow outbound access from the cluster
Only the Operator talks to Cequence. Every other component in the pool reaches the control plane through it. Allow outbound HTTPS (TCP 443) from the cluster to one host:
| Host | Used by | Why |
|---|---|---|
api.aigateway.cequence.ai | Operator | Pool configuration, sign-in and token checks, health reporting, and audit logs |
- Allow it by hostname, not IP address. Its addresses can change.
- Enforce the allowlist at your firewall or egress gateway. Kubernetes NetworkPolicies can't filter by hostname.
- Exempt it from TLS inspection, if your firewall inspects TLS. The Operator expects its public certificate.
- Allow Armor to reach your own services. Armor connects to whatever you put behind the gateway — your MCP servers, APIs, and LLM providers.
Your users' browsers need auth.aigateway.cequence.ai, because sign-in redirects there.
If outbound traffic must go through an HTTP proxy
Point the Operator at your proxy with a secret in the pool namespace. Only the Operator's traffic to Cequence goes through it; traffic to your own services is unaffected.
-
Create the secret in the pool namespace, creating the namespace first if it doesn't exist yet:
kubectl create namespace <namespace>
kubectl create secret generic aigw-proxy-config \
--from-literal=proxyUrl=http://proxy.example.com:3128 \
--namespace=<namespace>If your proxy needs credentials, include them in the URL:
http://<user>:<password>@proxy.example.com:3128. To send some hosts directly, add--from-literal=noProxy=<host>,<.domain>. -
Restart the Operator if it's already running. It reads the secret only when it starts:
kubectl rollout restart deployment/aigw-operator -n <namespace>If you create the secret before Step 8, skip this.
-
Check the Operator picked it up:
kubectl logs deployment/aigw-operator -n <namespace> | grep "outbound proxy"The line shows
source=secretand your proxy address, with any password hidden.
Your proxy must allow api.aigateway.cequence.ai, and allow HTTPS through it with CONNECT.
Step 2: Set up a workstation
The workstation needs outbound HTTPS to:
| Host | Why |
|---|---|
api.aigateway.cequence.ai, auth.aigateway.cequence.ai | The CLI fetches the pool's configuration and credentials |
registry.gitlab.com, gitlab.com, cdn.registry.gitlab-static.net | Pulling images from the Cequence registry |
cequence.gitlab.io | Downloading the CLI. Not needed if you copy the CLI binary in. |
If the workstation reaches the internet through a proxy, set HTTPS_PROXY (for example export HTTPS_PROXY=http://proxy.example.com:3128). The CLI and crane both use it.
-
Install the CLI. See Install the CLI. If this machine can't reach
cequence.gitlab.io, download the binary on another machine and copy it over. -
Initialize the CLI for your pool. Open the pool in the portal and copy the
aigateway initcommand from the Pool Configuration Pending banner, then sign in:aigateway init --tenant <tenant-id> --pool-id <pool-id> --namespace <namespace>
aigateway login -
Confirm the CLI can read the pool's configuration:
aigateway api config --json | jq '.data.poolName'This prints your pool's name.
Step 3: Sign in to the Cequence registry
Your pool comes with read-only credentials for the Cequence registry. Use them to sign crane in:
aigateway api config --json | jq -r '.data.regCreds[0].password' | \
crane auth login registry.gitlab.com \
--username "$(aigateway api config --json | jq -r '.data.regCreds[0].username')" \
--password-stdin
The output ends with logged in via ....
Also sign crane in to your internal registry, using your registry's usual credentials:
crane auth login artifactory.example.com --username <user> --password-stdin
Run skopeo login with the same arguments in place of crane auth login. In Step 5, use skopeo copy --all docker://<source> docker://<destination>.
Step 4: Find the versions to mirror
Set two variables that the rest of this guide uses — the Cequence release path, and the path in your registry where the images go:
SRC=registry.gitlab.com/cequence/ai-gateway/releases
DST=artifactory.example.com/aigw
Then find the version of each image:
# Operator: the version your pool is set to use
aigateway api config --json | jq -r '.data.operatorImage.tag'
# Armor, SIEM Manager, DLP engine: the latest release of each
for img in armor siem-manager dlp-engine; do
echo "$img: $(crane ls $SRC/$img | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -1)"
done
Note the versions down. The Operator version ends in -k8s, for example v28.0.5-k8s.
Step 5: Copy the images to your registry
Copy each image your pool uses. Replace the versions with the ones from Step 4.
| Image | Copy it when |
|---|---|
operator | Always |
armor | Always |
redis | The pool's Redis mode is Cequence Deployed |
siem-manager | You export logs to a SIEM |
dlp-engine | You use DLP or Prompt Guard |
crane copy $SRC/operator:v28.0.5-k8s $DST/operator:v28.0.5-k8s
crane copy $SRC/armor:v28.1.3 $DST/armor:v28.1.3
crane copy $SRC/redis:8.4.2-alpine $DST/redis:8.4.2-alpine
crane copy $SRC/siem-manager:v3.3.1 $DST/siem-manager:v3.3.1
crane copy $SRC/dlp-engine:v1.5.1 $DST/dlp-engine:v1.5.1
crane copy copies every CPU architecture of the image, so the copies work on both x86 and Arm nodes.
Check that the copies arrived:
crane ls $DST/armor
For other components, such as behavioral analytics, contact Cequence Support.
Step 6: Create a pull secret in the pool namespace
Create the namespace if you didn't already in Step 1, and a pull secret for your registry. Name the secret regcred:
kubectl create namespace <namespace>
kubectl create secret docker-registry regcred \
--docker-server=artifactory.example.com \
--docker-username=<user> \
--docker-password=<token> \
--namespace=<namespace>
Use credentials that can pull from $DST. You can also create this secret through your usual secrets tooling, such as External Secrets Operator or Vault, as long as it's named regcred and exists in the pool namespace.
Step 7: Point the pool at your registry
Do this before you install, so the Operator never tries to pull from the Cequence registry.
-
In the portal, open the pool and select the Configuration tab.
-
In the Images section, select Edit.
-
In Edit Images, set each image you copied to its path in your registry:
Field Value Operator Image artifactory.example.com/aigw/operator:v28.0.5-k8sArmor Image artifactory.example.com/aigw/armor:v28.1.3SIEM Manager Image artifactory.example.com/aigw/siem-manager:v3.3.1DLP Engine Image artifactory.example.com/aigw/dlp-engine:v1.5.1Registry Credentials Secret regcredLeave the fields empty for images you didn't copy.
-
Select Apply.
-
If the pool's Redis mode is Cequence Deployed, go to the Redis section, select Edit, and set Image to
artifactory.example.com/aigw/redis:8.4.2-alpine. Select Apply.
Step 8: Install the Operator
From the workstation, run:
aigateway deploy install --wait
The output includes this line, which confirms the CLI kept your pull secret instead of replacing it:
ℹ Skipping regcred secret "regcred" — already exists with external labels (customer-managed)
For install options and permissions, see Deploy the Operator and Cluster permissions.
Step 9: Verify the installation
-
Check that every pod pulled from your registry:
kubectl get pods -n <namespace> \
-o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.initContainers[*].image} {.spec.containers[*].image}{"\n"}{end}'Every image starts with
artifactory.example.com/aigw/, and every pod isRunning. -
Check the pool in the portal. The pool shows Active with a recent heartbeat.
-
Check component health:
aigateway status
Upgrading
When a new release is available:
- Repeat Step 3 to Step 5 to copy the new versions into your registry.
- Update the tags in the pool's Images section, as in Step 7.
- The Operator rolls out the new versions within a few minutes.
Troubleshooting
| Symptom | Likely cause and fix |
|---|---|
| The pool stays Pending after install | The Operator can't reach api.aigateway.cequence.ai. Check the allowlist or proxy setup in Step 1, and the Operator's logs: kubectl logs -n <namespace> deploy/aigw-operator. |
The Operator logs invalid outbound proxy URL | proxyUrl in aigw-proxy-config must start with http:// or https:// and include a host. |
A pod is stuck in ImagePullBackOff | Run kubectl describe pod <pod> -n <namespace>. If the image path points at registry.gitlab.com, set that image in Step 7. If it points at your registry, check that you copied that version in Step 5 and that regcred can pull it. |
crane auth login registry.gitlab.com fails | Run aigateway login again, then retry Step 3. |
Cequence AI Gateway