pub struct CertManager {
pub policy: Policy,
pub issuers: Vec<Arc<dyn CertIssuer>>,
pub certificates: Arc<dyn CertStore>,
pub storage: Arc<dyn Storage>,
pub cache: Arc<CertCache>,
pub on_demand: Option<Arc<OnDemandConfig>>,
pub on_event: Option<Arc<dyn Fn(&str, &Value) -> Result<()> + Send + Sync>>,
pub subject_transformer: Option<Arc<dyn Fn(&str) -> Result<String> + Send + Sync>>,
pub cert_selection: Option<Arc<dyn CertificateSelector>>,
/* private fields */
}Expand description
Central configuration for automatic TLS certificate management.
CertManager coordinates the full certificate lifecycle: obtainment, renewal,
revocation, OCSP stapling, caching, and storage. It holds references to
one or more CertIssuer implementations, a persistent Storage backend,
and a shared in-memory CertCache.
Use CertManager::builder() to construct an instance with sensible defaults.
Fields§
§policy: PolicyWhat should happen. Plain data, so it can be built, cloned, compared and printed on its own.
issuers: Vec<Arc<dyn CertIssuer>>Certificate issuers, tried in order until one succeeds.
Defaults to a single AcmeIssuer
configured for Let’s Encrypt production.
certificates: Arc<dyn CertStore>Where certificates go.
Defaults to a KeyValueCertStore over storage, so a deployment
that has said nothing keeps exactly the layout it already has on disk.
storage: Arc<dyn Storage>Key-value storage for everything that does not go through
CertStore yet: OCSP staples, ACME account data, challenge state,
and cluster locks.
cache: Arc<CertCache>Shared in-memory certificate cache.
on_demand: Option<Arc<OnDemandConfig>>On-demand TLS (optional). When set, certificate operations may be deferred to TLS handshake time for domains that are not yet managed.
on_event: Option<Arc<dyn Fn(&str, &Value) -> Result<()> + Send + Sync>>Optional event callback invoked when notable lifecycle events occur.
The callback receives an event name (one of the EVENT_* constants)
and a JSON value containing event-specific data. Returning an error
from the callback may abort the current operation (for critical
events like EVENT_CERT_OBTAINING). Callbacks should return
quickly as they are invoked synchronously.
subject_transformer: Option<Arc<dyn Fn(&str) -> Result<String> + Send + Sync>>Optional transform applied once per obtain or management operation, before validating, reading storage or taking lifecycle locks. The transformed subject is the managed identifier, normalized to lowercase. A queued job keeps that identity across retries; resubmission resolves it again. Explicit renewal and revocation take managed identifiers directly.
cert_selection: Option<Arc<dyn CertificateSelector>>Optional custom certificate selector for TLS handshakes.
Implementations§
Source§impl CertManager
impl CertManager
Sourcepub fn builder() -> CertManagerBuilder
pub fn builder() -> CertManagerBuilder
Create a new CertManagerBuilder.
Settings start at Policy::default(), which documents what each one
is and why it defaults where it does. Everything else — issuers, cache,
hooks — starts empty, and a Storage must be given.
Source§impl CertManager
impl CertManager
Sourcepub async fn make_certificate_with_ocsp(
&self,
cert_res: &CertificateResource,
) -> Result<Certificate>
pub async fn make_certificate_with_ocsp( &self, cert_res: &CertificateResource, ) -> Result<Certificate>
Parse a CertificateResource into a Certificate, applying OCSP
stapling if enabled.
The certificate PEM is decoded into a chain of DER-encoded certificates, and the private key PEM is decoded into raw key bytes. If OCSP stapling is not disabled, the function fetches and attaches an OCSP response (using the storage cache when possible).
Source§impl CertManager
impl CertManager
Sourcepub async fn manage(&self, domains: &[String]) -> Result<()>
pub async fn manage(&self, domains: &[String]) -> Result<()>
Manage certificates for the given domain names synchronously.
This is the primary entry point for certificate management. For each domain:
- Skip currently usable managed entries.
- Load storage resources and cache only certificates currently valid.
- If not found in storage – obtain a new certificate from the configured issuers.
- If loaded from storage, check if renewal is needed and renew if so.
“Synchronously” means that certificate operations are performed in
the foreground without background retries. Use CertManager::manage_in_background
instead if you want background retry behaviour.
Returns on the first error encountered.
Sourcepub async fn manage_in_background(&self, domains: &[String]) -> Result<()>
pub async fn manage_in_background(&self, domains: &[String]) -> Result<()>
Manage certificates for the given domain names asynchronously.
Same as manage, but ACME operations
(obtain, renew) are submitted as background tasks via the
JobQueue. This method returns as soon as each domain’s
management task has been submitted – certificates may not yet be
ready when this method returns.
At most four jobs execute and 68 are admitted per manager family;
further submissions apply backpressure until capacity is available.
Backoff releases execution. At most 64 jobs retain retry records, leaving
four admission records for new work. When retention is full, a failed job
ends with cert_failed / error_kind = "retry_backlog_full"; it can be
resubmitted later. Success here means submitted, not issued successfully.
Sourcepub async fn cache_certificate(&self, domain: &str) -> Result<Certificate>
pub async fn cache_certificate(&self, domain: &str) -> Result<Certificate>
Load a managed certificate from storage and add it to the in-memory cache. A future or expired certificate returns a validity error without replacing any working certificate already in the cache.
Sourcepub async fn load_certificate(
&self,
domain: &str,
) -> Result<Option<Certificate>>
pub async fn load_certificate( &self, domain: &str, ) -> Result<Option<Certificate>>
Load a certificate from storage for the given domain.
Tries all configured issuers, preferring currently valid certificates.
Returns the best stored resource even if it needs renewal; this method
does not publish it to the serving cache. Returns None when absent.
Source§impl CertManager
impl CertManager
Sourcepub async fn obtain(&self, domain: &str) -> Result<()>
pub async fn obtain(&self, domain: &str) -> Result<()>
Obtain a new certificate synchronously (foreground, no retries).
Generates a new private key and CSR, then tries each configured issuer in order until one succeeds. The resulting certificate, key, and metadata are persisted to storage. A distributed lock is held during the operation to prevent duplicate issuance.
Sourcepub async fn obtain_in_background(&self, domain: &str) -> Result<()>
pub async fn obtain_in_background(&self, domain: &str) -> Result<()>
Obtain a new certificate asynchronously (background, with retries).
Same as CertManager::obtain but wraps the
operation in do_with_retry,
automatically retrying transient failures with exponential backoff.
Source§impl CertManager
impl CertManager
Sourcepub async fn renew(&self, domain: &str, force: bool) -> Result<()>
pub async fn renew(&self, domain: &str, force: bool) -> Result<()>
Renew a certificate synchronously (foreground, no retries).
Loads the existing certificate from storage, checks if renewal is
needed (unless force is true), generates a new key and CSR,
and tries each configured issuer in order. A distributed lock is
held during the operation. With force = true, a quarantined stored
resource may supply the SANs for a replacement with a new leaf; its old
leaf remains blocked and cannot be republished.
A stored certificate outside its validity period always needs renewal.
Sourcepub async fn renew_in_background(&self, domain: &str, force: bool) -> Result<()>
pub async fn renew_in_background(&self, domain: &str, force: bool) -> Result<()>
Renew a certificate asynchronously (background, with retries).
Same as CertManager::renew but wraps the
operation in do_with_retry,
automatically retrying transient failures with exponential backoff.
Source§impl CertManager
impl CertManager
Sourcepub async fn revoke(&self, domain: &str, reason: Option<u8>) -> Result<()>
pub async fn revoke(&self, domain: &str, reason: Option<u8>) -> Result<()>
Revoke the certificate for domain.
Select the stored resource using the same validity/latest-issuance
preference as certificate loading, independent of issuer order. Pending
or confirmed markers do not lower its rank: recording intent alone cannot
redirect a retry to an older backup. This revokes one stored resource, not every
certificate that can serve this domain. Use Self::revoke_from_issuer
to target a particular issuer’s resource.
Every invocation selects from current storage under the lifecycle lock;
if resources or their validity state have changed, a new call may select
a different leaf.
Before calling
the provider, persist revocation intent in the shared Storage and
quarantine this leaf in the local cache. Provider errors do not undo
that intent. After confirmation, delete the matching stored resource;
cleanup retries skip a provider call already recorded as confirmed.
reason is an optional RFC 5280 revocation reason code (0-10).
The operation runs in an owned task: dropping the caller’s future does not cancel it. Await the result to observe provider, cleanup and task errors. Runtime/process shutdown can still interrupt it; a persistent pending marker blocks reuse until provider reconciliation and cleanup.
Other instances must share the storage/lock backend and refresh their
existing caches with Self::refresh_revocations or maintenance. This
does not close existing TLS sessions or invalidate separately cloned
signing keys. A provider without crate::Revoker support is an error.
Sourcepub async fn revoke_from_issuer(
&self,
domain: &str,
issuer_key: &str,
reason: Option<u8>,
) -> Result<()>
pub async fn revoke_from_issuer( &self, domain: &str, issuer_key: &str, reason: Option<u8>, ) -> Result<()>
Revoke the resource currently stored for domain under an exact
configured issuer_key. Other issuers are not consulted or used as
fallbacks, including when the selected provider is unavailable or does
not support revocation.
Unlike default target selection, this recovery/cleanup path needs only a
parseable leaf certificate: an expired certificate, incorrect SAN or
damaged private key does not prevent provider-side revocation.
Ownership, locking, persisted intent and cleanup semantics are the same
as Self::revoke. This selects an issuer, not an immutable historical
leaf: if that issuer’s resource was replaced, a new call targets its
current resource.
Sourcepub async fn refresh_revocations(&self) -> Result<usize>
pub async fn refresh_revocations(&self) -> Result<usize>
Poll shared revocation intent and quarantine matching cached leaves. Other processes’ existing caches are not synchronously invalidated; applications may call this after receiving their own invalidation event. Reads at most eight unique leaf markers concurrently and returns the number of quarantined leaves. Alternate chains share one marker read. A failed read does not prevent other leaves from being quarantined; the first snapshot-order error is returned after all reads finish.
Source§impl CertManager
impl CertManager
Sourcepub fn server_config(&self) -> ServerConfig
pub fn server_config(&self) -> ServerConfig
Build a rustls::ServerConfig wired up to serve certificates from
this config’s cache.
The returned server config uses a CertResolver backed by the
config’s in-memory certificate cache, with ALPN protocols set to
["h2", "http/1.1"].
If default_server_name or
fallback_server_name are
configured, they are applied to the resolver.
On-demand issuance and custom certificate selection are also applied.
Without an explicit on-demand obtain callback, this manager performs
issuance in the background; the first handshake may still fail.
Source§impl CertManager
impl CertManager
Sourcepub async fn client_credentials(
&self,
domain: &str,
) -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>)>
pub async fn client_credentials( &self, domain: &str, ) -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>)>
Build TLS client credentials from a managed certificate.
Loads the certificate and private key for domain from the cache (or
storage) and returns them as a pair suitable for constructing a
rustls::ClientConfig for mutual TLS (mTLS) authentication.
Candidates must be time-valid and not locally known to be revoked.
Each call reads persisted revocation intent even for a warm cache;
backend errors are propagated. An unusable leaf does not hide a usable
sibling. Server Must-Staple policy is not applied to client identities,
and this method does not query an OCSP responder.
Returned credentials are an immutable validated snapshot. A later revocation or expiry does not invalidate previously exported keys or configurations; construct fresh credentials to check current state.
§Returns
A tuple of (cert_chain, private_key) where:
cert_chainis a list of DER-encoded certificates (leaf first).private_keyis the DER-encoded private key.
§Errors
Returns an error if no usable certificate is found for domain, or if
persisted revocation intent cannot be read.
Sourcepub async fn client_config(
&self,
domain: &str,
roots: impl Into<Arc<RootCertStore>>,
) -> Result<ClientConfig>
pub async fn client_config( &self, domain: &str, roots: impl Into<Arc<RootCertStore>>, ) -> Result<ClientConfig>
Build a rustls::ClientConfig for mutual TLS (mTLS) using a
managed certificate.
This is a convenience wrapper around Self::client_credentials.
roots supplies the trust anchors used to authenticate the server;
client credentials do not establish trust in the server’s certificate.
Pass a store (or a shared Arc of one) populated with your trusted CAs.
An empty store rejects servers whose certificates require a trust anchor.
§Errors
Returns an error if no suitable certificate is found or if TLS configuration fails.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for CertManager
impl !UnwindSafe for CertManager
impl Freeze for CertManager
impl Send for CertManager
impl Sync for CertManager
impl Unpin for CertManager
impl UnsafeUnpin for CertManager
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more