Wallet and Key Attestations
Overview
Wallet Unit Attestations allow PID and EAA providers to assess the Wallet Instance and the security of the keys used for credential binding. The Wallet Instance Attestation (WIA) provides assurance about the Wallet Instance itself. The Key Attestation (KA) provides information about the keys and the WSCD or keystore in which they are held.
Terms and Definitions
- Wallet Unit Attestation (WUA): an umbrella term for Wallet Instance Attestations (WIAs) and Key Attestations (KAs).
- Wallet Instance Attestation (WIA): a JWT signed by the Wallet Provider that attests the integrity and authenticity of the Wallet Instance and enables PID Providers and EAA Providers to determine whether the Wallet Instance is trusted and non-revoked. It corresponds to the Client Attestation JWT of OAuth 2.0 Attestation-Based Client Authentication
- Client Attestation PoP JWT: a request-specific proof generated by the Wallet Instance
using the private key corresponding to the WIA's public key in
cnf.jwkclaim. It demonstrates possession of that key to the Authorization Server. Unlike the WIA, it is not signed by the Wallet Provider. - Key Attestation (KA): a JWT signed by the Wallet Provider that attests the security properties of cryptographic keys stored in a WSCD or keystore and enables PID and EAA Providers to determine whether those keys satisfy the requirements for credential binding.
Protocols, Attestation Format and Content
CIR 2024/2979 modified by CIR 2026/1731 mandates the use of Wallet Instance Attestation (WIAs) and Key Attestation (KAs) during the issuance of PID or device-bound EAA using the OID4VCI protocol. A Key Attestation is only used for device-bound credential issuance. It shall not be sent when issuing non-device-bound EAA. A Wallet Instance Attestation and a Key Attestation are each a JWT as specified in RFC 7519. The Wallet Provider Backend signs the WIA. In the German National EUDI Wallet, the Remote WSCA signs the KA.
The attestations are carried in different parts of the issuance flow.
The WIA authenticates the Wallet Instance towards the Authorization Server
in Pushed Authorization Requests (PAR) and Token Requests. The KA is conveyed
to the Credential Issuer in the proofs field of the Credential Request.
Wallet Instance Attestation Format and Content
The Wallet Instance Attestation follows the wallet attestation format
defined in Appendix E of OID4VCI. The Wallet Instance sends the Client
Attestation JWT together with a Client Attestation PoP JWT to the Authorization
Server in both the Pushed Authorization Request (PAR) and the Token Request.
If the request also carries a client_id parameter, the Authorization
Server verifies that it matches the WIA's sub and the PoP's iss.
In addition to the base claims defined in Appendix E of OID4VCI (including
the issuer, subject/client_id, validity information, and the WIA's public key
in cnf.jwk), CIR 2024/2979 modified by CIR 2026/1731 additionally requires
the following information:
wallet_name: the identifier of the wallet solution as registered on the list of Wallet Providers (Article 5 of CIR 2024/2980) — not a free-text display namewallet_version: the version of the wallet solution (a claim defined by this CIR 2026/1731, not part of OID4VCI itself)wallet_solution_certification_information: a JSON object with information on the conformity assessment body, certification number, and other certification detailsclient_status: an object with:statusreferencing the Token Status List entry for the Wallet Instance, andexpspecifying until when the Wallet Provider maintains that revocation status.
exp: The technical expiry of the WIA. This must not be interpreted as the end of the revocation-status maintenance period.
The WIA should also include wallet_link, a URI with further information about
the wallet solution.
Per Appendix E of OID4VCI, the sub claim is the client_id of the Wallet
Instance and, for privacy reasons, it is the same value across all Wallet
Instances of the same Wallet Provider — it does not identify an individual
Wallet Instance. Only cnf.jwk and the client_status status-list index
differentiate one Wallet Instance from another.
The German National EUDI Wallet documentation does not explicitly describe
wallet_name, wallet_version and wallet_solution_certification_information
in the publicly available WIA chapter. However, they are supported and
filled actually with dummy data.
The private key corresponding to the public key in the WIA's cnf.jwk
is held in the Wallet's mobile HKS, not in the RWSCD.
Key Attestation Format and Content
A Key Attestation follows Appendix D of OID4VCI. When required, the Wallet Instance
includes it in the Credential Request proofs field, using the jwt or
attestation proof type. With the jwt proof type, the Wallet Instance signs the
proof with the private key corresponding to the first public key in the KA's
attested_keys array. With the attestation proof type, the KA includes a valid
issuer-provided nonce.
In addition to the base claims specified in Appendix D of OID4VCI, CIR 2024/2979, as amended by CIR 2026/1731, requires Key Attestations to include the following attributes:
key_storageanduser_authentication: Arrays describing the attack resistance of the key storage and user-authentication mechanism. Where the KA refers to a WSCD, both must containiso_18045_high.certification: a URL (a JSON string, per Appendix D.1 of OID4VCI) linking to information on the certification achieved by the WSCD or keystore (e.g. scheme such as Common Criteria, the evaluated Protection Profile, and the evaluation level) — sufficient for a PID/EAA Provider to determine whether the key storage is a WSCD. The certification details themselves are not embedded in the JWT, unlikewallet_solution_certification_informationin the Wallet Instance Attestation, which is a JSON objectkey_storage_status: an object analogue toclient_statusin the WIA, representing the revocation status of the WSCD/keystore withstatusreferencing the Token Status List entry. The value represents either the revocation status of the WSCD or keystore type used to store the attested keys.expspecifying until when the Wallet Provider maintains that revocation status.
attested_keys: at least one attested public key — this is mandatory, not optional, since attesting keys is the purpose of a Key Attestationexp: the technical expiry of the attestation itself (distinct fromkey_storage_status.exp)
The German National EUDI Wallet implementation calls its Key Attestation a Wallet Trust Evidence (WTE). This chapter uses KA to align the implementation terminology with OID4VCI and CIR 2024/2979, as amended by CIR 2026/1731.
The implementation currently supports KAs for keys held in the Remote Wallet Secure Cryptographic Device (RWSCD); local keystore keys are not supported.
KA support is currently limited to PID issuance, and the PID Provider only
needs to support the attestation proof type for this wallet.
The Remote WSCA signs the KA. the Wallet Provider Backend (WPB) does not issue or sign the it.
The actual implementation of KA in the German National EUDI Wallet does not support the use of status lists.
The following claims mandated by CIR 2024/2979 modified by CIR 2026/1731, are not supported by the German National EUDI Wallet:
key_storage_statuscertification
Data Minimization
Attestations should contain the information needed for the relevant trust and security checks without exposing unrelated Wallet Instance capabilities or internal user-account identifiers. In particular, the Wallet Provider should avoid adding identifiers that would enable unnecessary correlation across issuers.
Further information about the Wallet Solution and its certification status should be conveyed via the trust list rather than embedded in the attestation.
Lifecycle
A Wallet Instance Attestation (WIA) is issued by the Wallet Provider Backend and associated with a Wallet Instance. A Key Attestation (KA) is issued by the party responsible for the key storage and associated with its key(s).
Their reuse is governed by different rules. In particular, reuse of the signed
WIA must be distinguished from reuse of the status-list index referenced by
its client_status.status claim.
Key Attestation Lifecycle
A Key Attestation (KA) is used for a single credential issuance or re-issuance process and shall not be reused for another issuance.
KAs are only relevant for device-bound credentials and shall not be provided when issuing non-device-bound EAAs. The technical validity of a KA is independent of the period during which its revocation status is maintained.
In the initial PID issuance flow, the KA is also sent to the Token endpoint
inside the DPoP proof's key_attestation claim, where it attests the refresh-token key.
The KA is created by the Remote WSCA, using the credential issuer's c_nonce,
and is valid for 10 minutes. It is not fetched in advance or stored by the Wallet.
Wallet Instance Attestation Lifecycle and Reuse
A Wallet Instance Attestation (WIA) shall not be used with more than one Authorization Server. During a single issuance process, the Wallet Instance uses the same WIA in both the Pushed Authorization Request (PAR) and the Token Request.
CIR 2024/2979 modified by CIR 2026/1731 allows the same WIA to be reused across multiple issuance processes with the same Authorization Server, provided the Wallet Provider supports the per-issuer reuse option and the WIA is still valid. Otherwise, a new WIA is required for each issuance process.
Each request must be accompanied by a fresh Client Attestation Proof of Possession (PoP) JWT,
signed using the private key corresponding to the public key in the WIA's cnf.jwk claim.
Reusing a WIA therefore does not imply reusing its PoP JWT.
Before issuing a WIA, the Wallet Provider must verify the integrity of the Wallet Instance.
The WIA is short-lived: its exp value must be less than 24 hours after the integrity verification.
Reuse of the WIA status-list index
The client_status.status claim references a status-list entry used to determine whether the Wallet
Instance has been revoked. This entry has its own lifecycle, independent of the signed WIA.
Under CIR 2024/2979 modified by CIR 2026/1731, the Wallet Provider may support per-issuer reuse
of the status-list index. In this case:
- The Wallet Instance keeps track of the status-list index assigned to each Authorization Server and requests the same index when obtaining a new WIA for that server.
- Before reusing an index, the Wallet Provider verifies that it was previously assigned to the requesting Wallet Instance.
- The same index must not be used with different Authorization Servers.
- The Wallet Provider must document this option in its privacy policy, as it allows the provider to determine how many Authorization Servers a Wallet Instance interacts with and how frequently.
If per-issuer reuse is not supported, each newly issued WIA receives a fresh, unlinkable status-list index.
The per-issuer reuse option is currently not supported by the German National EUDI Wallet.
Technical Expiry and Status-maintenance Period
WIAs and KAs contain two expiry-related values that serve different purposes:
expdefines the technical expiry of the attestation itself. According to CIR 2024/2979, as amended by CIR 2026/1731, a WIA must expire less than 24 hours after the Wallet Provider verified the integrity of the Wallet Instance. For KAs, the technical validity period is determined by the Wallet Provider.client_status.exp(WIA) andkey_storage_status.exp(KA) define the period until which the Wallet Provider commits to maintain the revocation status at the referenced status-list index.
The technical expiry of an attestation does not affect the Wallet Provider's obligation to maintain its revocation status. For example, a WIA may expire within 24 hours, while its revocation status must remain available for a considerably longer period.
The Wallet Provider must ensure that WIAs and KAs can be presented with a remaining status-maintenance period of at least 31 days at the time they are presented to the Authorization Server or Credential Issuer.
A Credential Issuer may specify a preferred minimum remaining status-maintenance period through its metadata:
preferred_client_status_periodspecifies the preferred remaining status-maintenance period for a WIA.preferred_key_storage_status_period, defined withinkey_attestations_required, specifies the corresponding period for a KA.
Where these parameters are provided, the Wallet Instance selects an attestation whose remaining status-maintenance period meets the issuer's preference as closely as possible without falling below it. If no suitable attestation is available, the Wallet Instance requests a new one from the Wallet Provider.
Revocation
CIR 2024/2979 modified by CIR 2026/1731 mandates IETF Token Status Lists as the revocation mechanism for both Wallet Instance Attestations and Key Attestations; see the Status Management chapter for the underlying mechanism.
For Wallet Instance Attestations, revoking a Wallet Instance means
revoking the index value(s) in client_status.status across all Wallet
Instance Attestations associated with it.
Cryptographic Formats
Long-Term keys:
- Wallet Provider has long-term key pair
- Wallet Instance generates device key
Artifacts — the Wallet Provider Backend issues two separate, independently signed JWTs:
- Wallet Instance Attestation:
- Key Attestation:
The Client Attestation PoP JWT accompanying a Wallet Instance Attestation is
not produced by the Wallet Provider Backend. The Wallet Instance creates it
per request and signs it with , the private key belonging to
the published in the attestation's cnf.jwk claim:
- Client Attestation PoP:
Sequence Diagrams
The following non-normative diagram illustrates how a Wallet Instance obtains a Wallet Instance Attestation (WIA) from its Wallet Provider Backend.
Example Issuance of Wallet Instance Attestation
Samples
The samples provided are non-normative and are intended solely to illustrate what the attestations may look like in practice.
Wallet Instance Attestation
Decoded WIA JWT Header
{
"typ": "oauth-client-attestation+jwt",
"alg": "ES256",
"x5c": [
"MIIC8DCCAdigAwIBAgIU...WALLET_PROVIDER_CERT...==",
"MIID...INTERMEDIATE_CERT...=="
]
}
Decoded WIA JWT Payload
{
"iss": "german-national-wallet:wpb:sandbox",
"sub": "https://wallet.example.eu/client",
"wallet_name": "EUDIW-EU-EXAMPLE-001",
"wallet_version": "0.0.1",
"wallet_link": "https://wallet.example.eu/info",
"wallet_solution_certification_information": {
"conformity_assessment_body": {
"name": "Example EU CAB",
"identifier": "CAB-DE-12345"
},
"certification_number": "EU-WALLET-CERT-2026-0042",
"certification_scheme": "EU Digital Identity Wallet Certification",
"certification_date": "2026-06-15",
"certification_status": "valid"
},
"client_status": {
"status": {
"status_list": {
"idx": 98812,
"uri": "https://wallet.example.eu/status-lists/1db75c9b-7080-4e74-abd6-f8c0a4da4559"
}
},
"exp": 1793404800
},
"nbf": 1788190200,
"exp": 1788276600,
"cnf": {
"jwk": {
"kty": "EC",
"crv": "P-256",
"x": "f83OJ3D2xF4m2M7v8...",
"y": "x_FEzRu9z0H8V4..."
}
}
}
wallet_nameholds the wallet solution's identifier as registered on the list of wallet providers, not a free-text display name — hence a code such asEUDIW-EU-EXAMPLE-001rather than a human-readable string.subis the Wallet Instance'sclient_id, which — for privacy reasons — is the same across all Wallet Instances of this Wallet Provider; it does not by itself distinguish one Wallet Instance from another.
Client Attestation PoP
The Wallet Instance generates this second JWT itself for each request and sends it alongside the WIA. It is not signed by the Wallet Provider.
Decoded PoP JWT Header
{
"typ": "oauth-client-attestation-pop+jwt",
"alg": "ES256"
}
Decoded PoP JWT Payload
{
"iss": "https://wallet.example.eu/client",
"aud": "https://pid-provider.example.eu",
"jti": "d25d00ab-552b-46fc-ae19-98f440f25064",
"iat": 1788190260,
"challenge":"5c1a9e10-29ff-4c2b-ae73-57c0957c09c4"
}
The header carries no
x5c/kid: the verification key is the public key in the WIA'scnf.jwkclaim, so the PoP is only verifiable in combination with its WIA.issrepeats theclient_idand shall match the WIA'ssub.audis the issuer identifier of the Authorization Server the request goes to.jtiis unique per PoP and lets the Authorization Server detect replay. A PoP may also carry achallengeclaim where the Authorization Server supplies one.
Key Attestation
Decoded KA JWT Header
{
"typ": "key-attestation+jwt",
"alg": "ES256",
"x5c": [
"MIIC8DCCAdigAwIBAgIU...REMOTE_WSCA_CERT...==",
"MIID...INTERMEDIATE_CERT...=="
]
}
Decoded KA JWT Payload
{
"iss": "https://wallet.example.eu/remote-wsca",
"iat": 1788190200,
"exp": 1788276600,
"certification": "https://cert.example.eu/wscd/CC-2026-1234",
"key_storage": [
"iso_18045_high"
],
"user_authentication": [
"iso_18045_high"
],
"key_storage_status": {
"status": {
"status_list": {
"idx": 271828,
"uri": "https://wallet.example.eu/status/ka/17"
}
},
"exp": 1790874000
},
"attested_keys": [
{
"kty": "EC",
"crv": "P-256",
"alg": "ES256",
"x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
"y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
}
]
}
certificationis a plain URL (seeOID4VCI Appendix D.1); the resource it points to is expected to convey the certification scheme (e.g. Common Criteria), the evaluated Protection Profile, the evaluation level, and whether the key storage is a WSCD.
Legal and regulatory references
- EU: eIDAS Regulation, CIR 2024/2979 (Articles 5a and 6, Annex Ia and Annex Ib, as inserted/replaced by CIR 2026/1731), CIR 2024/2980 (Article 5 — list of wallet providers used as the trust anchor for Wallet Attestation signature validation)
Other references
- ARF Technical Specification of Wallet Unit Attestations
- OAuth 2.0 Attestation-Based Client Authentication (Section 5.1 Client Attestation JWT, Section 5.2 Client Attestation PoP JWT, Section 6.1 Client Attestation HTTP Headers — the basis for the Wallet Instance Attestation format adopted by Appendix E of OID4VCI)
- WIA in German EUDI National Wallet
- KA (called Wallet Trust Evidence) in German EUDI National Wallet