Skip to content

feat(runtime): add TLS support to TCP request plane - #10921

Merged
athreesh merged 18 commits into
ai-dynamo:mainfrom
walkoss:walid/tcp-tls
Aug 4, 2026
Merged

feat(runtime): add TLS support to TCP request plane#10921
athreesh merged 18 commits into
ai-dynamo:mainfrom
walkoss:walid/tcp-tls

Conversation

@walkoss

@walkoss walkoss commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Overview

Adds opt-in TLS encryption to the TCP request plane (frontend ↔ worker) using rustls with the ring crypto provider. When no TLS env vars are set the transport behaves exactly as before — fully backward compatible.

Details

New shared helper (lib/runtime/src/tls_utils.rs):

  • server_tls_config(cert, key) — builds a rustls::ServerConfig
  • client_tls_config(ca, insecure) — builds a rustls::ClientConfig; emits a prominent warning when insecure=true

TCP server (tcp/server.rs):

  • Reads DYN_TCP_TLS_CERT_PATH + DYN_TCP_TLS_KEY_PATH at startup to optionally build a TlsAcceptor
  • TLS handshake is spawned per-connection (non-blocking accept loop), bounded by a 10s timeout
  • BoxRead/BoxWrite (Box<dyn AsyncRead/AsyncWrite + Unpin + Send>) unify TLS and plaintext streams through all inner functions with no branching after accept
  • CallHomeHandshake read and response-stream prologue read are also bounded by 10s timeouts

TCP client (tcp/client.rs):

  • OnceLock<Option<TlsConnector>> — connector built once from env on first connection, Arc-cloned per connection
  • connect_and_split() upgrades to TLS when configured, with a 10s handshake timeout
  • IPv6-safe SNI parsing with DYN_TCP_TLS_SERVER_NAME override for IP-addressed servers

Environment variables (all optional, plaintext when unset):

Variable Side Purpose
DYN_TCP_TLS_CERT_PATH Server PEM server certificate
DYN_TCP_TLS_KEY_PATH Server PEM server private key
DYN_TCP_TLS_CA_CERT_PATH Client CA cert to verify server
DYN_TCP_TLS_INSECURE Client Skip cert verification (dev only)
DYN_TCP_TLS_SERVER_NAME Client SNI override for IP-addressed servers

Where should the reviewer start?

  1. lib/runtime/src/tls_utils.rs — new file, self-contained rustls helpers
  2. lib/runtime/src/pipeline/network/tcp/server.rsbuild_tls_acceptor() and the accept loop spawn
  3. lib/runtime/src/pipeline/network/tcp/client.rsbuild_tls_connector_from_env() and connect_and_split()
  4. lib/runtime/src/config/environment_names.rs — the 5 new constants under tcp_response_stream::tls

Related Issues

Summary by CodeRabbit

  • New Features
    • Added optional TLS support for runtime TCP connections, including both client and server modes.
    • Added environment-based configuration for certificates, keys, CA roots, insecure verification, and server-name overrides.
    • Improved connection handling so encrypted and unencrypted streams behave consistently.
  • Bug Fixes
    • Added stricter timeouts for connection setup and stream handshakes to avoid indefinite waits.

@walkoss
walkoss requested a review from a team June 24, 2026 11:41
@copy-pr-bot

copy-pr-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@walkoss
walkoss temporarily deployed to external_collaborator June 24, 2026 11:41 — with GitHub Actions Inactive
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot added external-contribution Pull request is from an external contributor feat labels Jun 24, 2026
@datadog-official

datadog-official Bot commented Jun 24, 2026

Copy link
Copy Markdown

