Wallet Unit Attestation (WUA): How the EUDI Wallet proves it is genuine and its keys are protected
This article explains the Wallet Unit Attestation (WUA), the mechanism by which an EUDI Wallet proves to an issuer that it is a genuine, certified wallet and that the keys about to hold a credential are protected to the required level of assurance. It is grounded in the European Digital Identity Wallet Architecture and Reference Framework (ARF) 2.9.0 [1], the ARF discussion on re-issuance and revocation of Wallet Unit Attestations [2], the EUDI Technical Specification 3 (TS3) for Wallet Unit Attestation [3], and the OpenID for Verifiable Credential Issuance (OpenID4VC) specification [4]. It is a companion to our credential issuance lifecycle (OpenID4VCI) article, where the WUA appears as one of the issuer's validation checks.
To make the concepts tangible, every section links to the live, hands-on EUDI Wallet WUA Playground, where you can generate and inspect the actual payloads.
Target audience: Developers, solution architects, and product managers building or integrating EUDI Wallet and European Business Wallet issuance flows.
1.0 An ecosystem with no single owner
Europe's digital identity is built, on purpose, as an open and shared ecosystem. You choose your wallet from any certified provider. An issuer places a credential into whatever wallet you happen to use. A verifier later accepts it, anywhere across the member states. No single organisation owns the chain from end to end.

Figure 01: The EU Digital Identity Wallet ecosystem.
That openness is both the value and the challenge. The issuer almost never built the wallet. It is being asked to place a credential into software made by a different organisation, running on a device it does not control, possibly in another country.
In a closed system this barely arises: if the same company makes the app and runs the service, it trusts its own software and the question never comes up. EUDI is the opposite by design, so trust has to cross organisational and national borders. What is needed is a portable, standard way for any wallet to prove itself to any issuer, with no prior relationship between them.
When a Person Identification Data (PID) Provider or a Qualified Electronic Attestation of Attributes (QEAA) issuer is about to release a high-value credential, it faces a simple but critical question: is the thing asking for this credential a genuine, certified wallet, and will the credential be bound to keys that live in secure hardware? A username and password cannot answer that. Neither can a TLS connection on its own. The answer is the Wallet Unit Attestation (WUA).
The WUA is a signed statement, ultimately rooted in the Wallet Provider, that vouches for two things at once: the authenticity of the wallet instance, and the protection level of the cryptographic keys that will hold the credential. The ARF defines it as the wallet's trust anchor towards issuers and, where required, relying parties [1]. Without it, an issuer cannot distinguish a certified Wallet Unit from a convincing but rogue application.
This article unpacks the WUA into its two building blocks, shows how each is carried during OpenID4VCI issuance, explains how the EUDI TS3 profile tightens the generic OpenID4VCI rules, and walks through how an issuer verifies a WUA and how it behaves over its lifecycle.
This article focuses on the WUA at credential issuance, where it is defined and most visibly used. Wallet authentication towards a relying party at presentation time relies on a separate mechanism and is out of scope here.
2.0 What problem does a WUA solve?
Issuing a credential is an act of trust extended by the issuer to the wallet. Three concerns have to be settled before that trust is warranted:
- Is the wallet genuine? The issuer needs assurance that the requesting software is an instance of a Wallet Solution that has been certified and is operated by a known Wallet Provider, not a clone or a tampered build.
- Are the keys safe? A credential is only as trustworthy as the protection of the private key it is bound to. The issuer needs assurance that the binding keys were generated in, and cannot leave, a suitably certified Wallet Secure Cryptographic Device (WSCD) or key storage component, at the level of assurance the use case demands (for PID, the high level).
- Can trust be withdrawn? If a wallet instance or a key store is later found to be compromised, there has to be a way to revoke the attestations so that issuers stop trusting it. This is the subject of ARF discussion Topic C [2].
The WUA answers all three. It lets an issuer make a risk decision on solid, cryptographically verifiable grounds rather than on assumptions. Conceptually, you can explore the "why" behind these requirements on the playground's Get started page.
3.0 The two building blocks of a WUA
A WUA is not a single token. It is composed of two attestations, both originating from the Wallet Provider but answering different questions.

