pub struct ClientConfigBuilder { /* private fields */ }Expand description
Builds a rustls::ClientConfig backed by a live SPIFFE X509Source.
The resulting client configuration:
- presents the current SPIFFE X.509 SVID as the client certificate
- validates the server certificate chain against trust bundles from the Workload API
- authorizes the server by SPIFFE ID (URI SAN)
The builder retains an Arc<X509Source>. When the underlying SVID or trust
bundle is rotated by the SPIRE agent, new TLS handshakes automatically use
the updated material.
§Trust Domain Selection
The builder uses the bundle set from X509Source, which may contain bundles
for multiple trust domains (when SPIFFE federation is configured). The verifier
automatically selects the correct bundle based on the peer’s SPIFFE ID—no
manual configuration is required. You can optionally restrict which trust
domains are accepted using Self::trust_domain_policy.
§Authorization
Server authorization is performed by invoking the provided Authorizer with
the server’s SPIFFE ID extracted from the certificate’s URI SAN.
Use [authorizer::any] to disable authorization while retaining full TLS authentication.
§Examples
use spiffe_rustls::{authorizer, mtls_client, AllowList};
use std::collections::BTreeSet;
let source = spiffe::X509Source::new().await?;
// Pass string literals directly - exact() and trust_domains() will convert them
let allowed_server_ids = [
"spiffe://example.org/myservice",
"spiffe://example.org/myservice2",
];
let mut allowed_trust_domains = BTreeSet::new();
allowed_trust_domains.insert("example.org".try_into()?);
let client_config = mtls_client(source)
.authorize(authorizer::exact(allowed_server_ids)?)
.trust_domain_policy(AllowList(allowed_trust_domains))
.build()?;Implementations§
Source§impl ClientConfigBuilder
impl ClientConfigBuilder
Sourcepub fn new(source: X509Source) -> Self
pub fn new(source: X509Source) -> Self
Creates a new builder from an X509Source.
Defaults:
- Authorization: accepts any SPIFFE ID (authentication only)
- Trust domain policy:
AnyInBundleSet(uses all bundles from the Workload API) - ALPN protocols: empty (no ALPN)
Sets the authorization policy for server SPIFFE IDs.
Accepts any type that implements Authorizer, including closures.
§Examples
use spiffe_rustls::{authorizer, mtls_client};
let source = spiffe::X509Source::new().await?;
// Pass string literals directly
let config = mtls_client(source.clone())
.authorize(authorizer::exact([
"spiffe://example.org/service",
"spiffe://example.org/service2",
])?)
.build()?;
// Using a closure
let config = mtls_client(source.clone())
.authorize(|id: &spiffe::SpiffeId| id.path().starts_with("/api/"))
.build()?;
// Using the Any authorizer (default)
let config = mtls_client(source)
.authorize(authorizer::any())
.build()?;Sourcepub fn trust_domain_policy(self, policy: TrustDomainPolicy) -> Self
pub fn trust_domain_policy(self, policy: TrustDomainPolicy) -> Self
Sets the trust domain policy.
Defaults to AnyInBundleSet (uses all bundles from the Workload API).
Sourcepub fn with_alpn_protocols<I, P>(self, protocols: I) -> Self
pub fn with_alpn_protocols<I, P>(self, protocols: I) -> Self
Sets the ALPN (Application-Layer Protocol Negotiation) protocols.
The protocols are advertised during the TLS handshake. Common values:
b"h2"for HTTP/2 (required for gRPC)b"http/1.1"for HTTP/1.1
Protocols should be specified in order of preference (most preferred first).
§Examples
use spiffe_rustls::mtls_client;
let source = spiffe::X509Source::new().await?;
let config = mtls_client(source)
.with_alpn_protocols([b"h2"])
.build()?;Sourcepub fn with_config_customizer<F>(self, customizer: F) -> Self
pub fn with_config_customizer<F>(self, customizer: F) -> Self
Applies a customizer function to the ClientConfig after it’s built.
This is an advanced API for configuration not directly exposed by the builder. The customizer is called last, after all other builder settings (including ALPN) have been applied, allowing you to override any configuration.
Warning: Do not modify or replace the verifier or client certificate resolver, as they are required for SPIFFE authentication and authorization. Safe to modify: ALPN, cipher suites, protocol versions, and other non-security-critical settings.
§Examples
use spiffe_rustls::mtls_client;
let source = spiffe::X509Source::new().await?;
let config = mtls_client(source)
.with_config_customizer(|cfg| {
// Example: adjust cipher suite preferences
})
.build()?;Sourcepub fn build(self) -> Result<ClientConfig>
pub fn build(self) -> Result<ClientConfig>
Builds the rustls::ClientConfig.
The returned configuration:
- presents the current SPIFFE X.509 SVID as the client certificate
- validates the server certificate chain against trust bundles from the Workload API
- authorizes the server by SPIFFE ID (URI SAN)
The configuration is backed by a live X509Source. When the underlying
SVID or trust bundle is rotated by the SPIRE agent, new TLS handshakes
automatically use the updated material.
§Errors
Returns an error if:
- the Rustls crypto provider is not installed
- no current X.509 SVID is available from the
X509Source - building the underlying Rustls certificate verifier fails
Trait Implementations§
Auto Trait Implementations§
impl Freeze for ClientConfigBuilder
impl !RefUnwindSafe for ClientConfigBuilder
impl Send for ClientConfigBuilder
impl !Sync for ClientConfigBuilder
impl Unpin for ClientConfigBuilder
impl !UnwindSafe for ClientConfigBuilder
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
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> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request