Pipelines

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 43.66% (-5.50%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 5277065 | Docs | Datadog PR Page | Give us feedback!

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds optional TLS support to the Dynamo runtime's TCP networking layer. A new tls_utils module provides server_tls_config and client_tls_config builders backed by rustls. Both TcpStreamServer and TcpClient read TLS configuration from environment variables, perform handshakes with 10-second timeouts, and route streams through boxed AsyncRead/AsyncWrite abstractions so the rest of the pipeline handles plaintext and TLS uniformly.

Changes

TCP TLS Support

Layer / File(s) Summary
TLS utility module and dependencies
lib/runtime/Cargo.toml, lib/runtime/src/lib.rs, lib/runtime/src/tls_utils.rs
Adds tokio-rustls, rustls, and rustls-pemfile as dependencies; registers tls_utils as a public module; implements server_tls_config (cert/key PEM loading, ring provider, no client auth) and client_tls_config (optional CA cert, insecure mode via NoVerifier), plus the private NoVerifier ServerCertVerifier.
TLS environment variable constants
lib/runtime/src/config/environment_names.rs
Adds the tcp_response_stream::tls submodule with five public env var constants (DYN_TCP_TLS_CERT_PATH, DYN_TCP_TLS_KEY_PATH, DYN_TCP_TLS_CA_CERT_PATH, DYN_TCP_TLS_INSECURE, DYN_TCP_TLS_SERVER_NAME) and extends the duplicate-name unit test to cover them.
TCP server TLS acceptor and boxed I/O
lib/runtime/src/pipeline/network/tcp/server.rs
Introduces BoxRead/BoxWrite type aliases; adds build_tls_acceptor driven by env vars; extends start and tcp_listener to accept an optional Arc<TlsAcceptor>; per-connection handling spawns a task with a 10s TLS handshake timeout before boxing stream halves; all internal stream handlers (process_stream, process_request_stream, process_response_stream, request_stream_send_handler, network_receive_handler, network_send_handler) updated to use boxed framed I/O; CallHomeHandshake and response prologue reads bounded by 10s timeouts.
TCP client TLS connector and connect_and_split
lib/runtime/src/pipeline/network/tcp/client.rs
Adds BoxRead/BoxWrite type aliases; introduces static TCP_TLS_CONNECTOR OnceCell with env-var-driven builder and tls_server_name helper; adds connect_and_split that retries TCP connect, optionally performs a 10s-timeout TLS handshake, and returns boxed halves; create_response_stream and create_request_stream switch to connect_and_split; wait_for_connection_tasks, wait_for_server_shutdown, handle_reader, and handle_writer all updated to use boxed framed I/O.
Client test harness boxing updates
lib/runtime/src/pipeline/network/tcp/client.rs
Updates all test harnesses (WriterHarness, ReaderHarness, RequestReaderHarness) and their corresponding builder functions to box split TCP halves into FramedRead<BoxRead, ...> / FramedWrite<BoxWrite, ...>, aligning tests with the new boxed I/O abstraction.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding TLS support to the TCP request plane.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description covers overview, details, reviewer start points, and a related issue, matching the template closely enough.

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]

This comment was marked as resolved.

@walkoss
walkoss temporarily deployed to external_collaborator June 24, 2026 11:53 — with GitHub Actions Inactive
@walkoss
walkoss temporarily deployed to external_collaborator June 24, 2026 12:00 — with GitHub Actions Inactive
@walkoss
walkoss temporarily deployed to external_collaborator June 24, 2026 12:03 — with GitHub Actions Inactive
@walkoss

walkoss commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