Figure 02: The WUA is the combination of a Wallet Instance Attestation and a Key Attestation, both rooted in the Wallet Provider.
3.1 Wallet Instance Attestation (WIA)
The Wallet Instance Attestation answers "is this wallet instance genuine and healthy right now?". It is issued and signed by the Wallet Provider to a specific wallet instance after the instance has passed the provider's integrity checks. The wallet then proves it controls that instance with a separate proof of possession (the client attestation PoP), signed by the instance's own key [5]. During issuance it is used as client authentication at the OAuth 2.0 token endpoint, following the OAuth 2.0 Attestation-Based Client Authentication mechanism (media type oauth-client-attestation+jwt) [5]. OpenID4VCI v1.0 normatively references draft 07 of that mechanism [4][5].
Because the property it asserts ("this app is genuine and healthy") can change quickly, the WIA is deliberately short-lived: TS3 requires its time-to-live to be under 24 hours (§2.2.1.1) [3], so the wallet obtains a fresh WIA frequently. You can inspect a decoded WIA on the playground's Wallet Instance Attestation page.
3.2 Key Attestation (KA)
The Key Attestation answers "are the keys that will hold this credential in certified secure hardware?". It is a JWT, signed by the Wallet Provider, that lists one or more public keys in an attested_keys array and asserts that they were generated in, and are bound to, the same WSCD or key storage component, at a stated attack-potential-resistance level. In generic OpenID4VCI this is the key-attestation+jwt structure defined in Appendix D [4].
Crucially, the KA is the part that scales: a single KA can attest many keys at once, which is what makes batch issuance possible (Section 4.2). You can decode a KA, and toggle the TS3 profile, on the playground's Key Attestation page.
4.0 How a WUA is used during credential issuance
The two building blocks enter the OpenID4VCI flow at two different points.
Figure 03: Issuance in two stages. Stage A authenticates the wallet with the WIA at the Authorization Server; Stage B binds one credential per attested key using the KA carried in the Credential Request.
4.1 Proof of possession and the jwt proof
In OpenID4VCI, the KA is carried inside the Credential Request. The recommended transport is the jwt proof type: the wallet creates a proof of possession (PoP) for one of the attested keys and places the KA in that proof's key_attestation JOSE header [4]. The proof JWT is signed by a key identified in its header (via kid, jwk, or x5c), and the issuer validates that signature. This gives the issuer a live demonstration that the wallet actually controls the key material the KA describes.
There is also a standalone attestation proof type that conveys a KA without any proof of possession. It exists to avoid unnecessary user interaction, but it is the weaker option because it proves no live control of a key. For high-assurance use cases the jwt proof with a PoP is preferred. Compare both on the playground's Proof of possession page.
4.2 Batch and multi-key issuance
This is the part most often misunderstood, so it is worth stating precisely.
A single jwt proof carrying a KA with several attested_keys is enough to obtain several credentials in one step. OpenID4VCI Appendix F.1 says the issuer "SHOULD issue a Credential for each cryptographic public key specified in the attested_keys claim" [4], and Section 14.6 confirms the issuer "determines the number of the Credentials issued ... regardless of number of proofs/keys" [4]. In other words, the batch is driven by the attested_keys array, not by sending one proof per key.
Two numbers govern the outcome:
- N, the number of keys the KA attests.
batch_size, the cap the issuer applies. This comes from the issuer's credential metadata, specifically thecredential_reuse_policy.options.batch_sizeparameter defined in ETSI TS 119 472-3 [6].
The issuer binds min(N, batch_size) keys, issuing one copy of the credential per bound key so the wallet can present a fresh key per transaction for better unlinkability. Because the KA is single-use, any attested keys beyond the cap are wasted. Drag N and batch_size and watch the counters move on the playground's Batch issuance page.
5.0 OpenID4VCI v1.0 and the TS3 profile
TS3 v1.5 is the EUDI profile of how OpenID4VCI carries a Key Attestation and a proof of possession [3]. The two agree on the big picture (the proof carries the KA in its key_attestation header, and a single proof drives the batch), but TS3 tightens several details for the EUDI trust model. The differences that matter in practice:
| Aspect | OpenID4VCI v1.0 [4] | TS3 v1.5 profile [3] |
|---|---|---|
KA media type (typ) | key-attestation+jwt (hyphenated) | keyattestation+jwt (no hyphen). A known divergence to watch for interoperability. |
| Which key signs the proof | Any attested key, identified by the proof header (kid / jwk). No fixed position. | MUST be attested_keys index 0; the kid requirement was removed (§2.2.2.1). |
| Issuer identity on the KA | iss present (the Wallet Provider). | iss removed; identity is taken from the x5c signing certificate, which chains to the Wallet Provider Trusted List. |
| Key security level | key_storage / user_authentication on the ISO 18045 scale. | iso_18045_high required for a WSCD (for example, for PID). |
| Certification | certification is an OPTIONAL URL. | Mandatory; carries the scheme, evaluated requirements, and level. |
| Revocation and maintenance | Optional status reference. | Adds key_storage_status, with a status reference and an exp maintenance commitment. |
The single most common interoperability snag is the media-type hyphen: a verifier that matches typ exactly will reject the other form. See the full rule-by-rule view, side by side with the payloads, on the playground's OpenID4VCI vs TS3 page.
TS3 also explains why it asks for only one signature (by attested_keys[0]) rather than a per-key proof. Requiring a single signature improves the user experience, since some WSCDs require a user gesture to sign, and it does not weaken security, because the Wallet Provider's signature on the KA already binds every attested key to the same WSCD or keystore (§2.2.2.1) [3].
6.0 How an issuer verifies a WUA
When a Credential Request arrives, the issuer runs a sequence of checks before binding anything:
- Authenticate the client with the WIA at the token endpoint, and confirm it is current and not revoked.
- Verify the KA signature, and validate the
x5ccertificate chain up to the Wallet Provider Trusted List. Under TS3 the issuer identity comes from that certificate, not from anissclaim [3]. - Verify the proof of possession carried in the
jwtproof, confirming the wallet controls the signing key (under TS3,attested_keys[0]). - Check freshness. If the issuer provided a
c_nonce, it must appear in the attestation, which prevents replay [4]. - Check the assurance signals: that
key_storageanduser_authenticationmeet the level the use case requires (for PID,iso_18045_high), thatcertificationis acceptable, and thatkey_storage_statusis satisfactory.
Only when these pass does the issuer issue one credential per bound key, up to batch_size. Step through these checks interactively on the playground's How the issuer verifies page.
7.0 Lifecycle and maintenance
A WUA is not a one-off artefact; its two parts age differently, and TS3 sets out how trust is kept current [3].

