Skip to content

rust: default to rustls TLS backend, add native-tls opt-in#1851

Open
colbylwilliams wants to merge 1 commit into
mainfrom
colby-rust-rustls-tls-backend
Open

rust: default to rustls TLS backend, add native-tls opt-in#1851
colbylwilliams wants to merge 1 commit into
mainfrom
colby-rust-rustls-tls-backend

Conversation

@colbylwilliams

Copy link
Copy Markdown
Member

Summary

Fixes #1805.

The Rust crate hard-coded the OpenSSL-backed native-tls stack for its request-handler HTTP and WebSocket clients, with no way to opt into rustls:

reqwest = { version = "0.12", default-features = false, features = ["stream", "http2", "default-tls"] }
tokio-tungstenite = { version = "0.24", default-features = false, features = ["connect", "native-tls"] }

default-tls (reqwest) and native-tls (tokio-tungstenite) both pull in openssl-sys, which links the system OpenSSL on Linux. This breaks *-unknown-linux-musl / fully-static builds (no OpenSSL sysroot) and adds a dynamic libssl.so.3 runtime dependency on glibc.

Change

This implements both shapes the issue proposed: default to rustls and expose a native-tls cargo feature so consumers keep the choice.

  • rustls-tls (new, default): reqwest rustls-tls-native-roots + tokio-tungstenite rustls-tls-native-roots — rustls with the ring provider and the OS trust store. OpenSSL-free, so musl/static targets cross-compile without a system OpenSSL sysroot.
  • native-tls (new, opt-in): keeps the platform-native stack (OpenSSL on Linux, Secure Transport on macOS, SChannel on Windows) for consumers who want it.
  • Base reqwest/tokio-tungstenite deps drop their hard-coded TLS features; TLS is now selected via the cargo features above.

The transport code (copilot_request_handler.rs) is TLS-backend-agnostic (reqwest::Client::builder() + connect_async), so no source changes were required. For wss://, tokio-tungstenite resolves the rustls crypto provider via Cargo feature unification on the shared rustls crate (reqwest pins ring).

Note: default-features = false now drops the default rustls-tls backend along with bundled-cli; re-add rustls-tls or native-tls. This is documented in the README. Cargo features are additive, so enabling both is unnecessary — when both are present (e.g. under --all-features) the transport prefers native-tls.

Validation

  • cargo check --locked (default) is OpenSSL-free: openssl-sys no longer appears in the normal dependency graph; ring is the sole rustls crypto provider.
  • cargo check --no-default-features --features rustls-tls and --features native-tls both compile.
  • Verified at runtime that the default rustls wss:// path resolves the ring crypto provider (reaches the TLS handshake instead of panicking with "no process-level CryptoProvider available").
  • cargo +nightly fmt --check, cargo clippy --all-features --all-targets -- -D warnings: clean.
  • cargo test --all-features: green (lib + e2e + integration + doctests).
  • Request-handler e2e tests pass under the default rustls-only build.

Supersedes #1806 (which was opened from a fork before I had write access to this repo). This PR is branched directly off main.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Copilot AI 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.

Pull request overview

This PR updates the Rust SDK crate’s TLS feature configuration so it defaults to a rustls-based TLS stack (avoiding OpenSSL) while still offering an opt-in native-tls Cargo feature for consumers who prefer the platform TLS backend. This directly addresses the musl/static build pain described in #1805 without requiring transport-layer source changes.

Changes:

  • Switch default Rust crate TLS backend to rustls-tls (OpenSSL-free by default) and add an opt-in native-tls feature.
  • Remove hard-coded TLS features from the reqwest and tokio-tungstenite dependency declarations and delegate TLS selection to crate features.
  • Document the new TLS feature behavior and the default-features = false implications in the Rust README.
Show a summary per file
File Description
rust/README.md Documents new rustls-tls (default) and native-tls (opt-in) features and updates dependency examples accordingly.
rust/Cargo.toml Introduces rustls-tls/native-tls features, defaults to rustls, and removes dependency-level hard-coded TLS selection.
rust/Cargo.lock Updates the resolved dependency graph to reflect the new rustls-enabled default feature set.

Review details

  • Files reviewed: 2/3 changed files
  • Comments generated: 0
  • Review effort level: Low

The Rust crate hard-coded the OpenSSL-backed native-tls stack for its
request-handler HTTP (reqwest `default-tls`) and WebSocket
(tokio-tungstenite `native-tls`) clients, pulling in `openssl-sys`. That
breaks `*-unknown-linux-musl` / fully-static builds (no OpenSSL sysroot)
and adds a dynamic `libssl` runtime dependency on glibc.

Make TLS feature-gated and default to rustls:

- `rustls-tls` (default): reqwest `rustls-tls-native-roots` +
  tokio-tungstenite `rustls-tls-native-roots`, using rustls with the
  `ring` provider and the OS trust store. OpenSSL-free, so musl/static
  targets cross-compile with no system OpenSSL.
- `native-tls` (opt-in): keeps the platform-native stack for consumers
  who want it.

The transport code is TLS-backend-agnostic (`reqwest::Client::builder()`
+ `connect_async`), so no source changes were needed. For `wss://`,
tokio-tungstenite resolves the rustls crypto provider via Cargo feature
unification on the shared `rustls` crate (reqwest pins `ring`).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@colbylwilliams colbylwilliams force-pushed the colby-rust-rustls-tls-backend branch from 2f683c0 to 92ff3e3 Compare June 30, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rust SDK hard-codes native-tls (OpenSSL); offer a rustls TLS backend so musl/static builds work

2 participants