OID4VCI Key Attestation in JWT format (OpenID4VCI 1.0 draft 15/ID2,
"Key Attestation in JWT format" §D.1, #keyattestation-jwt).
A key attestation is a statement - issued by a Wallet's key storage component or its Wallet Provider - that a set of cryptographic public keys are held in a specific class of secure storage and (optionally) gated behind a specific class of user authentication. A Wallet MAY attach one to a Credential Request, either:
- in the
key_attestationJOSE header of ajwtproof (alongside a proof of possession of one of the attested keys), or - as the sole element of an
attestationproof type (no proof of possession of any attested key - one attestation can vouch for many).
verify/2 validates the attestation JWT and returns its attested_keys
plus any assurance claims (key_storage, user_authentication,
certification). Trust in the signer (the key storage component / Wallet
Provider) is host-supplied, exactly as Attesto.ClientAssertion and
Attesto.WalletAttestation take trusted keys from the caller. Conn-free
and fail-closed.
JWT shape (typ=key-attestation+jwt)
alg- REQUIRED header; MUST NOT benoneor a MAC algorithm.typ- REQUIRED header; MUST bekey-attestation+jwt.iat- REQUIRED.exp- OPTIONAL per the spec text, but "MUST be present if the attestation is used with thejwtproof type". Since this module cannot see the surrounding proof type, it defaults to requiringexp(fail-closed); passrequire_exp: falsefor a deployment that only ever uses theattestationproof type and intentionally issues attestations with no expiry.attested_keys- REQUIRED, a non-empty array of public JWKs.key_storage,user_authentication- OPTIONAL non-empty arrays of attack-potential-resistance strings (iso_18045_*or an ecosystem-defined value).certification- OPTIONAL, a URL.nonce- OPTIONAL; MUST echo the Issuer'sc_noncewhen one was provided. Checked against:noncewhen supplied.
As of this draft, the key attestation JWT carries no formal iss/aud
claim (unlike the Client/Wallet Attestation JWT) - the spec's own example
includes iss, but the normative claim list does not. verify/2 still
lets a caller pin :issuer for deployments that populate and rely on it
by convention; it is not checked unless supplied.
Summary
Functions
Returns true iff jwk (a public JWK map) is among attested_keys,
compared by RFC 7638 thumbprint rather than raw map equality so key
members in a different order, or an added alg/use/kid, do not cause
a false negative.
Verify a key attestation JWT.
Types
@type verify_error() ::
:invalid_attestation
| :invalid_typ
| :invalid_alg
| :unsupported_critical_header
| :invalid_signature
| :missing_iat
| :invalid_iat
| :missing_exp
| :expired
| :not_yet_valid
| :missing_attested_keys
| :invalid_attested_keys
| :invalid_issuer
| :invalid_nonce
@type verify_opts() :: [ trusted_jwks: map() | [map()], issuer: String.t(), nonce: String.t(), now: DateTime.t() | non_neg_integer(), require_exp: boolean(), accepted_algs: [Attesto.SigningAlg.alg()] ]
Functions
Returns true iff jwk (a public JWK map) is among attested_keys,
compared by RFC 7638 thumbprint rather than raw map equality so key
members in a different order, or an added alg/use/kid, do not cause
a false negative.
Used to cross-check a credential-request proof's holder key against a
key attestation's attested_keys (see Attesto.CredentialProof's
:key_attestation opt).
@spec verify(String.t(), verify_opts()) :: {:ok, verified()} | {:error, verify_error()}
Verify a key attestation JWT.
Required opts
:trusted_jwks- an RFC 7517 JWK Set, a single public JWK map, or a list of public JWK maps the attestation's signature is checked against. Establishing which key-storage components / Wallet Providers to trust is the host's responsibility.
Optional opts
:issuer- when set, the attestation'siss(if present) MUST equal it. Not required to be present unless the caller relies on it - see the module doc.:nonce- the expectedc_nonce; when set, the attestation'snonceclaim MUST match it exactly.:now- clock reference (DateTime or unix seconds).:require_exp- whetherexpmust be present. Defaults totrue.:accepted_algs- JWS algorithms accepted. Defaults toAttesto.SigningAlg.fapi_algs/0.
Returns {:ok, %{attested_keys:, key_storage:, user_authentication:, certification:, claims:}}, where attested_keys is the list of public
JWK maps this attestation vouches for.