Figure 04: The WUA lifecycle. From the Issued state the attestation is kept current (revocation re-checked at least every 24 hours; re-issuance with a fresh single-use WIA and KA), until it becomes Revoked (status set to revoked) or Expired (WIA time-to-live elapsed).
- The WIA is short-lived. Its time-to-live is under 24 hours (§2.2.1.1), so the wallet refreshes it frequently. This is appropriate because "the app is genuine and healthy" is a fast-changing claim.
- The KA is single-use and describes a fixed fact. "These keys are in this kind of certified secure hardware" does not change day to day, so the KA is not given a short expiry. Instead, a new, previously unused KA is sent on each re-issuance (§2.4.2).
- Revocation is the safety net. A PID Provider must re-check the revocation status of both the WIA and the KA at least once every 24 hours for the credential's validity period (§2.4.3, §2.3.1). A KA must be revoked if a security vulnerability affecting the WSCD or key storage is identified (§2.5.2), and a Wallet Provider can revoke a wallet instance's attestations when it is no longer trusted [2].
- Device and app updates. TS3 does not define triggers specific to an operating-system update or a Wallet App update or reinstall. In practice, change is governed by the mechanisms above: the sub-24-hour WIA means a fresh WIA is obtained soon after any change, and whether a new KA or re-attestation is needed depends on whether the update alters the instance identity or the WSCD keys, which is implementation-specific.
The playground's FAQ collects these lifecycle questions with their exact TS3 section references.
8.0 WUA in practice: real-world scenarios
The mechanics above play out in a handful of recurring patterns.
8.1 Issuing a PID at the high level of assurance
A government PID Provider receives a Credential Request from a wallet. Before it releases the PID, it authenticates the client with the WIA, validates the KA and its x5c chain to the Wallet Provider Trusted List, and confirms that key_storage and user_authentication report iso_18045_high. Only if the keys are shown to live in a high-assurance WSCD does it bind and issue the PID. If the assurance signals fall short, the issuer denies the request. Here the WUA is acting as the issuer's risk gate.
8.2 Batch issuance for unlinkable presentations
A wallet wants several copies of the same PID so it can present a different key to each relying party and avoid being tracked. It attests five keys in one KA and sends a single jwt proof. The issuer reads attested_keys, applies its batch_size, and returns one PID bound to each key, up to the cap. One user gesture, one proof, several single-use credentials.
8.3 A Wallet Unit Attestation in a European Business Wallet
WUAs are not limited to personal wallets. When a European Business Wallet requests an organisational attestation, the same two building blocks apply: a WIA authenticates the business wallet instance, and a KA attests the keys that will hold the organisational credential. The issuer's checks are identical in shape, which is why the lifecycle generalises across individual and business identity.
8.4 Withdrawing trust after a key-store vulnerability
A vulnerability is found in a particular WSCD model. Under TS3, the Wallet Provider must revoke the affected Key Attestations (§2.5.2), and because a PID Provider re-checks the revocation status of the WIA and KA at least every 24 hours (§2.4.3, §2.3.1), the issued credentials stop being trusted without anyone having to reach into each wallet. This is why the WUA is not only an issuance-time check but a standing trust relationship.
9.0 Try it: the interactive WUA Playground
Reading about a WUA only takes you so far. The EUDI Wallet WUA Playground lets you generate and inspect the real payloads in the browser, with nothing to install:
- Open the WUA Playground to set the number of keys and the
batch_size, then click any KA, proof, credential, or Credential Request to read its JSON. - Toggle "Show the TS3 profile" to diff the generic OpenID4VCI Key Attestation against the EUDI-profiled one, field by field.
- Watch the counters for credentials, WSCD signatures, and bound keys respond as you change the inputs.
It is an illustrative teaching aid: every payload is generated and signed client-side, and every detail links back to the source specification.
10.0 Conclusion
The Wallet Unit Attestation is what turns "trust me, I am a wallet" into something an issuer can verify. Its two parts answer two questions: the WIA proves the wallet instance is genuine and healthy, and the KA proves the binding keys live in certified secure hardware. Together they let an issuer release a PID or a (Q)EAA on solid, cryptographic grounds, support batch issuance from a single proof, and be withdrawn through revocation if trust is lost. TS3 sharpens the generic OpenID4VCI rules for the EUDI ecosystem, most notably by anchoring identity in the Trusted List via x5c, mandating high-assurance signals, and standardising on a single proof signed by the first attested key. The interactive playground is the fastest way to build intuition for how all of this looks on the wire.
References
- European Commission (2026), 'The European Digital Identity Wallet Architecture and Reference Framework (ARF) 2.9.0', Available at: https://eudi.dev/2.9.0/architecture-and-reference-framework-main/
- European Commission (2026), 'ARF Discussion Topic C: Re-issuance and Revocation of Wallet Unit Attestations', Available at: https://eudi.dev/2.9.0/discussion-topics/c-rr-wallet-unit-attestations/
- EU Digital Identity Wallet (2026), 'Technical Specification 3 (TS3): Wallet Unit Attestation', Available at: https://github.com/eu-digital-identity-wallet/eudi-doc-standards-and-technical-specifications/blob/main/docs/technical-specifications/ts3-wallet-unit-attestation.md
- OpenID Foundation (2025), 'OpenID for Verifiable Credential Issuance (OpenID4VC) 1.0', Available at: https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html
- IETF (2025), 'OAuth 2.0 Attestation-Based Client Authentication (draft-ietf-oauth-attestation-based-client-auth-07)', Available at: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-attestation-based-client-auth-07
- ETSI (2026), 'ETSI TS 119 472-3 V1.1.1: Electronic Signatures and Trust Infrastructures (ESI); Profiles for Electronic Attestation of Attributes; Part 3: Profiles for issuance of EAA or PID', European Telecommunications Standards Institute.
- European Parliament and Council (2024), 'Regulation (EU) 2024/1183 (eIDAS 2.0)', Available at: https://eur-lex.europa.eu/eli/reg/2024/1183/oj
- iGrant.io (2026), 'EUDI Wallet WUA Playground', Available at: https://eudi-wallet-wua-playground.igrant.io/