Context
Follow-up to #1338 / #1340.
The dynamic cert resolver (#1340) provides the hook for certificate rotation, but users must implement ResolvesClientCert themselves. The most common use case — a sidecar (Vault agent, cert-manager) writes rotated cert/key files to disk — should have a batteries-included implementation.
Proposal
Provide a FileWatchingCertResolver (or ReloadingCertProvider if #1341 adds the SDK-owned trait):
let resolver = FileWatchingCertResolver::new(
"/run/secrets/client.pem",
"/run/secrets/client.key",
)?;
let conn_opts = ConnectionOptions::new(url)
.tls_options(TlsOptions {
client_cert_resolver: Some(Arc::new(resolver)),
..Default::default()
});
Behavior
- Reads cert/key on first call and caches as
Arc<CertifiedKey>
- Checks file mtime on subsequent calls; re-parses only when changed
- Thread-safe via
RwLock
- Logs at
info! when certs are reloaded, warn! on parse errors (falls back to last good cert)
Alternative: poll-based vs. inotify
Start with simple mtime polling (zero extra deps). A notify-based watcher can be added later behind a feature flag.
References
Context
Follow-up to #1338 / #1340.
The dynamic cert resolver (#1340) provides the hook for certificate rotation, but users must implement
ResolvesClientCertthemselves. The most common use case — a sidecar (Vault agent, cert-manager) writes rotated cert/key files to disk — should have a batteries-included implementation.Proposal
Provide a
FileWatchingCertResolver(orReloadingCertProviderif #1341 adds the SDK-owned trait):Behavior
Arc<CertifiedKey>RwLockinfo!when certs are reloaded,warn!on parse errors (falls back to last good cert)Alternative: poll-based vs. inotify
Start with simple mtime polling (zero extra deps). A
notify-based watcher can be added later behind a feature flag.References
GetClientCertificateclosure reading from disk