OID4VCI credential-request key proof of type jwt
(draft-ietf-oauth-openid4vci §8.2.1.1).
When a wallet asks the credential endpoint for a credential, it proves
possession of the key the issued credential will be bound to (its cnf) with
a proof object {"proof_type": "jwt", "jwt": <JWS>}. The proof JWS is typed
openid4vci-proof+jwt; its header carries the holder's public key (as jwk);
its payload carries:
aud- the Credential Issuer Identifier (this issuer). REQUIRED.iat- issuance time. REQUIRED, and must be fresh.nonce- thec_noncethe issuer previously handed out, when it did.iss- the client_id, for the authorized code flow.
verify_jwt/2 validates the proof and returns the holder public JWK (and its
RFC 7638 thumbprint) so the caller binds the credential to it via cnf.
This is the issuance-time sibling of Attesto.DPoP / Attesto.SdJwt's Key
Binding JWT: same "prove you hold this key" shape, different claim set.
Conn-free and fail-closed.
Optional key attestation cross-check
A Wallet MAY additionally carry a key attestation (Attesto.KeyAttestation)
in the proof's key_attestation JOSE header, vouching that the proof's
jwk is held in attested secure storage (OID4VCI Appendix D). This is
off by default - passing neither :key_attestation_trusted_jwks nor
:require_key_attestation reproduces the exact behavior of every prior
release. Supplying :key_attestation_trusted_jwks opts a caller into
verifying a present key_attestation header and rejecting a proof whose
key is not among its attested_keys; :require_key_attestation additionally
rejects a proof that carries no key_attestation header at all.
Summary
Functions
Verify a jwt credential-request key proof.
Types
@type verified() :: %{ jwk: map(), jkt: String.t(), key_attestation: Attesto.KeyAttestation.verified() | nil }
@type verify_error() ::
:invalid_proof
| :invalid_typ
| :invalid_alg
| :missing_jwk
| :invalid_jwk
| :invalid_signature
| :invalid_audience
| :invalid_nonce
| :invalid_iat
| :invalid_issuer
| :missing_key_attestation
| :invalid_key_attestation
| :key_not_attested
Functions
@spec verify_jwt( String.t(), keyword() ) :: {:ok, verified()} | {:error, verify_error()}
Verify a jwt credential-request key proof.
Required opts:
:issuer- the Credential Issuer Identifier the proof'saudmust equal.
Optional opts:
:nonce- the expectedc_nonce. When set, the proof MUST carry a matchingnonce; when omitted, nononceis required (issuers that do not usec_nonce).:client_id- when set, the proof'sissMUST equal it.:now- clock reference (DateTime or unix seconds).:max_age_seconds- how far in the pastiatmay be. Default 300.:accepted_algs- JWS algorithms accepted. Defaults toAttesto.SigningAlg.fapi_algs/0.:key_attestation_trusted_jwks- opts into verifying akey_attestationJOSE header (see "Optional key attestation cross-check" above) against these trusted keys and rejecting a proof whose key is not among the attestation'sattested_keys. Omitted (the default), no such header is looked at.:require_key_attestation- when true, a proof with nokey_attestationheader is rejected. Only meaningful alongside:key_attestation_trusted_jwks; defaults tofalse.
Returns {:ok, %{jwk: holder_public_jwk, jkt: thumbprint, key_attestation: verified_attestation_or_nil}}. key_attestation is nil unless
:key_attestation_trusted_jwks was supplied and a key_attestation header
was present and verified.