Skip to content

Commit 2bea5ba

Browse files
authored
perf(deps): drop aws-lc-rs from non-FIPS builds, use ring backend (#1219)
## Summary Stacks on top of #1218. Drops the duplicate `aws-lc-rs` crypto provider from non-FIPS builds, leaving a single backend per mode. Cuts ~15% off the deployed layer zip on its own. | | before | after | Δ | |---|---:|---:|---:| | `bottlecap` stripped (arm64) | 11,709,896 B | **10,137,032 B** | **−1,572,864 B (−13.4%)** | | `datadog_extension.zip` (arm64) | 5,324,844 B | **4,528,013 B** | **−796,831 B (−15.0%)** | ## Why this exists Until #1218 landed the libdatadog gating fixes, bottlecap was pulling **both** `ring` and `aws-lc-rs` into every build: - `ring` came in transitively via `libdd-common/https → rustls/ring + hyper-rustls/ring` - `aws-lc-rs` was hardcoded directly via `rustls = { features = ["aws-lc-rs"] }` in `bottlecap/Cargo.toml`, plus explicit `rustls::crypto::aws_lc_rs::default_provider().install_default()` calls in `http_client.rs` and `trace_processor.rs` The libdatadog gating from DataDog/libdatadog#1943 fixed the *transitive* path, but bottlecap's *direct* `aws-lc-rs` usage remained. Result: the `db05e1f` bump in #1218 keeps both providers linked into the binary and ships ~1.5 MiB of unused machine code (`aws-lc-sys` alone is ~543 KiB stripped per `cargo bloat`, and the surrounding rustls / hyper-rustls / boringssl glue makes up the rest). ## Change 1. **`bottlecap/Cargo.toml`** — drop the `aws-lc-rs` feature from the rustls direct dep: ```diff -rustls = { version = "0.23.18", default-features = false, features = ["aws-lc-rs"] } +rustls = { version = "0.23.18", default-features = false } ``` The provider now flows in transitively per mode: - `default`: `libdd-common/https` → `rustls/ring` - `fips`: `bottlecap/fips` → `rustls/fips` (FIPS-validated aws-lc-rs) 2. **`bottlecap/src/traces/http_client.rs`** — make `ensure_crypto_provider_initialized` cfg-conditional on the bottlecap `fips` feature so `rustls::crypto::ring::default_provider` is used in non-FIPS and `rustls::crypto::aws_lc_rs::default_provider` only in FIPS. 3. **`bottlecap/src/traces/trace_processor.rs`** — same cfg split for the test-helper `default_provider().install_default()` call. ## Verification `cargo tree`: ``` $ cargo tree -i ring --no-default-features --features default ring v0.17.14 └── ... (via libdd-common/https path) ✓ pulled $ cargo tree -i aws-lc-rs --no-default-features --features default warning: nothing to print. ✓ absent $ cargo tree -i ring --no-default-features --features fips warning: nothing to print. ✓ absent $ cargo tree -i aws-lc-rs --no-default-features --features fips aws-lc-rs v1.16.2 └── ... ✓ pulled ``` Build script's FIPS dep check still passes: ``` $ cargo clippy --workspace --all-targets --no-default-features --features fips warning: bottlecap@0.1.0: No ring dependency found. FIPS compliance check passed warning: bottlecap@0.1.0: No openssl dependency found. FIPS compliance check passed warning: bottlecap@0.1.0: No boringssl dependency found. FIPS compliance check passed warning: bottlecap@0.1.0: All dependency checks passed. ``` ## Risk This is a real behavior change for non-FIPS deployments — TLS goes from `aws-lc-rs` to `ring` as the default provider. Both are FIPS-incapable in non-FIPS builds anyway (the FIPS variant lives behind `rustls/fips`), so the user-visible difference is limited to TLS internals (cipher suite priority list, perf characteristics, supported algorithms). `ring` is the libdatadog-wide default and is what every other libdd-* consumer in the workspace ends up on after #1943, so this aligns bottlecap with the rest of the ecosystem. Should be smoke-tested in a real Lambda environment before merging — the dev-server path and a representative trace/metric flush should both work end-to-end. ## Test plan - [x] `cargo check --all-targets` (default features) - [x] `cargo clippy --workspace --all-targets --features default` - [x] `cargo clippy --workspace --all-targets --no-default-features --features fips` — FIPS dep check still passes - [x] `cargo tree` — verified single provider per mode - [x] Production layer build via `ARCHITECTURE=arm64 FIPS=false ./scripts/build_bottlecap_layer.sh` — built successfully, sizes above - [ ] End-to-end smoke test in a real Lambda environment (TLS handshake, trace/metric/log flushes) - [ ] FIPS production build smoke test ## Base Stacked on #1218 (libdatadog `db05e1f` bump + HttpClientTrait adoption). Will rebase to `main` once that lands.
1 parent 3d4c862 commit 2bea5ba

3 files changed

Lines changed: 13 additions & 4 deletions

File tree

bottlecap/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ hmac = { version = "0.12", default-features = false }
4040
sha2 = { version = "0.10", default-features = false }
4141
hex = { version = "0.4", default-features = false, features = ["std"] }
4242
base64 = { version = "0.22", default-features = false }
43-
rustls = { version = "0.23.18", default-features = false, features = ["aws-lc-rs"] }
43+
rustls = { version = "0.23.18", default-features = false }
4444
# Transitive via rustls. Pinned to >=0.103.13 so cargo audit passes (RUSTSEC-2026-0098, RUSTSEC-2026-0099, RUSTSEC-2026-0104).
4545
rustls-webpki = { version = "0.103.13", default-features = false }
4646
rustls-pemfile = { version = "2.0", default-features = false, features = ["std"] }

bottlecap/src/traces/http_client.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,16 @@ impl HttpClientTrait for HttpClient {
7979
/// Initialize the crypto provider needed for setting custom root certificates.
8080
fn ensure_crypto_provider_initialized() {
8181
static INIT_CRYPTO_PROVIDER: LazyLock<()> = LazyLock::new(|| {
82+
// FIPS builds use the FIPS-validated aws-lc-rs provider, non-FIPS
83+
// builds use ring (the libdatadog default). Pick based on the bottlecap
84+
// `fips` feature so we never pull both crypto backends into the binary.
85+
#[cfg(all(unix, feature = "fips"))]
86+
let provider = rustls::crypto::aws_lc_rs::default_provider();
87+
#[cfg(all(unix, not(feature = "fips")))]
88+
let provider = rustls::crypto::ring::default_provider();
89+
8290
#[cfg(unix)]
83-
if let Err(_already_installed) =
84-
rustls::crypto::aws_lc_rs::default_provider().install_default()
85-
{
91+
if let Err(_already_installed) = provider.install_default() {
8692
debug!(
8793
"HTTP_CLIENT | Default CryptoProvider already installed, using existing provider"
8894
);

bottlecap/src/traces/trace_processor.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,10 @@ mod tests {
637637
#[allow(clippy::unwrap_used)]
638638
#[cfg_attr(miri, ignore)]
639639
async fn test_process_trace() {
640+
#[cfg(feature = "fips")]
640641
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
642+
#[cfg(not(feature = "fips"))]
643+
let _ = rustls::crypto::ring::default_provider().install_default();
641644
let start = get_current_timestamp_nanos();
642645

643646
let tags_provider = create_tags_provider(create_test_config());

0 commit comments

Comments
 (0)