Skip to content

fix(deps)!: link the TLS provider only with a crypto backend - #114

Merged
polaz merged 3 commits into
mainfrom
fix/#106-tls-provider-features
Sep 27, 2026
Merged

polaz merged 3 commits into
mainfrom
fix/#106-tls-provider-features

Conversation

@polaz

@polaz polaz commented Sep 27, 2026

Copy link
Copy Markdown
Member

Summary

A default-features = false build no longer links a TLS crypto provider, so a crate that only transcodes (or injects its own verifier) pulls in none of rustls-rustcrypto, rsa, paste or rustls-webpki 0.102, and its advisory scan passes without ignores.

The outbound rustls provider (JWKS fetches, the rate-limit service) now follows the crypto backend features, in this order:

  1. the provider the process installed with rustls::crypto::CryptoProvider::install_default: an explicit choice wins, as in rustls itself;
  2. aws-lc with aws_lc_rs (it also wins the tie with rust_crypto, as for JWTs);
  3. RustCrypto with rust_crypto (default).

With neither feature and no installed provider, building a JWKS or rate-limit client fails at startup with an error naming both remedies. It applies to http:// endpoints too: reqwest builds its TLS connector with every client.

The issue's other suggestion, making ring or aws-lc the provider, is not taken: the default build stays free of C crypto, which CI checks. The default build keeps rsa through the rust_crypto JWT backend, as it did before 4.3.0; that is covered by the existing deny.toml entry.

Changes

  • Cargo.toml: rustls-rustcrypto is optional, enabled by rust_crypto; aws_lc_rs enables rustls' aws-lc provider.
  • src/tls.rs: provider selection (select_provider, pure, so its error path is tested without process state); client_config returns a Result, including for an installed provider that cannot negotiate TLS 1.2 or 1.3.
  • JwksCache::new returns a Result instead of falling back to a default reqwest client, which panics without a provider.
  • CI: the injected-verifier leg checks that the build links none of the crates whose advisories deny.toml ignores.
  • src/shield/resolve.rs: its tests move to resolve/tests.rs; in a build without a backend they install the RustCrypto provider, as an embedder of such a build would.
  • README (Outbound TLS), crate docs and deny.toml describe the provider order.

Testing

fmt, clippy with -D warnings and the test suite on all four backend legs (518 / 518 / 519, and 465 without a backend), doc tests with and without a backend, rustdoc with -D warnings, cargo deny check advisories. A cargo deny run with no ignores and dev dependencies excluded passes on the build without a backend and fails on the default one.

Closes #106

BREAKING CHANGE: a default-features = false build links no rustls crypto provider; install one before configuring a JWKS endpoint or the rate-limit service. JwksCache::new returns Result<JwksCache, String>.

rustls-rustcrypto was an unconditional dependency, so a
`default-features = false` build (transcoding only, or an injected
verifier) still linked it, and with it `rsa`, `paste` and
`rustls-webpki` 0.102: a consumer's advisory scan failed on crates the
build never needed.

