> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/deployment/self-hosted/enterprise/secure-gateway.md).

# Secure Gateway

Secure Gateway proxies the routes Roboflow Deployment servers need into your company's DMZ, and caches model weights and container images locally.

Secure Gateway is a proxy for the Roboflow API and your models' weights, for when you firewall the Roboflow Inference Server from the internet. It is the successor to the [License Server](/deployment/self-hosted/enterprise/license-server.md) and adds local caching of model weights and container images, so a fleet of inference servers shares one controlled point of egress.

{% hint style="info" %}
This page covers the essentials. For the complete configuration and operations reference, see the [Secure Gateway manual](https://secure-gateway.roboflow.com/manual/).
{% endhint %}

## Prerequisites

* Docker Engine 20.10+, or Kubernetes v1.24+
* A host with access to api.roboflow\.com and repo.roboflow\.com
* Port 80 available, with TLS terminated at a load balancer in front of the gateway or inside the container
* 4GB+ memory
* An S3 bucket, or 50GB+ of local disk for the cache

{% hint style="info" %}
Deploying on Red Hat Enterprise Linux? [Secure Gateway on RHEL with Podman](/deployment/self-hosted/enterprise/secure-gateway-podman.md) covers RHEL hosts without Docker or Kubernetes, and [Secure Gateway on MicroShift](/deployment/self-hosted/enterprise/secure-gateway-microshift.md) covers Red Hat Device Edge hosts running MicroShift. Both use dedicated installers with the same air-gapped bundle model.
{% endhint %}

## Using Secure Gateway

On a machine with access to `https://api.roboflow.com` and `https://repo.roboflow.com`, pull the Secure Gateway container:

```
docker pull repo.roboflow.com/roboflow-edge/secure-gateway:latest
```

The `latest` tag tracks the most recent release. For production, and especially for air-gapped deployments, pin a specific version instead so upgrades stay deliberate and reproducible, for example `repo.roboflow.com/roboflow-edge/secure-gateway:0.2.0`.

Run it with a local disk cache and a loopback-only HTTP listener for local testing or a TLS proxy on the same host:

```
docker run -d --name secure-gateway -p 127.0.0.1:80:80 --restart unless-stopped \
    -v gateway-cache:/var/cache/secure-gateway \
    repo.roboflow.com/roboflow-edge/secure-gateway:latest
```

Confirm it is running:

```
curl http://localhost/health
```

To cache on S3 instead of local disk, set the `CACHE_S3_BUCKET` and `CACHE_S3_REGION` environment variables. Leave the credentials unset to use an instance or IAM role.

## TLS certificates

By default the gateway listens on plain HTTP, and you terminate TLS at a load balancer in front of it. To serve HTTPS from the gateway itself, mount your certificate and private key into the container and set both `TLS_CERT_FILE` and `TLS_KEY_FILE`. The gateway then serves HTTPS on its configured port:

```
docker run -d --name secure-gateway -p 443:443 --restart unless-stopped \
    -e PORT=443 \
    -e TLS_CERT_FILE=/etc/ssl/certs/gateway.crt \
    -e TLS_KEY_FILE=/etc/ssl/private/gateway.key \
    -v /path/to/certs:/etc/ssl:ro \
    -v gateway-cache:/var/cache/secure-gateway \
    repo.roboflow.com/roboflow-edge/secure-gateway:latest
```

Both `TLS_CERT_FILE` and `TLS_KEY_FILE` are required to enable inbound HTTPS, and each points to a PEM-encoded file.

When the gateway's outbound traffic passes through a corporate TLS inspection proxy, such as Zscaler, set `TLS_CA_BUNDLE` to that proxy's CA bundle so the gateway trusts its connections to api.roboflow\.com and repo.roboflow\.com:

```
-e TLS_CA_BUNDLE=/etc/ssl/certs/corporate-ca.pem
```

## Connecting Inference Servers

Point each Inference Server at the gateway's HTTPS listener or TLS proxy with an explicit `SECURE_GATEWAY` URL. The server routes its Roboflow API calls and model downloads through that address.

```bash
sudo docker run --rm -p 127.0.0.1:9001:9001 \
    --env SECURE_GATEWAY=https://gateway.example.com \
    roboflow/roboflow-inference-server-cpu:latest
```

Include the port when it differs from 443, such as `https://gateway.example.com:8443`. The certificate must cover the hostname or IP in the URL, and the Inference Server container must trust its issuing CA; configuring the gateway's outbound `TLS_CA_BUNDLE` does not install trust on clients.

Use the [RHEL with Podman](/deployment/self-hosted/enterprise/secure-gateway-podman.md) or [MicroShift](/deployment/self-hosted/enterprise/secure-gateway-microshift.md) client installation instructions when using those deployments.

### Legacy addresses and local tunnels

Use an explicit HTTPS scheme across versions. In the pending runtime-hardening build, bare addresses switch from HTTP to HTTPS, and plaintext remote or LAN gateways are rejected; see [migration scope](/deployment/self-hosted/inference-server/configuration/security-migration.md#gateway-transport).

That build accepts explicit HTTP only for a loopback IP or `localhost`, such as `SECURE_GATEWAY=http://127.0.0.1:8080`. The tunnel must be reachable from the Inference Server's own network namespace; a bridge container's loopback is not its host's loopback.

Only the gateway needs outbound access to api.roboflow\.com and repo.roboflow\.com. After the Inference Server starts, run a model and confirm the requests appear in the gateway's access logs.

The legacy `LICENSE_SERVER` variable is still accepted as an alias for `SECURE_GATEWAY`, with the same transport rules. Prefer `SECURE_GATEWAY` for new configurations.

## Caching

Secure Gateway caches each response on first download, tiered by how often the content changes. Content-addressed container blobs and model weights are held longest, and mutable API responses for a shorter window. Subsequent requests from any Inference Server are served from the cache, which reduces bandwidth use and cold starts across a fleet.
