deps(observability): declare rustls roots stack for a shared TLS module [ skip ci ]
Dependency/policy-only PR: Cargo.toml + Cargo.lock, no source. It declares the crate set a shared native TLS root loader needs in preloop-observability, and merges before the code PR that uses it.
Why preloop-observability at all
The same policy is implemented twice today:
crates/preloop-runner-server/src/shared_http.rs— bundled Mozilla roots (webpki-root-certs), the OS certificate store read on a detached thread with a 5 s deadline, and thePRELOOP_GITHUB_CA_FILE/SSL_CERT_FILEbundles; installed withreqwest'stls_certs_only(engine, CLI, orchestrator, runner-client).crates/preloop-runner/src/client/tls.rs— the same three sources and the same 5 s deadline, re-expressed for the runner's rustls config (use_preconfigured_tls) becausepreloop-runnerdoes not depend onpreloop-runner-server.
A security-relevant root set living in two places is the failure mode: one side adds a source (or changes the deadline) and the other silently keeps verifying against something else. preloop-observability is the only crate both binaries already depend on, so it is where the single loader belongs. It needs rustls and friends declared first — hence this PR, and hence a code PR that touches no manifest.
The declared set
| dependency | kind | why |
|---|---|---|
rustls (feature ring) | runtime | RootCertStore filtering of the OS-store entries and the ClientConfig the runner installs with use_preconfigured_tls; ring is the provider both crates already build (preloop-runner, preloop-runner-server declare rustls = { version = "0.23", features = ["ring"] }). |
rustls-native-certs | runtime | Reads the OS store (securityd/trustd on macOS), behind the 5 s deadline. Already a workspace dependency. |
webpki-root-certs | runtime | The bundled Mozilla anchors — already a workspace dependency (1.x, resolved in the lock via rustls-platform-verifier), and declared directly for preloop-runner-server by b39aceb61. |
anyhow | runtime | The client-config helper's error type, which is what both existing call sites (preloop-runner's client::http and main) already return. |
rcgen | dev | So the moved loader tests mint a CA and a localhost leaf in-process instead of shelling out to the openssl CLI. Already a workspace dev-dependency of preloop-runner-server. |
webpki-root-certs, not webpki-roots 0.26
Both are Mozilla's store, but only one can serve both binaries from a single list:
webpki-root-certsexposes DER (CertificateDer<'static>) directly, which is exactly whatreqwest'stls_certs_onlytakes (reqwest::Certificate::from_der), and rustls parses the same DER list withadd_parsable_certificatesfor the preconfigured config. One list, both verifiers, byte-identical anchors.webpki-rootsexposesTrustAnchor, which cannot be fed toreqwest::Certificate::from_der— the engine side would keep a second code path (and a second root snapshot) purely to bridge types.- It is already in the tree for
preloop-runner-server, so this consolidates on the crate that is already shipped rather than keeping two Mozilla snapshots in step.
That leaves preloop-runner's webpki-roots dependency unused once the code PR lands. Removing it is a separate policy PR, as the guard requires: on main today it is still used by the copy being deleted.
Policy files only
supply-chain/guard-policy-files.sh public/main HEAD:
Dependency/policy PR detected: OK
- Cargo.lock
- crates/preloop-observability/Cargo.toml
The rest of the guard's job also passes locally: cargo vet --locked (Succeeded), cargo audit (pre-existing yanked-crate warnings only), cargo deny check all (advisories ok, bans ok, licenses ok, sources ok).
No lockfile versions change — every crate above was already in the graph at the same version, so the Cargo.lock diff is one package's dependency list. cargo check -p preloop-observability --locked passes.
What merges next
The code PR ("refactor(observability): one native TLS root loader for the engine and the runner") is stacked on this branch, contains the new preloop_observability::tls module plus the deletion of both copies, and touches no policy file. Once this PR merges, that PR is rebased on main and the dependency commit cancels out.
Summary by cubic
Declares the rustls roots stack in preloop-observability ahead of a shared native TLS root loader that replaces the duplicate copies in preloop-runner-server and preloop-runner. Dependency/policy-only change: Cargo.toml and Cargo.lock, no source code.
Dependency set
- Adds
rustls(ring),rustls-native-certs,webpki-root-certs, andanyhowas runtime deps, plusrcgenas a dev dep for in-process test certificates. webpki-root-certsis picked overwebpki-rootsbecause it exposes DER directly, which bothreqwest'stls_certs_onlyand rustls'add_parsable_certificatesconsume, keeping a single anchor list for both binaries.- No lockfile versions change; every crate was already in the graph at the same version.
Summary by CodeRabbit
- Chores
- This update does not change any user-visible features or behavior. There are no new controls, workflows, or settings to report. Internal updates are not included in these release notes.