Skip to content

Commit 21b694c

Browse files
authored
Prepare release spiffe-rustls 0.1.3 (#207)
Signed-off-by: Max Lambrecht <[email protected]>
1 parent 7108624 commit 21b694c

File tree

6 files changed

+154
-75
lines changed

6 files changed

+154
-75
lines changed

spiffe-rustls/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## [0.1.3] – 2025-12-24
4+
5+
* Documentation improvements only. No functional changes.
6+
7+
38
## [0.1.2] – 2025-12-24
49

510
* Migrated to the Rust 2021 edition.

spiffe-rustls/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "spiffe-rustls"
3-
version = "0.1.2"
3+
version = "0.1.3"
44
edition = "2021"
55
rust-version = "1.83"
66
license = "Apache-2.0"

spiffe-rustls/README.md

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,46 +16,57 @@ delegating all cryptography and TLS mechanics to `rustls`.
1616

1717
---
1818

19-
## Features
19+
## Quick start
2020

21-
`spiffe-rustls` supports multiple `rustls` crypto providers:
21+
### 1. Create an X509Source
2222

23-
```toml
24-
[features]
25-
default = ["ring"]
26-
ring = ["rustls/ring"]
27-
aws-lc-rs = ["rustls/aws_lc_rs"]
23+
The source is configured via `SPIFFE_ENDPOINT_SOCKET`:
24+
25+
```rust
26+
let source = spiffe::X509Source::new().await?;
2827
````
2928

30-
* **Default:** `ring`
31-
* **Optional:** `aws-lc-rs`
29+
---
3230

33-
Exactly **one** provider must be enabled. Enabling more than one results in a compile-time error.
31+
### 2. Build a rustls client configuration
3432

35-
Example (AWS-LC):
33+
```rust
34+
use spiffe_rustls::{ClientConfigBuilder, ClientConfigOptions};
35+
use std::sync::Arc;
3636

37-
```bash
38-
cargo add spiffe-rustls --no-default-features --features aws-lc-rs
37+
let opts = ClientConfigOptions {
38+
trust_domain: "example.org".try_into()?,
39+
// Authorize the server by its SPIFFE ID (connection-level authorization)
40+
authorize_server: Arc::new(|id: &str| {
41+
id == "spiffe://example.org/myservice"
42+
}),
43+
};
44+
45+
let client_cfg = ClientConfigBuilder::new(source.clone(), opts)
46+
.build()
47+
.await?;
3948
```
4049

41-
Provider choice affects only cryptographic primitives; **SPIFFE semantics and API behavior are
42-
identical** across providers.
50+
The resulting `ClientConfig` can be used directly with `rustls`, or integrated into
51+
`tokio-rustls`, `tonic-rustls`, or similar libraries.
4352

4453
---
4554

46-
## Public API
55+
## API overview
4756

48-
The public API is intentionally small:
57+
The public API is intentionally small and consists of two builders:
4958

50-
* `ClientConfigBuilder`, `ClientConfigOptions`
51-
* `ServerConfigBuilder`, `ServerConfigOptions`
59+
* `ClientConfigBuilder`
60+
* `ServerConfigBuilder`
5261

53-
Both builders retain an `Arc<X509Source>` and always use the **latest SVIDs and bundles** for new TLS
54-
handshakes.
62+
Each builder:
5563

56-
---
64+
* retains an `Arc<X509Source>`
65+
* builds a `rustls::{ClientConfig, ServerConfig}`
66+
* always uses the **latest SVIDs and trust bundles**
67+
* authorizes peers by SPIFFE ID (URI SAN)
5768

58-
## Builders
69+
---
5970

6071
### ClientConfigBuilder
6172

@@ -65,6 +76,8 @@ Builds a `rustls::ClientConfig` that:
6576
* validates the server certificate chain against the trust domain bundle
6677
* authorizes the server by SPIFFE ID (URI SAN)
6778

79+
---
80+
6881
### ServerConfigBuilder
6982

7083
Builds a `rustls::ServerConfig` that:
@@ -111,38 +124,30 @@ authentication.
111124

112125
---
113126

114-
## Quick start
115-
116-
### 1. Create an X509Source
127+
## Features
117128

118-
The source is configured via `SPIFFE_ENDPOINT_SOCKET`:
129+
`spiffe-rustls` supports multiple `rustls` crypto providers:
119130

120-
```rust
121-
let source = spiffe::X509Source::new().await?;
131+
```toml
132+
[features]
133+
default = ["ring"]
134+
ring = ["rustls/ring"]
135+
aws-lc-rs = ["rustls/aws_lc_rs"]
122136
```
123137

124-
---
125-
126-
### 2. Build a rustls client configuration
138+
* **Default:** `ring`
139+
* **Optional:** `aws-lc-rs`
127140

128-
```rust
129-
use spiffe_rustls::{ClientConfigBuilder, ClientConfigOptions};
130-
use std::sync::Arc;
141+
Exactly **one** provider must be enabled. Enabling more than one results in a compile-time error.
131142

132-
let opts = ClientConfigOptions {
133-
trust_domain: "example.org".try_into()?,
134-
authorize_server: Arc::new(|id: &str| {
135-
id == "spiffe://example.org/myservice"
136-
}),
137-
};
143+
Example (AWS-LC):
138144

139-
let client_cfg = ClientConfigBuilder::new(source.clone(), opts)
140-
.build()
141-
.await?;
145+
```bash
146+
cargo add spiffe-rustls --no-default-features --features aws-lc-rs
142147
```
143148

144-
The resulting `ClientConfig` can be used directly with `rustls`, or integrated into
145-
`tokio-rustls`, `tonic-rustls`, or similar libraries.
149+
Provider choice affects only cryptographic primitives; **SPIFFE semantics and API behavior are
150+
identical** across providers.
146151

147152
---
148153

spiffe-rustls/src/client.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,26 @@ use rustls::ClientConfig;
77
use spiffe::{TrustDomain, X509Source};
88
use std::sync::Arc;
99

10-
/// Options for building a SPIFFE-aware `rustls::ClientConfig`.
10+
/// Configuration options for [`ClientConfigBuilder`].
11+
///
12+
/// These options control trust bundle selection and server authorization.
1113
#[derive(Clone)]
1214
pub struct ClientConfigOptions {
1315
/// Trust domain whose bundle is used as the verification root set.
1416
pub trust_domain: TrustDomain,
1517

1618
/// Authorization hook invoked with the server SPIFFE ID.
1719
///
18-
/// Returning `false` rejects the peer even if the certificate chain is valid.
20+
/// The hook receives the SPIFFE ID extracted from the server certificate’s
21+
/// URI SAN and must return `true` to allow the connection.
1922
pub authorize_server: AuthorizeSpiffeId,
2023
}
2124

2225
impl ClientConfigOptions {
23-
/// Creates options that accept any server SPIFFE ID for the given trust domain.
26+
/// Creates options that authenticate the server but allow any SPIFFE ID.
2427
///
25-
/// Authentication still happens via bundle verification; only authorization is permissive.
28+
/// This disables authorization while retaining full TLS authentication.
29+
/// Use only if authorization is performed at another layer.
2630
pub fn allow_any(trust_domain: TrustDomain) -> Self {
2731
Self {
2832
trust_domain,
@@ -31,14 +35,26 @@ impl ClientConfigOptions {
3135
}
3236
}
3337

34-
/// Builds a `rustls::ClientConfig` backed by an [`spiffe::X509Source`].
38+
/// Builds a [`rustls::ClientConfig`] backed by a live SPIFFE `X509Source`.
39+
///
40+
/// The resulting client configuration:
41+
///
42+
/// * presents the current SPIFFE X.509 SVID as the client certificate
43+
/// * validates the server certificate chain against the trust domain bundle
44+
/// * authorizes the server by SPIFFE ID (URI SAN)
45+
///
46+
/// The builder retains an `Arc<X509Source>`. When the underlying SVID or trust
47+
/// bundle is rotated by the SPIRE agent, **new TLS handshakes automatically use
48+
/// the updated material**.
49+
///
50+
/// ## Authorization
3551
///
36-
/// The resulting config:
37-
/// - presents the current SVID as the client certificate
38-
/// - verifies server certificates using the trust domain bundle
39-
/// - authorizes the server by SPIFFE ID (URI SAN)
52+
/// Server authorization is performed by invoking the provided
53+
/// [`AuthorizeSpiffeId`] hook with the server’s SPIFFE ID extracted from the
54+
/// certificate’s URI SAN.
4055
///
41-
/// New handshakes use the latest SVID/bundle material after rotations.
56+
/// Use [`ClientConfigOptions::allow_any`] to disable authorization while
57+
/// retaining full TLS authentication.
4258
pub struct ClientConfigBuilder {
4359
source: Arc<X509Source>,
4460
opts: ClientConfigOptions,

spiffe-rustls/src/lib.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,51 @@
1-
//! rustls integration for SPIFFE `X509Source` (SPIRE Workload API).
1+
//! # spiffe-rustls
22
//!
3-
//! This crate builds `rustls::ClientConfig` and `rustls::ServerConfig` that use an always-up-to-date
4-
//! [`spiffe::X509Source`] for:
5-
//! - the local X.509 SVID (certificate + private key)
6-
//! - the trust bundle for peer verification (by trust domain)
3+
//! `spiffe-rustls` integrates [`rustls`] with SPIFFE/SPIRE using a live
4+
//! [`spiffe::X509Source`] (SPIFFE Workload API).
75
//!
8-
//! Peer authorization is performed using a user-provided callback over the peer SPIFFE ID
9-
//! (URI SAN, e.g. `spiffe://example.org/myservice`).
6+
//! It provides builders for [`rustls::ClientConfig`] and
7+
//! [`rustls::ServerConfig`] that are backed by an `X509Source`. When the SPIRE
8+
//! agent rotates X.509 SVIDs or trust bundles, **new TLS handshakes automatically
9+
//! use the updated material**, without restarting the application.
1010
//!
11-
//! See `examples/mtls_tcp_client` and `examples/mtls_tcp_server` for complete runnable examples.
11+
//! The crate focuses on TLS authentication and **connection-level authorization
12+
//! via SPIFFE IDs**, while delegating all cryptography and TLS mechanics to
13+
//! `rustls`.
14+
//!
15+
//! ## Quick example (client)
16+
//!
17+
//! ```no_run
18+
//! use spiffe_rustls::{ClientConfigBuilder, ClientConfigOptions};
19+
//! use std::sync::Arc;
20+
//!
21+
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
22+
//! let source = spiffe::X509Source::new().await?;
23+
//!
24+
//! let opts = ClientConfigOptions {
25+
//! trust_domain: "example.org".try_into()?,
26+
//! authorize_server: Arc::new(|id: &str| {
27+
//! id == "spiffe://example.org/myservice"
28+
//! }),
29+
//! };
30+
//!
31+
//! let client_config = ClientConfigBuilder::new(source, opts)
32+
//! .build()
33+
//! .await?;
34+
//! # Ok(())
35+
//! # }
36+
//! ```
37+
//!
38+
//! The resulting `ClientConfig` can be used directly with `rustls` or integrated
39+
//! into higher-level libraries such as `tokio-rustls` or `tonic-rustls`.
40+
//!
41+
//! ## Feature flags
42+
//!
43+
//! Exactly **one** `rustls` crypto provider must be enabled:
44+
//!
45+
//! * `ring` (default)
46+
//! * `aws-lc-rs`
47+
//!
48+
//! Enabling more than one provider results in a compile-time error.
1249
1350
#[cfg(all(feature = "ring", feature = "aws-lc-rs"))]
1451
compile_error!("Enable only one crypto provider feature: `ring` or `aws-lc-rs`.");

spiffe-rustls/src/server.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,26 @@ use rustls::ServerConfig;
77
use spiffe::{TrustDomain, X509Source};
88
use std::sync::Arc;
99

10-
/// Options for building a SPIFFE-aware `rustls::ServerConfig`.
10+
/// Configuration options for [`ServerConfigBuilder`].
11+
///
12+
/// These options control trust bundle selection and client authorization.
1113
#[derive(Clone)]
1214
pub struct ServerConfigOptions {
1315
/// Trust domain whose bundle is used as the verification root set.
1416
pub trust_domain: TrustDomain,
1517

1618
/// Authorization hook invoked with the client SPIFFE ID.
1719
///
18-
/// Returning `false` rejects the peer even if the certificate chain is valid.
20+
/// The hook receives the SPIFFE ID extracted from the client certificate’s
21+
/// URI SAN and must return `true` to allow the connection.
1922
pub authorize_client: AuthorizeSpiffeId,
2023
}
2124

2225
impl ServerConfigOptions {
23-
/// Creates options that accept any client SPIFFE ID for the given trust domain.
26+
/// Creates options that authenticate clients but allow any SPIFFE ID.
2427
///
25-
/// Authentication still happens via bundle verification; only authorization is permissive.
28+
/// This disables authorization while retaining full TLS authentication.
29+
/// Use only if authorization is performed at another layer.
2630
pub fn allow_any(trust_domain: TrustDomain) -> Self {
2731
Self {
2832
trust_domain,
@@ -31,14 +35,26 @@ impl ServerConfigOptions {
3135
}
3236
}
3337

34-
/// Builds a `rustls::ServerConfig` backed by an [`spiffe::X509Source`].
38+
/// Builds a [`rustls::ServerConfig`] backed by a live SPIFFE `X509Source`.
39+
///
40+
/// The resulting server configuration:
41+
///
42+
/// * presents the current SPIFFE X.509 SVID as the server certificate
43+
/// * requires and validates client certificates (mTLS)
44+
/// * authorizes the client by SPIFFE ID (URI SAN)
45+
///
46+
/// The builder retains an `Arc<X509Source>`. When the underlying SVID or trust
47+
/// bundle is rotated by the SPIRE agent, **new TLS handshakes automatically use
48+
/// the updated material**.
49+
///
50+
/// ## Authorization
3551
///
36-
/// The resulting config:
37-
/// - presents the current SVID as the server certificate
38-
/// - requires and verifies client certificates (mTLS) using the trust domain bundle
39-
/// - authorizes the client by SPIFFE ID (URI SAN)
52+
/// Client authorization is performed by invoking the provided
53+
/// [`AuthorizeSpiffeId`] hook with the client’s SPIFFE ID extracted from the
54+
/// certificate’s URI SAN.
4055
///
41-
/// New handshakes use the latest SVID/bundle material after rotations.
56+
/// Use [`ServerConfigOptions::allow_any`] to disable authorization while
57+
/// retaining full TLS authentication.
4258
pub struct ServerConfigBuilder {
4359
source: Arc<X509Source>,
4460
opts: ServerConfigOptions,

0 commit comments

Comments
 (0)