TCP TLS
Dynamo supports opt-in TLS encryption on the TCP request and response streams
between frontends and workers. When enabled, both the request plane
(frontend → worker inference requests) and the response stream (worker →
frontend inference output) are encrypted using
rustls with the ring cryptographic
provider. When no TLS configuration is provided, these streams operate in
plaintext exactly as before.
The same DYN_TCP_TLS_* environment variables apply to both transports — a
single set of certificates encrypts the frontend↔worker TCP request and
response streams. This does not cover the KV event plane, which is carried
over ZMQ or NATS Core depending on setup and is a separate transport; those
paths are not encrypted by this configuration.
Environment variables
All TLS configuration is driven by environment variables. The Rust runtime reads these directly at first connection (lazy initialization).
Both frontends and workers act as TCP server and client depending on the stream direction (response streams: worker dials frontend; request streams: frontend dials worker). All TLS env vars should be set on every pod.
Server role (accepting connections)
Client role (dialing connections)
CLI flags
The same configuration is available via command-line flags on all backends
(vllm, sglang, trtllm, tokenspeed) through DynamoRuntimeArgGroup:
The frontend (dynamo.frontend) also accepts --tcp-tls-cert-path,
--tcp-tls-key-path, and --tcp-tls-ca-cert-path.
Quick start
Generate a self-signed certificate for local testing:
Both frontend and worker need the same flags (both act as server and client):
Kubernetes deployment
In Kubernetes, TLS certificates are typically delivered by a certificate
management system and mounted into pods. Set the
environment variables on each component’s pod template in the
DynamoGraphDeployment spec:
Both components need the same TLS env vars because each acts as both TCP server and client depending on the stream direction.
Note: A future PR (#10809) will add operator-level TLS configuration via
InfrastructureConfiguration, allowing TLS to be configured once at the platform level and auto-injected into all DGD pods without per-component env var setup.
Encrypted paths
When TLS is configured, the following frontend↔worker streams are encrypted:
Design notes
- Server certificates hot-reload: the request-plane and response-stream servers serve their leaf cert/key through a resolver that re-reads the files from disk when their contents change (detected by a content hash, so rotations done by an atomic symlink swap are handled too), so certificate rotation takes effect without a process restart. The check is rate-limited (at most once every 30s, sooner after a failed reload) and never blocks a handshake; a failed reload keeps serving the last valid certificate. Client trust anchors (the CA) are still loaded once, so rotating the CA itself requires a restart.
- Client TLS connectors are built once and cached via
OnceCellon the first outbound connection. - The TLS handshake is spawned per-connection on both the request plane and response stream servers so the accept loop is never blocked.
- Invalid TLS configuration on the request plane (e.g. bad cert path) prevents server startup rather than silently falling back to plaintext.
- When server and client TLS configurations are mismatched (e.g., server has TLS but client does not), a warning is logged at startup.
- An empty CA certificate file is detected at load time and rejected with a clear error message.