Expand description
DID resolution and production: the DidResolver and DidProducer traits a DID method
implements, the Resolver registry that routes a DID to the resolver of its method, an
optional TTL DocumentCache, and DID URL dereferencing. Beside DIDs, finding the key a
token was signed with: KeyReference and KeyResolver.
The module ships no DID method. Each method is a type implementing DidResolver and/or
DidProducer, registered with ResolverBuilder::with; adding one needs no change here.
§Resolution
Resolver::resolve implements the DID Resolution algorithm around the method’s resolver:
it reports ResolutionErrorKind::MethodNotSupported for a method nobody registered, turns a
result whose metadata reports an error into Err, refuses a document whose id is not the
DID being resolved (nor its canonicalId), and serves repeated resolutions from the cache
when one is configured. Resolver::resolve_document is the shortcut to the document.
§Dereferencing
Resolver::dereference resolves the DID of a DID URL and then selects the resource the URL
names: the document itself, or the verification method or service whose id is the URL
(Dereferenced). The versionId and versionTime DID parameters are passed to the
method’s resolver as resolution options; a path, any other query parameter and the
service/relativeRef parameters are method-specific and reported as
DereferenceError::MethodSpecific. Resolver::resolve_public_key goes one step further
and returns the Jwk of a verification method, optionally checked to be
usable for a verification relationship, decoding publicKeyMultibase material as a Multikey,
which is what a JWS verifier needs.
§Key references
A JWT names the key that signed it in one of several ways (ADR 0006), and
KeyReference::from_jws reads which, in this order: a kid that is a DID URL
(did:…#fragment, without a path or DID parameters); a kid that is a #fragment, joined
with a DID iss; another kid with an HTTPS iss, naming a key of the issuer’s key set; the
key itself in a jwk header; an x5c certificate chain; a jku key set URL. A
KeyResolver turns the reference into a key for a KeyRole, the issuer’s
(assertionMethod in a DID document) or the subject’s (authentication):
| Reference | Resolved by |
|---|---|
KeyReference::DidUrl | Resolver, dereferencing the verification method |
KeyReference::Jwk | JwkResolver, the key itself |
KeyReference::Jwks | JwksResolver (feature jwks), the JWT VC issuer metadata of the issuer |
KeyReference::X509Chain, KeyReference::Jku | nothing in the crate yet; an application’s own KeyResolver |
CompositeKeyResolver tries several in order. Resolving says nothing about trust: after
the signature verifies, KeyReference::binds_to checks that the key belongs to the party
the token claims, which the validators of the upper layer do.
§Examples
A method is a type implementing DidResolver; here one that serves documents from memory.
use std::collections::HashMap;
use identity_kit::did::{
Did, DidDocument, DidUrl, ResolutionError, ResolutionErrorKind, ResolutionOptions,
ResolutionResult,
};
use identity_kit::resolver::{Dereferenced, DidResolver, Resolver};
struct Static(HashMap<Did, DidDocument>);
#[async_trait::async_trait]
impl DidResolver for Static {
fn method(&self) -> &'static str {
"example"
}
async fn resolve(
&self,
did: &Did,
_: &ResolutionOptions,
) -> Result<ResolutionResult, ResolutionError> {
self.0.get(did).cloned().map(ResolutionResult::new).ok_or_else(|| {
ResolutionError::new(ResolutionErrorKind::NotFound)
.with_detail(format!("no document is stored for `{did}`"))
})
}
}
let document: DidDocument = serde_json::from_str(r##"{
"id": "did:example:123",
"verificationMethod": [{
"id": "did:example:123#key-1",
"type": "JsonWebKey2020",
"controller": "did:example:123",
"publicKeyJwk": {
"kty": "OKP", "crv": "Ed25519", "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
}
}],
"authentication": ["#key-1"]
}"##)?;
let did = document.id.clone();
let resolver = Resolver::builder()
.with(Static(HashMap::from([(did.clone(), document)])))
.cache(std::time::Duration::from_secs(60))
.build();
assert_eq!(resolver.resolve_document(&did).await?.id, did);
let key = DidUrl::parse("did:example:123#key-1")?;
let jwk = resolver.resolve_public_key(&key, None).await?;
assert_eq!(jwk.crv(), Some("Ed25519"));
assert!(matches!(resolver.dereference(&key).await?, Dereferenced::VerificationMethod(_)));
let unknown = Did::parse("did:other:123")?;
let error = resolver.resolve(&unknown).await.unwrap_err();
assert_eq!(error, ResolutionErrorKind::MethodNotSupported);
assert_eq!(error.detail(), Some("no resolver is registered for `did:other`"));Structs§
- Composite
KeyResolver - Resolvers tried in order: the first answer other than
Unsupportedis the answer, an error included. - Document
Cache - A bounded cache of resolution results, keyed by DID, where every entry expires after the same time to live.
- JwkResolver
- Resolves a
KeyReference::Jwkto its public part; every other reference isUnsupported. - Jwks
Resolver jwks - Resolves a
KeyReference::Jwksthrough the JWT VC issuer metadata of the issuer (SD-JWT VC §3.5); every other reference isUnsupported. - Method
Capabilities - What a DID method can do, declared by its
DidProducerso an application can pick a method without knowing it. - Resolver
- Routes each DID to the
DidResolverregistered for its method, with an optionalDocumentCachein front. - Resolver
Builder - Builds a
Resolver.
Enums§
- Dereference
Error - Why a DID URL could not be dereferenced.
- Dereferenced
- The resource a DID URL names, as
Resolver::dereferencereturns it. - Hosting
- Where the documents of a DID method live, which decides what creating one involves.
- Jwks
Error jwks - Why a
JwksResolverfound no key. - KeyReference
- Where a token says the key that signed it is (ADR 0006).
- KeyReference
Error - Why a token names no key this crate can look for.
- KeyResolution
Error - Why a
KeyResolverfound no key. - KeyRole
- The role a key plays in a token, which decides what a DID document must say about it.
- Produce
Error - Why a
DidProducercould not produce a document.
Traits§
- DidProducer
- Produces the DID document of one method from public keys.
- DidResolver
- Resolves the DIDs of one method (DID Resolution “DID Resolution Algorithm”).
- KeyResolver
- Finds the public key a
KeyReferencenames.