Skip to content

Commit 28c32aa

Browse files
committed
Update spiffe/README.md
Signed-off-by: Max Lambrecht <[email protected]>
1 parent 7ee91ba commit 28c32aa

File tree

1 file changed

+97
-107
lines changed

1 file changed

+97
-107
lines changed

spiffe/README.md

Lines changed: 97 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,165 +1,155 @@
1-
# Rust SPIFFE Library
1+
# Rust SPIFFE
22

3-
This utility library enables interaction with the [SPIFFE Workload API](https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Workload_API.md). It allows fetching of X.509 and JWT SVIDs, bundles and supports watch/stream updates. The types in the library are in compliance with [SPIFFE standards](https://github.com/spiffe/spiffe/tree/main/standards). More about SPIFFE can be found at [spiffe.io](https://spiffe.io/).
3+
A Rust library for interacting with the **SPIFFE Workload API**.
4+
It provides idiomatic access to SPIFFE identities and trust material, including:
5+
6+
- X.509 SVIDs and bundles
7+
- JWT SVIDs and bundles
8+
- Streaming updates (watch semantics)
9+
- Strongly typed SPIFFE primitives compliant with the SPIFFE standards
10+
11+
For background on SPIFFE, see <https://spiffe.io>.
12+
For the Workload API specification, see the
13+
[SPIFFE Workload API standard](https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Workload_API.md).
414

515
[![crates.io](https://img.shields.io/crates/v/spiffe.svg)](https://crates.io/crates/spiffe)
616
[![Build](https://github.com/maxlambrecht/rust-spiffe/actions/workflows/ci.yml/badge.svg)](https://github.com/maxlambrecht/rust-spiffe/actions/workflows/ci.yml)
717
[![docs.rs](https://docs.rs/spiffe/badge.svg)](https://docs.rs/spiffe)
8-
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/maxlambrecht/rust-spiffe/blob/main/LICENSE)
18+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
19+
20+
---
921

10-
## Getting Started
22+
## Installation
1123

12-
Include `spiffe` in your `Cargo.toml` dependencies to get both the SPIFFE types (`spiffe-types`) and the Workload API
13-
client (`workload-api`) by default:
24+
Add `spiffe` to your `Cargo.toml`:
1425

1526
```toml
1627
[dependencies]
1728
spiffe = "0.6.7"
18-
```
29+
````
1930

20-
## Examples of Usage
31+
This includes both SPIFFE core types and a Workload API client.
2132

22-
### Creating a `WorkloadApiClient`
33+
---
2334

24-
Create client using the endpoint socket path:
35+
## Quick Start
2536

26-
```rust
27-
let mut client = WorkloadApiClient::new_from_path("unix:/tmp/spire-agent/public/api.sock").await?;
28-
```
37+
### Create a Workload API client
2938

30-
Or by using the `SPIFFE_ENDPOINT_SOCKET` environment variable:
39+
Using an explicit socket path:
3140

3241
```rust
33-
let mut client = WorkloadApiClient::default().await?;
34-
```
42+
use spiffe::WorkloadApiClient;
3543

36-
### Fetching X.509 Materials
44+
let client = WorkloadApiClient::new_from_path(
45+
"unix:///tmp/spire-agent/public/api.sock",
46+
).await?;
47+
```
3748

38-
Fetch the default X.509 SVID, a set of X.509 bundles, all X.509 materials, or watch for updates on the X.509 context and bundles.
49+
Or via the `SPIFFE_ENDPOINT_SOCKET` environment variable:
3950

4051
```rust
41-
// fetch the default X.509 SVID
42-
let x509_svid: X509Svid = client.fetch_x509_svid().await?;
52+
use spiffe::WorkloadApiClient;
4353

44-
// fetch a set of X.509 bundles (X.509 public key authorities)
45-
let x509_bundles: X509BundleSet = client.fetch_x509_bundles().await?;
54+
let client = WorkloadApiClient::default().await?;
55+
```
4656

47-
// fetch all the X.509 materials (SVIDs and bundles)
48-
let x509_context: X509Context = client.fetch_x509_context().await?;
57+
---
4958

50-
// get the X.509 chain of certificates from the SVID
51-
let cert_chain: &Vec<Certificate> = x509_svid.cert_chain();
59+
## X.509 identities
5260

53-
// get the private key from the SVID
54-
let private_key: &PrivateKey = x509_svid.private_key();
61+
### Fetch X.509 materials directly
62+
63+
```rust
64+
use spiffe::{TrustDomain, X509Context};
65+
66+
let svid = client.fetch_x509_svid().await?;
67+
let bundles = client.fetch_x509_bundles().await?;
68+
let context: X509Context = client.fetch_x509_context().await?;
5569

56-
// parse a SPIFFE trust domain
5770
let trust_domain = TrustDomain::try_from("example.org")?;
71+
let bundle = bundles.get_bundle(&trust_domain)?;
72+
```
5873

59-
// get the X.509 bundle associated to the trust domain
60-
let x509_bundle: &X509Bundle = x509_bundles.get_bundle(&trust_domain)?;
61-
62-
// get the X.509 authorities (public keys) in the bundle
63-
let x509_authorities: &Vec<Certificate> = x509_bundle.authorities();
64-
65-
// watch for updates on the X.509 context
66-
let mut x509_context_stream = client.stream_x509_contexts().await?;
67-
while let Some(x509_context_update) = x509_context_stream.next().await {
68-
match x509_context_update {
69-
Ok(update) => {
70-
// handle the updated X509Context
71-
}
72-
Err(e) => {
73-
// handle the error
74-
}
75-
}
76-
}
74+
### Watch for updates
75+
76+
```rust
77+
let mut stream = client.stream_x509_contexts().await?;
7778

78-
// watch for updates on the X.509 bundles
79-
let mut x509_bundle_stream = client.stream_x509_bundles().await?;
80-
while let Some(x509_bundle_update) = x509_bundle_stream.next().await {
81-
match x509_bundle_update {
82-
Ok(update) => {
83-
// handle the updated X509 bundle
84-
}
85-
Err(e) => {
86-
// handle the error
87-
}
88-
}
79+
while let Some(update) = stream.next().await {
80+
let context = update?;
81+
// react to updated SVIDs / bundles
8982
}
9083
```
9184

92-
### Fetching X.509 Materials using `X509Source`
85+
---
86+
87+
## X.509Source (recommended)
9388

94-
A convenient way to fetch X.509 materials is by using the `X509Source`:
89+
`X509Source` maintains a locally cached, automatically refreshed view of X.509
90+
SVIDs and bundles.
9591

9692
```rust
9793
use spiffe::X509Source;
98-
use spiffe::BundleSource;
99-
use spiffe::TrustDomain;
100-
use spiffe::X509Svid;
101-
use spiffe::SvidSource;
102-
103-
async fn fetch_x509_materials() -> Result<(), Box<dyn std::error::Error>> {
104-
// Create a new X509Source
105-
let x509_source = X509Source::default().await?;
10694

107-
// Fetch the SVID
108-
let svid = x509_source.get_svid()?.ok_or("No X509Svid found")?;
95+
let source = X509Source::new().await?;
10996

110-
// Fetch the bundle for a specific trust domain
111-
let trust_domain = spiffe::TrustDomain::new("example.org"); // Replace with the appropriate trust domain
112-
let bundle = x509_source.get_bundle_for_trust_domain(&trust_domain)?.ok_or("No bundle found for trust domain")?;
97+
// Default SVID
98+
let svid = source.get_svid()?.expect("no SVID available");
11399

114-
Ok(())
115-
}
100+
// Bundle for a trust domain
101+
let bundle = source
102+
.get_bundle_for_trust_domain(&"example.org".try_into()?)?
103+
.expect("no bundle found");
116104
```
117105

118-
### Fetching and Validating JWT Tokens and Bundles
106+
---
107+
108+
## JWT identities
119109

120-
Fetch JWT tokens, parse and validate them, fetch JWT bundles, or watch for updates on the JWT bundles.
110+
### Fetch and validate JWT SVIDs
121111

122112
```rust
123-
// parse a SPIFFE ID to ask a token for
113+
use spiffe::{JwtSvid, SpiffeId};
114+
124115
let spiffe_id = SpiffeId::try_from("spiffe://example.org/my-service")?;
125116

126-
// fetch a jwt token for the provided SPIFFE-ID and with the target audience `service1.com`
127-
let jwt_token = client.fetch_jwt_token(&["audience1", "audience2"], Some(&spiffe_id)).await?;
117+
let jwt = client
118+
.fetch_jwt_svid(&["audience1", "audience2"], Some(&spiffe_id))
119+
.await?;
120+
```
128121

129-
// fetch the jwt token and parses it as a `JwtSvid`
130-
let jwt_svid = client.fetch_jwt_svid(&["audience1", "audience2"], Some(&spiffe_id)).await?;
122+
### Fetch JWT bundles
131123

132-
// fetch a set of jwt bundles (public keys for validating jwt token)
133-
let jwt_bundles = client.fetch_jwt_bundles().await?;
124+
```rust
125+
use spiffe::TrustDomain;
134126

135-
// parse a SPIFFE trust domain
127+
let bundles = client.fetch_jwt_bundles().await?;
136128
let trust_domain = TrustDomain::try_from("example.org")?;
129+
let bundle = bundles.get_bundle(&trust_domain)?;
130+
```
131+
132+
### Watch JWT bundle updates
133+
134+
```rust
135+
let mut stream = client.stream_jwt_bundles().await?;
137136

138-
// get the JWT bundle associated to the trust domain
139-
let jwt_bundle: &JwtBundle = jwt_bundles.get_bundle(&trust_domain)?;
140-
141-
// get the JWT authorities (public keys) in the bundle
142-
let jwt_authority: &JwtAuthority = jwt_bundle.find_jwt_authority("a_key_id")?;
143-
144-
// parse a `JwtSvid` validating the token signature with a JWT bundle source.
145-
let validated_jwt_svid = JwtSvid::parse_and_validate(&jwt_token, &jwt_bundles_set, &["service1.com"])?;
146-
147-
// watch for updates on the JWT bundles
148-
let mut jwt_bundle_stream = client.stream_jwt_bundles().await?;
149-
while let Some(jwt_bundle_update) = jwt_bundle_stream.next().await {
150-
match jwt_bundle_update {
151-
Ok(update) => {
152-
// handle the updated JWT bundle
153-
}
154-
Err(e) => {
155-
// handle the error
156-
}
157-
}
137+
while let Some(update) = stream.next().await {
138+
let bundles = update?;
139+
// react to updated JWT authorities
158140
}
159141
```
160142

161-
For more detailed examples and additional features, refer to the [documentation](https://docs.rs/spiffe).
143+
---
144+
145+
## Documentation
146+
147+
API documentation and additional examples are available on [docs.rs](https://docs.rs/spiffe).
148+
149+
---
162150

163151
## License
164152

165-
This library is licensed under the Apache License. See the [LICENSE.md](../LICENSE) file for details.
153+
Licensed under the Apache License, Version 2.0.
154+
See [LICENSE](../LICENSE) for details.
155+

0 commit comments

Comments
 (0)