Skip to main content

JwksResolver

Struct JwksResolver 

Source
pub struct JwksResolver<C> { /* private fields */ }
Available on crate feature jwks only.
Expand description

Resolves a KeyReference::Jwks through the JWT VC issuer metadata of the issuer (SD-JWT VC §3.5); every other reference is Unsupported.

For an issuer https://host[:port][/path] it fetches https://host[:port]/.well-known/jwt-vc-issuer[/path] (a trailing / of the path dropped), requires the metadata’s issuer to be the issuer, takes its jwks, or fetches its jwks_uri, and returns the one key whose kid is the reference’s. Issuer and jwks_uri must be https, and the issuer has no query, fragment or credentials. The key set of an issuer is cached for a time to live (DEFAULT_TTL unless set with with_ttl), so a rotated key is found once its entry expires.

The issuer comes from the token, so the client fetches whatever a token names: client must enforce the protections ReqwestClient (feature reqwest) does (HTTPS only, no redirects, no non-public addresses after name resolution, a body limit and a timeout), or resolution becomes a request forgery primitive. Resolving says nothing about whether the issuer is trusted; that stays the application’s policy.

§Examples

use identity_kit::methods::web::{HttpClient, HttpError, HttpResponse};
use identity_kit::resolver::{JwksResolver, KeyReference, KeyResolver as _, KeyRole};
use url::Url;

/// Serves the metadata of `https://example.com/issuer`.
struct Served;

#[async_trait::async_trait]
impl HttpClient for Served {
    async fn get(&self, url: &Url) -> Result<HttpResponse, HttpError> {
        assert_eq!(url.as_str(), "https://example.com/.well-known/jwt-vc-issuer/issuer");
        Ok(HttpResponse::new(200, r#"{
          "issuer": "https://example.com/issuer",
          "jwks": { "keys": [{
            "kid": "key-1", "kty": "OKP", "crv": "Ed25519",
            "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
          }]}
        }"#))
    }
}

let resolver = JwksResolver::new(Served);
let reference = KeyReference::Jwks {
    issuer: Url::parse("https://example.com/issuer")?,
    kid: "key-1".to_owned(),
};
let key = resolver.resolve_key(&reference, KeyRole::Issuer).await?;
assert_eq!(key.crv(), Some("Ed25519"));

Implementations§

Source§

impl<C> JwksResolver<C>

Source

pub const DEFAULT_TTL: Duration

How long new keeps an issuer’s key set: five minutes.

Source

pub const DEFAULT_CAPACITY: usize = 256

How many issuers new keeps key sets of.

Source

pub fn new(client: C) -> Self

A resolver fetching with client, keeping key sets for DEFAULT_TTL.

Source

pub fn with_ttl(self, ttl: Duration) -> Self

This resolver keeping key sets for ttl; zero keeps none.

Source

pub fn with_capacity(self, capacity: usize) -> Self

This resolver keeping the key sets of at most capacity issuers (at least one).

Source

pub fn ttl(&self) -> Duration

How long a key set is kept.

Source

pub fn client(&self) -> &C

The HTTP client.

Trait Implementations§

Source§

impl<C> Debug for JwksResolver<C>
where C: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<C: HttpClient> KeyResolver for JwksResolver<C>

Source§

fn resolve_key<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 KeyReference, __arg2: KeyRole, ) -> Pin<Box<dyn Future<Output = Result<Jwk, KeyResolutionError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

The public key key names, usable in role. Read more

Auto Trait Implementations§

§

impl<C> !Freeze for JwksResolver<C>

§

impl<C> RefUnwindSafe for JwksResolver<C>
where C: RefUnwindSafe,

§

impl<C> Send for JwksResolver<C>
where C: Send,

§

impl<C> Sync for JwksResolver<C>
where C: Sync,

§

impl<C> Unpin for JwksResolver<C>
where C: Unpin,

§

impl<C> UnsafeUnpin for JwksResolver<C>
where C: UnsafeUnpin,

§

impl<C> UnwindSafe for JwksResolver<C>
where C: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more