TLS
Octopus terminates TLS on its listener when gateway.tls is configured. The same listener handles
HTTP/1.1 and HTTP/2 (negotiated via ALPN, advertising h2 and http/1.1). Without gateway.tls,
the listener serves plain HTTP — unless TLS is supplied by the Kubernetes operator (see
Kubernetes-managed TLS).
Configuration01
gateway:
listen: "0.0.0.0:8443"
tls:
cert_file: /etc/octopus/tls/cert.pem
key_file: /etc/octopus/tls/key.pem
min_tls_version: "1.2"
enable_cert_reload: true
reload_interval_secs: 300
# Mutual TLS:
client_ca_file: /etc/octopus/tls/client-ca.pem
require_client_cert: true| Key | Type | Default | Description |
cert_file | string | — | Server certificate file (PEM). Required. |
key_file | string | — | Server private key file (PEM). Required. |
client_ca_file | string | none | CA used to verify client certificates (enables mutual TLS). |
require_client_cert | boolean | false | Require a client certificate during the handshake. |
min_tls_version | string | 1.2 | Minimum TLS version. Must be 1.2 or 1.3 — see the note below. |
enable_cert_reload | boolean | true | Watch the certificate files and reload on change. |
reload_interval_secs | integer (seconds) | 300 | How often the certificate files are checked for changes. |
For the full gateway.tls schema and validation rules, see
TLS configuration.
Minimum TLS version02
min_tls_version is validated at load time (only 1.2 and 1.3 are accepted) and logged when the
acceptor starts.
The file-based TLS acceptor does not currently pin the rustls protocol versions from
min_tls_version — it builds the server config with rustls's defaults (TLS 1.2 and TLS 1.3). So
setting min_tls_version: "1.3" is validated and logged but does not yet disable TLS 1.2 at
the protocol level. Treat this field as advisory for now; do not rely on it to forbid TLS 1.2.
Mutual TLS (client certificates)03
Setting client_ca_file enables client-certificate verification at the TLS handshake. The CA file
is loaded into a root store and a verifier is built:
require_client_cert: true— clients must present a certificate that chains to the configured CA; the handshake fails otherwise.require_client_cert: false— a client certificate is optional; if presented it is verified against the CA, but a client without one still completes the handshake.
After a successful handshake the peer certificate's Common Name (CN) is extracted and made available to the gateway. To turn that verified identity into an authenticated principal with roles, pair this with the mTLS auth provider.
There are two distinct layers: gateway.tls performs the cryptographic verification of the client
certificate, while the mtls auth provider maps the resulting CN to a principal and roles.
Verification happens at the listener — the auth provider does not re-verify the certificate.
Certificate hot reload (file-based)04
When enable_cert_reload is true, a background task checks the certificate file's modification
time every reload_interval_secs and, on change, rebuilds the server config from disk (preserving
mTLS and ALPN) and swaps it into the live acceptor — connections accepted afterward use the new
certificate without a restart. If a rebuild fails (for example, a half-written file), the previous
certificate is kept and the error is logged.
The file-based path and the Kubernetes operator path use the same swappable acceptor
(SwappableTlsAcceptor), so certificate rotation is zero-downtime in both. (min_tls_version
remains advisory regardless of path — see above.)
Kubernetes-managed TLS05
On Kubernetes, certificates can come from Gateway listener Secrets instead of files on disk. The
operator builds a rustls config from the Secret's tls.crt / tls.key and serves it through a
swappable acceptor: when the Secret rotates (for example, a cert-manager renewal), the operator
swaps in the new config so connections accepted afterward use the new certificate — without a
restart. A single listener can serve many hostnames, selecting the certificate by SNI server name
(with exact-host matches preferred over wildcards, and an optional default).
This path is selected when no file-based gateway.tls is configured but operator TLS is available.
See Kubernetes TLS with cert-manager and
Gateway API support.
See also06
mTLS auth provider — authenticate callers by client certificate.