Skip to main content

Crate rustls_native_roots_cache

Crate rustls_native_roots_cache 

Source
Expand description

Process-wide cache for the system trust store.

rustls_native_certs::load_native_certs reaches into the OS keychain (Security framework on macOS, NSS / OpenSSL stores on Linux). On macOS the underlying Sec* APIs are not concurrency-safe under load — multiple threads calling them in parallel can return errSecIO (-36) on what would otherwise succeed. Production daemons that build many distinct rustls ClientConfigs (one per upstream-TLS fingerprint, e.g.) hit this whenever a reload introduces a handful of new fingerprints concurrently.

The fix is a process-wide cache: read the trust store once per process, share the resulting rustls::RootCertStore behind Arc. The first call’s init barrier serialises the (single) load attempt; every subsequent caller gets a cheap Arc::clone.

In-process the cache is sufficient. Across processes (e.g. a test runner that boots multiple binaries in parallel) each binary still makes its own first call, and those simultaneous calls can lose to keychain contention. The init path therefore retries on transient failure with a small backoff before giving up — errSecIO is documented by Apple as recoverable, and the happy path skips the backoff entirely.

Long-running daemons need to pick up CA-cert updates (an OS security update revoking a root, an operator dropping a corporate CA into the keychain) without restarting. refresh_native_roots re-runs the load and atomically swaps the cached store on success; on failure the previous value is preserved and a warning is logged. The swap is lock-free on the read side so the upstream-TLS hot path is unaffected.

Structs§

NativeRootsError
Shared error type. Carries an operator-readable message; the underlying rustls_native_certs::Error is not Clone, so we stringify at first-failure time and re-yield the same string on subsequent calls.

Functions§

native_roots
Return the cached system trust store, loading it on first call.
refresh_native_roots
Re-read the OS trust store and atomically swap the cached snapshot when the load succeeds.
warm_native_roots
Eagerly trigger the first load. Useful when a daemon’s boot path wants to know the trust-store status before any TLS code runs — idempotent; subsequent calls return the cached result without re-touching the OS keychain.