feat(0052): port BE's mTLS ClickHouse client#45
Conversation
Port crates/db-clickhouse/src/mtls.rs from soroban-block-explorer into
prices-clickhouse behind an aws-mtls feature: builds a hyper-rustls
connector with a client cert (with_client_auth_cert), root store =
webpki-roots + bundle CA, injected via clickhouse::Client::with_http_client;
fetches the {cert,key,ca} bundle from the AWS Parameters & Secrets Lambda
Extension (MTLS_SECRET_NAME/CH_DOMAIN). Manual Debug redacts all PEM.
Works on our clickhouse 0.13 (with_http_client is connector-generic) so
no version bump. Default build stays plaintext-only; mTLS stack is gated.
Supersedes the closed PR #44 (enabling the clickhouse crate's rustls-tls
features could not present a client cert). aws-lc-rs provider, matching BE.
Verified: default + aws-mtls builds, clippy clean, 7 unit tests pass,
single rustls 0.23.40 in the tree. Live round-trip deferred to 0063/0051.
Close the last in-scope acceptance criterion: the prices-clickhouse README now documents the aws-mtls feature, the MTLS_SECRET_NAME / CH_DOMAIN / AWS_SESSION_TOKEN contract for client_from_lambda_env, the off-Lambda client_with_mtls path, and the build-once-clone-per-invocation pattern that amortises the cross-cloud TLS handshake.
Code review — high effort (recall-biased)Clean, near-verbatim port with strong hygiene (PEM-redacting Findings1. 2. Verified & dismissed (not reported)
Method: 8 finder angles (3 correctness + reuse/simplification/efficiency/altitude/conventions) → dedup → recall-biased verification. CI green (aws-mtls build + clippy + unit tests). |
Two low-severity accuracy fixes from the code review: - Qualify the build-once-reuse amortisation claim (doc comment + README). The ~80-130 ms handshake is only amortised while a pooled socket survives; pool_idle_timeout(8s) closes quiet connections, so invocations spaced past the idle window re-handshake. State the bound instead of implying zero handshakes on sparse traffic. - Make the private-key parse error actionable: rustls_pemfile's None means no recognised key block, so name the supported PKCS#8/PKCS#1/SEC1 formats and point at the bundle's key field.
|
All findings from the review are now addressed in Finding 1 — amortisation overstatement ( Finding 2 — ambiguous key-parse error ( Both were doc/message wording only — no logic change. Verified: |
In-scope work (mTLS port + unit tests + README) merged to develop via PR #45 (d4a9657). The two open acceptance criteria — live mTLS round-trip and >=1 downstream consumer — both need the real cert bundle + reachable Caddy endpoint that 0063 provisions, so 0052 waits on 0063. No code work remains on 0052 itself.
Summary
Port BE's production mTLS ClickHouse client (
soroban-block-explorer/crates/db-clickhouse/src/mtls.rs) intoprices-clickhousebehind anaws-mtlsfeature, so both tenants share one proven transport.src/mtls.rs(ported, credited):client_with_mtls(domain, &bundle, db)—hyper-rustlsconnector withwith_client_auth_cert, root store =webpki-roots+ bundle CA, injected viaclickhouse::Client::with_http_client.fetch_bundle_from_extension—{cert,key,ca}JSON bundle from the AWS Parameters & Secrets Lambda Extension (localhost:2773), warm-cached.client_from_lambda_env(db)— cold-start one-shot (MTLS_SECRET_NAME+CH_DOMAIN).MtlsBundlehas a manualDebugthat redacts all PEM.Cargo.toml—aws-mtlsfeature gating optional deps; default build stays plaintext-only.lib.rs—#[cfg(feature = "aws-mtls")] pub mod mtls;.Why a port (not the closed #44 approach)
Enabling the
clickhousecrate'srustls-tls-*features (PR #44, now closed) makes its default client TLS-capable but can't present a client cert. mTLS needs a custom connector viawith_http_client— which exists in ourclickhouse0.13 and is generic over the connector (impl<C> HttpClient for Client<C, RequestBody>), so BE's pattern compiles with no version bump.Verification
--features aws-mtlsbuilds.clippyclean; 7 unit tests pass (cargo test -p prices-clickhouse --features aws-mtls): PEM-parse shape,MtlsBundleDebug redaction, missing-env.cargo tree→ singlerustls 0.23.40,hyper-rustls 0.27.9,reqwest 0.12,aws-lc-rs.Deferred
Live mTLS round-trip against the Hetzner
pricesDB needs a real cert bundle + endpoint → 0063 (provisioning) / 0051 (live schema-apply, its first consumer).