pub struct ServerConfigBuilder { /* private fields */ }Expand description
Builds a rustls::ServerConfig backed by a live SPIFFE X509Source.
The resulting server configuration:
- presents the current SPIFFE X.509 SVID as the server certificate
- requires and validates client certificates (mTLS)
- authorizes the client by SPIFFE ID (URI SAN)
§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.
The default policy is TrustDomainPolicy::AnyInBundleSet, which accepts any
trust domain present in the source bundle set. For non-federated deployments,
prefer TrustDomainPolicy::LocalOnly to restrict verification to the local
trust domain.
§Authorization
Client authorization is performed by invoking the provided Authorizer with
the client’s SPIFFE ID extracted from the certificate’s URI SAN.
The default authorizer is crate::authorizer::any. It accepts any authenticated
SPIFFE ID from any trust domain accepted by the configured trust-domain policy.
By default, this means every trust domain in the source bundle set.
Security: with the default configuration, authentication validates the
client certificate against the trust bundle for the peer’s SPIFFE ID trust
domain. Authorization uses crate::authorizer::any together with
TrustDomainPolicy::AnyInBundleSet, so any client whose certificate
validates and whose SPIFFE ID is accepted by that policy is allowed.
Production deployments should normally configure a specific Authorizer
(via Self::authorize) and an appropriate TrustDomainPolicy (via
Self::trust_domain_policy); TrustDomainPolicy::LocalOnly is suitable
when federation is not required.
§Examples
use spiffe::{TrustDomain, X509Source};
use spiffe_rustls::{authorizer, mtls_server, LocalOnly};
let source = X509Source::new().await?;
// Pass string literals directly - trust_domains() will convert them
let allowed_trust_domains = ["example.org"];
let local_trust_domain: TrustDomain = "example.org".try_into()?;
let server_config = mtls_server(source)
.authorize(authorizer::trust_domains(allowed_trust_domains)?)
.trust_domain_policy(LocalOnly(local_trust_domain))
.build()?;Implementations§
Source§impl ServerConfigBuilder
impl ServerConfigBuilder
Sourcepub fn new(source: X509Source) -> Self
pub fn new(source: X509Source) -> Self
Creates a new builder from an X509Source.
Defaults:
- Authorization:
crate::authorizer::any, which accepts any authenticated SPIFFE ID from any trust domain accepted by the configured trust-domain policy. By default, this means every trust domain in the source bundle set. - Trust domain policy:
TrustDomainPolicy::AnyInBundleSet, which accepts any trust domain present in the source bundle set - ALPN protocols: empty (no ALPN)
With the default configuration, authentication validates the peer
certificate against the configured trust bundle, and authorization uses
crate::authorizer::any with TrustDomainPolicy::AnyInBundleSet.
Production deployments should normally configure a specific authorizer via
Self::authorize and an appropriate trust domain policy via
Self::trust_domain_policy; TrustDomainPolicy::LocalOnly is suitable
when federation is not required.
Sets the authorization policy for client SPIFFE IDs.
Accepts any type that implements Authorizer, including closures.
§Examples
use spiffe_rustls::{authorizer, mtls_server};
let source = spiffe::X509Source::new().await?;
// Pass string literals directly
let config = mtls_server(source.clone())
.authorize(authorizer::trust_domains([
"example.org",
])?)
.build()?;
// Using a closure
let config = mtls_server(source.clone())
.authorize(|id: &spiffe::SpiffeId| id.path().starts_with("/api/"))
.build()?;
// Using the Any authorizer (default)
let config = mtls_server(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 TrustDomainPolicy::AnyInBundleSet, which accepts any trust
domain present in the source bundle set. For non-federated deployments,
prefer TrustDomainPolicy::LocalOnly to restrict verification to the local
trust domain.
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_server;
let source = spiffe::X509Source::new().await?;
let config = mtls_server(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 ServerConfig 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, and gives direct access to the underlying rustls
configuration.
Warning: Replacing the verifier or resolver disables SPIFFE authentication.
Do not use this hook for that purpose; build a custom rustls configuration instead.
§Examples
use spiffe_rustls::mtls_server;
let source = spiffe::X509Source::new().await?;
let config = mtls_server(source)
.with_config_customizer(|cfg| {
// Example: adjust cipher suite preferences
})
.build()?;Sourcepub fn build(self) -> Result<ServerConfig>
pub fn build(self) -> Result<ServerConfig>
Builds the rustls::ServerConfig.
TLS session resumption (stateful session caching and TLS 1.3 session
tickets) is disabled by default. rustls does not re-invoke the
client certificate verifier on a resumed handshake, so resumption would
let a session outlive its SVID’s (deliberately short) expiry, and
bypass a bundle or authorizer change (e.g. defederation, a tightened
allow list) until the cached session/ticket ages out. SPIRE’s own TLS
server endpoint disables session tickets for the same reason. If you
understand this trade-off and want resumption for its performance
benefit, re-enable it via Self::with_config_customizer by setting
cfg.session_storage and cfg.send_tls13_tickets.
§Errors
Returns an error if:
- the SPIFFE
X509Sourcedoes not currently have an SVID, - rustls crypto providers are not installed,
- or the material watcher cannot be initialized.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for ServerConfigBuilder
impl !Sync for ServerConfigBuilder
impl !UnwindSafe for ServerConfigBuilder
impl Freeze for ServerConfigBuilder
impl Send for ServerConfigBuilder
impl Unpin for ServerConfigBuilder
impl UnsafeUnpin for ServerConfigBuilder
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