Expand description
The signing party: which identifiers it controls and the keys that sign for them.
Every protocol that signs on behalf of a party needs the same three things: an identifier for
iss or sub, a kid for the header and a Signer. Which identifier depends on what the
other side accepts, a DID of some method or the RFC 7638 thumbprint of a bare key, and on the
algorithm both sides agreed on. The protocol negotiates that pair (SIOPv2 matches
subject_syntax_types_supported against what the wallet offers, OID4VCI the
proof_signing_alg_values_supported), using Identity::capabilities for the identity’s
side; the identity then answers for the chosen pair:
Identity::identifier: theiss/subvalue, aDidor a thumbprint;Identity::public_jwk: the public key, forcnf.jwk,sub_jwkor ajwkheader;Identity::signer: aSignerwhosekidis the absolute DID URL of the verification method for a DID, andNonefor a thumbprint, where the caller puts the public key in the header instead.
All three name the same key for the same pair. A party may hold a key per algorithm for one
kind, so the identifier takes the algorithm too: a did:key, a did:jwk or a thumbprint is
derived from the key and differs between them.
KeyStoreIdentity is the implementation the crate ships, over any KeyStore and the
DidProducers registered with it. There is no hook for an external signer: a remote or
hardware signer is a KeyStore (ADR 0006).
§Examples
use std::sync::Arc;
use identity_kit::did::{DidMethod, VerificationRelationship};
use identity_kit::identity::{Identity, IdentityKind, KeyStoreIdentity};
use identity_kit::jose::{CompactJws, DefaultVerifier, JwsAlgorithm, JwsHeader, KeyType, encode_compact};
use identity_kit::keys::{InMemoryKeyStore, KeySpec, KeyStore};
use identity_kit::methods::DidKey;
use identity_kit::resolver::Resolver;
let store = Arc::new(InMemoryKeyStore::new());
let key = store.generate(KeySpec::new(KeyType::Ed25519, JwsAlgorithm::EdDSA)).await?;
let identity = KeyStoreIdentity::new(store).with_producer(DidKey::default());
// The protocol settled on did:key and EdDSA.
let kind = IdentityKind::Did(DidMethod::new("key")?);
let did = identity.bind(kind.clone(), JwsAlgorithm::EdDSA, key).await?;
assert!(did.to_string().starts_with("did:key:z6Mk"));
let signer = identity.signer(&kind, JwsAlgorithm::EdDSA).await?;
let kid = signer.kid().expect("a DID signer names its verification method");
let header = JwsHeader::new(JwsAlgorithm::EdDSA).with_kid(kid);
let token = encode_compact(&header, br#"{"iss":"me"}"#, &*signer).await?;
// A verifier finds the key through the DID in `kid`.
let resolver = Resolver::builder().with(DidKey::default()).build();
let url = kid.parse()?;
let key = resolver
.resolve_public_key(&url, Some(VerificationRelationship::AssertionMethod))
.await?;
CompactJws::decode(&token)?.verify(&DefaultVerifier, &key)?;Structs§
- KeyStore
Identity - An
Identityover the keys of aKeyStore, vendor-agnostic: a KMS or HSM backend that implementsKeyStoreworks without glue.
Enums§
- Identifier
- The identifier of an
Identityfor one kind and algorithm;Displaygives theissorsubvalue. - Identity
Error - Why an
Identitycannot answer for a kind and algorithm. - Identity
Kind - The kind of identifier the other side accepts.
Traits§
- Identity
- A party that signs: the identifiers it controls and the keys behind them.