From b1429ffa68ea9efb16c366db5c8a37655538241e Mon Sep 17 00:00:00 2001 From: Will Jones Date: Fri, 9 Oct 2026 19:36:49 -0700 Subject: [PATCH] fix: use aws-lc-rs instead of ring for remote HTTP and gRPC TLS (#4504) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary LanceDB's remote HTTP client (reqwest) and gRPC client (tonic) used rustls with the `ring` crypto provider, while the AWS SDK and object_store use aws-lc-rs. This moves both clients to aws-lc-rs: - `tonic`: `tls-ring` → `tls-aws-lc`. - `reqwest`: 0.12 → 0.13. reqwest 0.12 has no aws-lc-rs feature; 0.13's `rustls` feature uses it. 0.13 was already in the lockfile through object_store. No code changes were needed. - `macos-system-configuration` is replaced by its 0.13 name, `system-proxy`, which also reads the system proxy on Windows. - `query` is now an opt-in feature in 0.13; it's used for request query parameters. - Certificate verification moves from `rustls-native-certs` to `rustls-platform-verifier`, which uses the OS verifier on macOS and Windows. `ring` is still compiled in, because `lance-namespace-impls` and `lance-namespace-reqwest-client` enable it through reqwest 0.12 (lance-format/lance#9855, lance-format/lance-namespace#369). Both clients here pick aws-lc-rs explicitly, so they don't depend on which providers are compiled in. ## Evidence A temporary example that connects the remote client to real HTTPS hosts: ``` https://example.com: Http error: ... 404 Not Found: ... # TLS handshake OK https://expired.badssl.com: Hit retry limit ... connect_failures=3/3 # bad cert rejected ``` ## Merge Risk **Door:** two-way; dependency feature changes only. **Blast Radius:** `remote` TLS and certificate verification (Python, Node, and Rust LanceDB Cloud clients). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 --- Cargo.lock | 5 ++++- Cargo.toml | 2 +- rust/lancedb/Cargo.toml | 8 +++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3180e6ad7..b0860f72f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5833,7 +5833,7 @@ dependencies = [ "rand 0.9.5", "random_word", "regex", - "reqwest 0.12.28", + "reqwest 0.13.4", "roaring", "rstest", "semver", @@ -8972,6 +8972,7 @@ checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ "base64 0.22.1", "bytes", + "encoding_rs", "futures-core", "futures-util", "h2 0.4.16", @@ -8983,6 +8984,7 @@ dependencies = [ "hyper-util", "js-sys", "log", + "mime", "percent-encoding", "pin-project-lite", "quinn", @@ -8991,6 +8993,7 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", + "serde_urlencoded", "sync_wrapper", "tokio", "tokio-rustls 0.26.4", diff --git a/Cargo.toml b/Cargo.toml index 6c05f297a..8c9f5a91e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +75,7 @@ serde = "1" serde_json = "1" tempfile = "3.5.0" tokio = { version = "1.23", features = ["rt-multi-thread", "sync"] } -tonic = { version = "0.14", features = ["tls-native-roots", "tls-ring"] } +tonic = { version = "0.14", features = ["tls-native-roots", "tls-aws-lc"] } uuid = { version = "1.7.0", features = ["v4", "v7"] } chrono = { version = "0.4", default-features = false, features = ["clock"] } diff --git a/rust/lancedb/Cargo.toml b/rust/lancedb/Cargo.toml index f42c05bed..d148d19f5 100644 --- a/rust/lancedb/Cargo.toml +++ b/rust/lancedb/Cargo.toml @@ -70,15 +70,17 @@ tempfile = { workspace = true } aws-smithy-types = { workspace = true, optional = true } aws-sdk-bedrockruntime = { version = "1.27.0", optional = true } # For remote feature -reqwest = { version = "0.12.0", default-features = false, features = [ +reqwest = { version = "0.13.0", default-features = false, features = [ "charset", "gzip", "http2", "json", - "macos-system-configuration", + "query", # Avoid linking OpenSSL into Python wheels, which breaks on FIPS hosts. - "rustls-tls-native-roots", + # This uses the aws-lc-rs crypto provider. + "rustls", "stream", + "system-proxy", ], optional = true } tonic = { workspace = true, optional = true } http = { version = "1", optional = true } # Matching what is in reqwest