> 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/inference-server/configuration/https.md).

# Serving Inference over HTTPS

Serve a self-hosted Roboflow Inference server over HTTPS with your own TLS certificate, custom cert paths, encrypted keys, and mutual TLS.

The Inference server can serve HTTPS directly when you provide your own TLS certificate and private key. This is useful for self-hosted deployments where you cannot place a TLS-terminating reverse proxy in front of the container.

HTTPS is configured entirely through environment variables.

## Environment variables

<table data-search="false"><thead><tr><th>Variable</th><th>Description</th><th>Default</th></tr></thead><tbody><tr><td>ENABLE_HTTPS</td><td>Master switch. Set to True, 1, or yes to enable HTTPS.</td><td>False</td></tr><tr><td>SSL_CERTFILE</td><td>Path inside the container to the PEM-encoded certificate.</td><td>/etc/inference/certs/server.crt</td></tr><tr><td>SSL_KEYFILE</td><td>Path inside the container to the PEM-encoded private key.</td><td>/etc/inference/certs/server.key</td></tr><tr><td>SSL_KEYFILE_PASSWORD</td><td>Passphrase for an encrypted private key.</td><td>unset</td></tr><tr><td>SSL_CA_CERTS</td><td>CA bundle used to verify client certificates (mTLS).</td><td>unset</td></tr></tbody></table>

The cert and key paths default to `/etc/inference/certs/...`, so the simplest deployment only needs to mount your cert and key at those paths and set `ENABLE_HTTPS=true`.

If `ENABLE_HTTPS` is set but the cert or key is missing, the server refuses to start with an error listing the paths it tried to read.

## Quickstart with self-signed certs

The example below runs the CPU image on `https://localhost:9001` using a self-signed certificate. Replace the cert generation step with your own CA-issued certificate in production.

```bash
# 1. Generate a self-signed cert/key pair valid for localhost
mkdir -p /tmp/inference-certs
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout /tmp/inference-certs/server.key \
  -out /tmp/inference-certs/server.crt \
  -days 365 \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

# 2. Run the inference server with HTTPS enabled
docker run --rm -p 127.0.0.1:9001:9001 \
  -e ENABLE_HTTPS=true \
  -v /tmp/inference-certs:/etc/inference/certs:ro \
  roboflow/roboflow-inference-server-cpu:latest

# 3. Validate from another shell
curl --cacert /tmp/inference-certs/server.crt https://localhost:9001/info
```

`--cacert` trusts the generated certificate for this request while retaining certificate and hostname verification.

## Custom cert paths

If your certs live somewhere other than the defaults, set the paths explicitly:

```bash
docker run --rm -p 127.0.0.1:9001:9001 \
  -e ENABLE_HTTPS=true \
  -e SSL_CERTFILE=/run/secrets/tls/fullchain.pem \
  -e SSL_KEYFILE=/run/secrets/tls/privkey.pem \
  -v /etc/letsencrypt/live/inference.example.com:/run/secrets/tls:ro \
  roboflow/roboflow-inference-server-cpu:latest
```

## Encrypted private keys

For Python and shell Uvicorn launchers, supply the passphrase via `SSL_KEYFILE_PASSWORD` when the private key is encrypted. The parallel Gunicorn launcher does not support that option and the pending runtime-hardening build rejects it at startup; use Uvicorn for encrypted keys. Keep the passphrase in a secret store rather than baking it into an image.

## Mutual TLS

In the pending runtime-hardening build described in [Security Configuration Migration](/deployment/self-hosted/inference-server/configuration/security-migration.md#tls-client-certificates), set `ENABLE_HTTPS=True` and `SSL_CA_CERTS` to a mounted client CA bundle to require client certificates. The Python and shell Uvicorn launchers and the parallel Gunicorn launcher then reject clients without a valid certificate signed by that CA.

Earlier launchers could load the CA bundle without requiring a client certificate. Do not rely on that setting alone for access control on a build without the enforcement fix.

### Connect with a client certificate

Provide both the client's certificate and private key, and verify the server against its CA:

```bash
curl --cacert server-ca.pem \
  --cert client.crt --key client.key \
  https://localhost:9001/healthz
```

Applications, health probes, and metrics scrapers all need client certificates when mTLS is enabled, even for endpoints exempt from API-key authentication. Check that a request without a client certificate fails before relying on this boundary.

HTTPS without `SSL_CA_CERTS` retains server-only TLS. Review [server security](/deployment/self-hosted/inference-server/configuration/security.md) for network access and Workspace authentication.