- The outbound rustls provider follows the crypto backend features: a
  provider the process installed wins, else aws-lc with `aws_lc_rs`,
  else RustCrypto with `rust_crypto`. With neither feature no provider
  is linked, and building a JWKS or rate-limit client without an
  installed one fails with an error naming both remedies (reqwest needs
  a provider even for http:// endpoints).
- `JwksCache::new` returns a `Result` instead of falling back to a
  default client, which panics when no provider exists.
- CI checks that the build without a crypto backend links none of the
  crates whose advisories deny.toml ignores.
- The limit-service tests move out of resolve.rs into resolve/tests.rs.

Tests cover the provider order, the error without one, a provider that
cannot negotiate TLS 1.2 or 1.3, and which provider each backend brings.

BREAKING CHANGE: a `default-features = false` build links no rustls crypto provider; install one before configuring a JWKS endpoint or the rate-limit service. `JwksCache::new` returns `Result<JwksCache, String>`.

Closes #106
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-27T17:37:40.675576Z 4814406 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Warning

Review limit reached

Next included review available in 38 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: f531f9b9-1b28-4a98-94d9-44f1e500196f

📥 Commits

Reviewing files that changed from the base of the PR and between 5d72f4f and 4814406.

📒 Files selected for processing (12)
  • .github/workflows/ci.yml
  • Cargo.toml
  • README.md
  • deny.toml
  • src/auth/jwks.rs
  • src/auth/jwks/tests.rs
  • src/auth/verifier.rs
  • src/lib.rs
  • src/shield/resolve.rs
  • src/shield/resolve/tests.rs
  • src/tls.rs
  • src/tls/tests.rs

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: ca9af0ac-b856-434d-9681-73e24a527b62

📥 Commits

Reviewing files that changed from the base of the PR and between 1e34884 and 5d72f4f.

📒 Files selected for processing (12)
  • .github/workflows/ci.yml
  • Cargo.toml
  • README.md
  • deny.toml
  • src/auth/jwks.rs
  • src/auth/jwks/tests.rs
  • src/auth/verifier.rs
  • src/lib.rs
  • src/shield/resolve.rs
  • src/shield/resolve/tests.rs
  • src/tls.rs
  • src/tls/tests.rs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Summary

Summary by CodeRabbit

  • New Features
    • Outbound TLS can use an already-installed provider or one enabled at build time. Builds without a provider can run without linking a TLS crypto backend.
  • Bug Fixes
    • Startup now reports errors when required outbound TLS clients cannot be configured, including for JWKS and rate-limit service connections.
  • Documentation
    • Clarified TLS provider selection and when a provider is required for startup.
  • Tests
    • Expanded coverage for TLS provider selection, rate-limit resolution, and cache behavior.

Walkthrough

Outbound TLS now selects a process-installed or feature-provided rustls crypto provider. JWKS and rate-limit client construction returns provider errors instead of falling back to a default client. CI checks the injected-verifier dependency tree for specified crates.

Changes

Outbound TLS configuration

Layer / File(s) Summary
Select and configure the TLS provider
Cargo.toml, src/tls.rs, src/tls/tests.rs, README.md, src/lib.rs
The rust_crypto and aws_lc_rs features control built-in providers. TLS configuration prefers an installed provider, then selects a compiled-in provider. It returns errors when no provider is available or the provider lacks TLS 1.2 or TLS 1.3 support. Tests cover provider selection and configuration errors.
Propagate outbound client initialization errors
src/auth/jwks.rs, src/auth/jwks/tests.rs, src/auth/verifier.rs, src/shield/resolve.rs, src/shield/resolve/tests.rs
JwksCache::new returns a Result, and ConfigVerifier::build propagates construction errors. LimitService::build also propagates TLS configuration errors. Tests cover JWKS constructor updates and rate-limit resolution, cache, and endpoint behavior.
Document and check provider dependency boundaries
.github/workflows/ci.yml, deny.toml, README.md
The injected-verifier CI leg checks the dependency tree for rsa, rustls-rustcrypto, paste, and rustls-webpki version 0.102.x. Documentation and the deny comment describe feature-dependent provider and dependency behavior.

Priority: ⬆️ High

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: High

Merge Risk: ⚪ Minimal · up to 5d72f

The provider-free startup requirements and remedies are documented, and the dependency check targets the intended build configuration. No identified issue prevents merging after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 5d72f

Outbound clients now require an available TLS provider and fail during startup if one cannot be used. The examined paths retain certificate verification and do not silently start without configured authentication or rate limiting. Custom provider choices and deployment behavior remain to be validated by adopters.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The provider choice is process-wide when an embedder installs one; its outbound effect reaches configured JWKS retrieval and rate-limit service calls. A missing provider prevents construction of those configured controls rather than activating them without a client.

Trust Boundaries and Controls

  • observed — Provider authority can pass from the crate's feature-selected backend to an explicitly installed process provider. The examined client configuration retains certificate roots and protocol checks; it does not independently establish the algorithm policy of an arbitrary installed provider.

Resilience and Maintainability Implications

  • observed — Startup errors propagate through the configured security-control builders. Once running, an uncached rate-limit lookup may still fall through to a static or default profile, or to no profile if neither exists; the reviewed TLS change does not modify that runtime fallback.

Hardening Proposals

  • proposed — For deployments that install their own provider, document and validate the intended cipher and algorithm policy as well as successful construction of configured JWKS and rate-limit clients before rollout.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR makes the TLS provider optional and disables it for default-features = false. It adds provider-selection tests and keeps the #104 header-forwarding code unchanged. However, Cargo.toml still… Use a TLS provider with a clean advisory dependency tree, or patch rustls-rustcrypto to a fixed rustls-webpki. Add cargo audit or cargo deny check advisories coverage for both the default and --no-default-features builds. Keep the…
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: linking the TLS provider only when a crypto backend is enabled.
Description check ✅ Passed The description directly explains the dependency, provider-selection, API, CI, documentation, and breaking-change updates.
Out of Scope Changes check ✅ Passed The changes stay connected to [#106]. They alter TLS feature wiring and provider selection, propagate provider configuration errors to JWKS and rate-limit clients, update related tests and documentati…
Docstring Coverage ✅ Passed Docstring coverage is 92.86% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 42 functions across 8 files. (4 skipped: 4 …
Full details: Linked Issues check

Explanation

The PR makes the TLS provider optional and disables it for default-features = false. It adds provider-selection tests and keeps the #104 header-forwarding code unchanged. However, Cargo.toml still uses rustls-rustcrypto 0.0.2-alpha, which depends on rustls-webpki 0.102.x; the PR does not patch that dependency to a fixed release. The security job runs cargo-deny only for the default lockfile. The no-backend matrix leg uses a grep for selected advisory crates, not cargo audit or cargo deny check advisories for that build. These facts do not meet the advisory requirements in [#106]. The requested 4.3.1 release is non-coding work and is not assessed.

Resolution

Use a TLS provider with a clean advisory dependency tree, or patch rustls-rustcrypto to a fixed rustls-webpki. Add cargo audit or cargo deny check advisories coverage for both the default and --no-default-features builds. Keep the existing header-forwarding behavior.

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@greptile-apps

greptile-apps Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[High risk] Refactors TLS provider selection to require explicit configuration.

No outstanding findings block merging.

Summary

Outbound TLS selects the enabled crypto backend or an explicitly installed rustls provider and propagates client-construction errors. The CLI is now gated by a feature, with CI and release commands updated for that package layout.

Reviews (3) · Last reviewed commit: "Merge branch 'main' into fix/#106-tls-pr..."

Comment thread src/tls.rs Outdated
Comment thread src/tls/tests.rs Outdated
@greptile-apps

This comment has been minimized.

The handshake tests always handed the client the RustCrypto provider, so
with `aws_lc_rs` the aws-lc provider production selects never completed a
handshake in a test. The client now uses the provider the build brings,
and RustCrypto only in a build without a backend.

The `client_config` doc linked a function that no longer exists; it now
links `select_provider`, so a private-item rustdoc build with warnings
denied passes.
main moved the binary into this package behind the `cli` feature. The
injected-verifier CI leg now builds with `--no-default-features --features
cli`; the check that it links no crate with an ignored advisory runs on
that build, next to main's check that the default build links no CLI
dependency.
@polaz
polaz merged commit 689ab08 into main Sep 27, 2026
7 checks passed
@sw-release-bot sw-release-bot Bot mentioned this pull request Sep 27, 2026
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.

fix(deps): 4.3.0 pulls a TLS provider with open RUSTSEC advisories even without default features

1 participant