This utility library enables interaction with the SPIFFE Workload API. 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. More about SPIFFE can be found at spiffe.io.
Include spiffe
in your Cargo.toml
dependencies to get both the SPIFFE types (spiffe-types
) and the Workload API
client (workload-api
) by default:
toml
[dependencies]
spiffe = "0.4.0"
WorkloadApiClient
Create client using the endpoint socket path:
rust
let mut client = WorkloadApiClient::new_from_path("unix:/tmp/spire-agent/public/api.sock").await?;
Or by using the SPIFFE_ENDPOINT_SOCKET
environment variable:
rust
let mut client = WorkloadApiClient::default().await?;
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.
```rust // fetch the default X.509 SVID let x509svid: X509Svid = client.fetchx509_svid().await?;
// fetch a set of X.509 bundles (X.509 public key authorities) let x509bundles: X509BundleSet = client.fetchx509_bundles().await?;
// fetch all the X.509 materials (SVIDs and bundles) let x509context: X509Context = client.fetchx509_context().await?;
// get the X.509 chain of certificates from the SVID
let certchain: &Vec
// get the private key from the SVID let privatekey: &PrivateKey = x509svid.private_key();
// parse a SPIFFE trust domain let trustdomain = TrustDomain::tryfrom("example.org")?;
// get the X.509 bundle associated to the trust domain let x509bundle: &X509Bundle = x509bundles.getbundle(&trustdomain)?;
// get the X.509 authorities (public keys) in the bundle
let x509authorities: &Vec
// watch for updates on the X.509 context let mut x509contextstream = client.streamx509contexts().await?; while let Some(x509contextupdate) = x509contextstream.next().await { match x509contextupdate { Ok(update) => { // handle the updated X509Context } Err(e) => { // handle the error } } }
// watch for updates on the X.509 bundles let mut x509bundlestream = client.streamx509bundles().await?; while let Some(x509bundleupdate) = x509bundlestream.next().await { match x509bundleupdate { Ok(update) => { // handle the updated X509 bundle } Err(e) => { // handle the error } } } ```
X509Source
A convenient way to fetch X.509 materials is by using the X509Source
:
```rust use spiffe::workloadapi::x509source::X509Source; use spiffe::bundle::BundleSource; use spiffe::spiffe_id::TrustDomain; use spiffe::svid::x509::X509Svid; use spiffe::svid::SvidSource;
async fn fetchx509materials() -> Result<(), Box
// Fetch the SVID
let svid = x509_source.get_svid()?.ok_or("No X509Svid found")?;
// Fetch the bundle for a specific trust domain
let trust_domain = spiffe::TrustDomain::new("example.org"); // Replace with the appropriate trust domain
let bundle = x509_source.get_bundle_for_trust_domain(&trust_domain)?.ok_or("No bundle found for trust domain")?;
Ok(())
} ```
Fetch JWT tokens, parse and validate them, fetch JWT bundles, or watch for updates on the JWT bundles.
```rust // parse a SPIFFE ID to ask a token for let spiffeid = SpiffeId::tryfrom("spiffe://example.org/my-service")?;
// fetch a jwt token for the provided SPIFFE-ID and with the target audience service1.com
let jwttoken = client.fetchjwttoken(&["audience1", "audience2"], Some(&spiffeid)).await?;
// fetch the jwt token and parses it as a JwtSvid
let jwtsvid = client.fetchjwtsvid(&["audience1", "audience2"], Some(&spiffeid)).await?;
// fetch a set of jwt bundles (public keys for validating jwt token) let jwtbundles = client.fetchjwt_bundles().await?;
// parse a SPIFFE trust domain let trustdomain = TrustDomain::tryfrom("example.org")?;
// get the JWT bundle associated to the trust domain let jwtbundle: &JwtBundle = jwtbundles.getbundle(&trustdomain)?;
// get the JWT authorities (public keys) in the bundle let jwtauthority: &JwtAuthority = jwtbundle.findjwtauthority("akeyid")?;
// parse a JwtSvid
validating the token signature with a JWT bundle source.
let validatedjwtsvid = JwtSvid::parseandvalidate(&jwttoken, &jwtbundles_set, &["service1.com"])?;
// watch for updates on the JWT bundles let mut jwtbundlestream = client.streamjwtbundles().await?; while let Some(jwtbundleupdate) = jwtbundlestream.next().await { match jwtbundleupdate { Ok(update) => { // handle the updated JWT bundle } Err(e) => { // handle the error } } } ```
For more detailed examples and additional features, refer to the documentation.
This library is licensed under the Apache License. See the LICENSE.md file for details.