@grahamking — this is PR 1 from the TLS contribution request (#10809) you approved. Scope is TCP request-plane TLS only (no mTLS, no NATS). Happy to address any feedback!

@grahamking

Copy link
Copy Markdown
Contributor

@walkoss Great! Can you start with the red tests. Look like clippy, maybe some others. Then I'll trigger the bigger unit tests, and schedule a review.

Have you done a second round of agent work, where you ask it to simplify and remove unnecessary tests? Can usually slim down an agentic PR a fair bit like that.

@walkoss
walkoss temporarily deployed to external_collaborator June 25, 2026 08:05 — with GitHub Actions Inactive
@walkoss
walkoss temporarily deployed to external_collaborator June 25, 2026 08:12 — with GitHub Actions Inactive
@walkoss
walkoss temporarily deployed to external_collaborator June 25, 2026 08:19 — with GitHub Actions Inactive
@walkoss
walkoss temporarily deployed to external_collaborator June 25, 2026 08:30 — with GitHub Actions Inactive
@walkoss

walkoss commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

@grahamking thank you, all checks are green now.
I rebased onto the latest main which surfaced some Cargo.lock drift in the sub-workspaces (lib/bindings/python, lib/runtime/examples, lib/bindings/kvbm) - these needed syncing independently of our changes.
I also simplified the tests as you suggested, removing redundant cases and merging related assertions. Does the test coverage look good to you?

@grahamking

Copy link
Copy Markdown
Contributor

/ok to test 69d75de

Encrypt frontend ↔ worker TCP connections using rustls (ring provider).
TLS is opt-in via environment variables; existing deployments require no
changes.

New env vars (all optional):
- DYN_TCP_TLS_CERT_PATH / DYN_TCP_TLS_KEY_PATH  — server-side TLS
- DYN_TCP_TLS_CA_CERT_PATH                       — client CA verification
- DYN_TCP_TLS_INSECURE                           — skip cert verify (dev only)
- DYN_TCP_TLS_SERVER_NAME                        — SNI override for IP addresses

Key design decisions:
- BoxRead/BoxWrite unify TLS and plaintext streams through all inner
  functions with zero branching after accept/connect
- TLS acceptor spawned per-connection so the accept loop is never blocked;
  handshake timeout is 10s on both server and client
- ClientConfig cached via OnceLock — built once, Arc-cloned per connection
- Warn at startup when server/client TLS env vars are mismatched
- Empty CA PEM detected at build time rather than failing at handshake

Signed-off-by: Walid El Bouchikhi <walid.elbouchikhi@datadoghq.com>
@walkoss
walkoss temporarily deployed to external_collaborator June 25, 2026 16:48 — with GitHub Actions Inactive
@walkoss
walkoss temporarily deployed to external_collaborator August 1, 2026 11:15 — with GitHub Actions Inactive
@walkoss
walkoss temporarily deployed to external_collaborator August 1, 2026 11:21 — with GitHub Actions Inactive
Signed-off-by: Walid <walid.elbouchikhi@datadoghq.com>

@ziqifan617 ziqifan617 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only sign off for dynamo-kv-memory-codeowners, since the related part is kvbm cargo.lock

Comment thread docs/fern/index.yml Outdated

@nv-anants nv-anants left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toml changes look good

Per review feedback from nealvaidya: TLS configuration is not tied to
Kubernetes or the operator, so it belongs alongside the other runtime
reference docs instead of under the Kubernetes Operator section.

Signed-off-by: Walid <walid.elbouchikhi@datadoghq.com>
@walkoss
walkoss temporarily deployed to external_collaborator August 3, 2026 20:16 — with GitHub Actions Inactive
@walkoss
walkoss requested a review from nealvaidya August 3, 2026 20:34
The request-plane page documents all other DYN_TCP_* environment
variables, so add a pointer to the TLS reference for the encryption
options as well (per review feedback).

Signed-off-by: Walid <walid.elbouchikhi@datadoghq.com>
@walkoss
walkoss temporarily deployed to external_collaborator August 3, 2026 21:18 — with GitHub Actions Inactive
@nv-tusharma

Copy link
Copy Markdown
Collaborator

/ok to test 78ba919

@GuanLuo
GuanLuo temporarily deployed to external_collaborator August 4, 2026 01:38 — with GitHub Actions Inactive
@dynamo-ops

Copy link
Copy Markdown
Contributor

/ok to test 5277065

@athreesh
athreesh merged commit c3f0f71 into ai-dynamo:main Aug 4, 2026
119 of 121 checks passed
hhzhang16 added a commit that referenced this pull request Aug 4, 2026
dyn-3691-extract-shared-target-pid-cuda-customstorage-operation-layer

* 'main' of https://github.com/ai-dynamo/dynamo: (50 commits)
  docs(cli): correct removed vLLM prefill-worker flag reference (#12581)
  docs(operator): reserve webhook Ignore for emergencies (#12563)
  ci(docs): make previews and checks match what actually publishes (#12339)
  refactor(vllm): organize custom encoder modules (#12416)
  feat(llm): Select reasoning output field via env var (#11464)
  feat(runtime): add TLS support to TCP request plane (#10921)
  fix: convert conditional disagg sglang warning to httperror 400 (#12578)
  feat(operator): add runtime feature gates (#12421)
  refactor(runtime): extract PushRouter transport seam behind StreamingDispatch trait (#12447)
  feat(replay): add deterministic canonical offline reports (#12363)
  build: bump ModelExpress to 0.5.0(OPS-7978) (#12455)
  fix(mocker): use logical KV tokens for decode timing (#12583)
  fix(examples): update Triton example for CUDA 13 + fix libdcgm copy (DYN-3697) (#12577)
  refactor(operator): implement composition-first DGD reconciliation (#12283)
  feat(frontend): add basetenkenizer backend (#12376)
  fix(profiler): configure rapid mocker without planner (#12573)
  docs(vllm): correct worker-role flags and document --kv-transfer-config (#12568)
  ci: add Kubernetes deploy test to nightly (#12090)
  fix(container): reuse pinned protoc in runtime image (#12535)
  feat(self-host): flip DYN_SELF_HOST_METADATA default to ON (gh-8749) (#11417)
  ...

Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation external-contribution Pull request is from an external contributor feat frontend `python -m dynamo.frontend` and `dynamo-run in=http|text|grpc` size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants