Wallet Attestations

Wallet attestations are cryptographic proofs that establish trust in digital identity wallets. They enable credential issuers and relying parties to verify that they are communicating with legitimate, secure wallet applications before sharing sensitive identity data.

Why Wallet Attestations Matter

In a digital identity ecosystem, trust flows in multiple directions:

  • Issuers need assurance that credentials are being issued to secure, legitimate wallets
  • Verifiers (Relying Parties) need confidence that presented credentials come from trustworthy wallet applications
  • Users need protection against malicious apps impersonating legitimate wallets

Wallet attestations address these requirements by providing cryptographic proof of a wallet's integrity, security properties, and authorization status.

OAuth 2.0 Attestation-Based Client Authentication

The foundation for wallet attestations in modern digital identity systems is the OAuth 2.0 Attestation-Based Client Authentication specification (IETF draft-ietf-oauth-attestation-based-client-auth). This standard extends OAuth 2.0 to enable traditionally "public" clients (like mobile wallet apps) to authenticate with authorization servers.

The Problem with Traditional OAuth Clients

In classic OAuth 2.0, clients are categorized as:

Client TypeDescriptionAuthentication
ConfidentialServer-side apps that can securely store secretsClient secret or private key
PublicMobile/browser apps that cannot securely store secretsNo authentication possible

Digital identity wallets are inherently public clients—they run on user devices where secrets cannot be reliably protected. Yet issuers need strong assurance about which wallet is requesting credentials.

The Attestation Solution

Attestation-based client authentication solves this by introducing a trusted third party (the Wallet Provider) who vouches for the wallet instance:

┌─────────────────────────────────────────────────────────────────┐
│                    Wallet Provider                               │
│                    (Trusted Authority)                           │
└─────────────────────────────────────────────────────────────────┘
        │                                           │
        │ (1) Validates wallet                      │ (3) Issues Client
        │     integrity & security                  │     Attestation JWT
        │                                           │
        ▼                                           ▼
┌─────────────────────────────────────────────────────────────────┐
│                    Wallet Instance                               │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  (2) Generates key pair in secure hardware              │   │
│  │  (4) Creates Proof of Possession (PoP)                  │   │
│  └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘
        │
        │ (5) Client Attestation JWT + PoP
        ▼
┌─────────────────────────────────────────────────────────────────┐
│                    Issuer / Verifier                             │
│                    (Authorization Server)                        │
└─────────────────────────────────────────────────────────────────┘

Two-Part Authentication

The attestation consists of two JWTs sent together, separated by a ~ character:

ComponentCreated ByPurpose
Client Attestation JWTWallet ProviderVouches for the wallet instance's authenticity and security
Client Attestation PoPWallet InstanceProves possession of the key bound in the attestation

Token Request Example:

POST /token HTTP/1.1
Host: issuer.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=SplxlOBeZQQYbYS6WxSbIA&
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-client-attestation&
client_assertion=eyJhbGciOiJFUzI1NiIs...~eyJhbGciOiJFUzI1NiIs...

How an Issuer Trusts a Wallet

When a wallet requests a credential from an issuer, the issuer must verify that:

  1. The wallet is a legitimate, authorized application
  2. The wallet meets security requirements for the credential type
  3. The credential will be stored securely

Issuer Trust Flow (OpenID4VCI)

┌──────────┐                    ┌──────────┐                    ┌──────────┐
│  Wallet  │                    │  Wallet  │                    │  Issuer  │
│ Instance │                    │ Provider │                    │          │
└────┬─────┘                    └────┬─────┘                    └────┬─────┘
     │                               │                               │
     │ 1. Generate key pair          │                               │
     │    in secure hardware         │                               │
     │                               │                               │
     │ 2. Request attestation        │                               │
     │   (with platform evidence)    │                               │
     │──────────────────────────────>│                               │
     │                               │                               │
     │                               │ 3. Validate:                  │
     │                               │    - App integrity            │
     │                               │    - Device security          │
     │                               │    - Key storage type         │
     │                               │                               │
     │ 4. Client Attestation JWT     │                               │
     │<──────────────────────────────│                               │
     │                               │                               │
     │ 5. Discover issuer metadata                                   │
     │──────────────────────────────────────────────────────────────>│
     │                               │                               │
     │ 6. Authorization request (PAR)                                │
     │    + Client Attestation + PoP                                 │
     │──────────────────────────────────────────────────────────────>│
     │                               │                               │
     │                               │    7. Validate attestation:   │
     │                               │       - Signature (Provider)  │
     │                               │       - PoP (Wallet key)      │
     │                               │       - Provider in Trust List│
     │                               │       - Security claims       │
     │                               │                               │
     │ 8. Authorization response                                     │
     │<──────────────────────────────────────────────────────────────│
     │                               │                               │
     │ 9. Token request + attestation                                │
     │──────────────────────────────────────────────────────────────>│
     │                               │                               │
     │ 10. Access token                                              │
     │<──────────────────────────────────────────────────────────────│
     │                               │                               │
     │ 11. Credential request                                        │
     │     + Key proof (+ optional WTE)                              │
     │──────────────────────────────────────────────────────────────>│
     │                               │                               │
     │                               │    12. Verify key binding     │
     │                               │        Issue credential       │
     │                               │                               │
     │ 13. Credential                                                │
     │<──────────────────────────────────────────────────────────────│

What the Issuer Validates

CheckPurpose
Attestation SignatureConfirms the Wallet Provider issued this attestation
Proof of PossessionConfirms the wallet controls the attested key
Provider TrustVerifies the Wallet Provider is in the EU Trust List
ExpirationEnsures the attestation is still valid
Security ClaimsChecks key storage type, user authentication requirements
Revocation StatusConfirms the wallet instance hasn't been revoked

Client Attestation JWT Claims

{
  "typ": "wallet-attestation+jwt",
  "alg": "ES256",
  "kid": "wallet-provider-key-1"
}
.
{
  "iss": "https://wallet-provider.example.com",
  "sub": "https://wallet-provider.example.com/wallet/v1.6.0",
  "iat": 1704067200,
  "exp": 1704153600,
  "wallet_name": "Example EUDI Wallet",
  "wallet_version": "1.6.0",
  "key_type": "STRONGBOX",
  "user_authentication": "SYSTEM_BIOMETRIC",
  "attested_security_context": "https://trust-list.eu/asc/high",
  "cnf": {
    "jwk": {
      "kty": "EC",
      "crv": "P-256",
      "x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
      "y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
    }
  }
}

Wallet Trust Evidence (WTE)

For high-assurance credentials, issuers may require additional proof about the key that will hold the credential. Wallet Trust Evidence is conveyed at the Credential Endpoint:

{
  "format": "vc+sd-jwt",
  "credential_identifier": "eu.europa.ec.eudi.pid",
  "proofs": {
    "jwt": {
      "proof_type": "jwt",
      "jwt": "eyJhbGciOiJFUzI1NiIs..."
    },
    "attestation": {
      "attestation": "eyJhbGciOiJFUzI1NiIs...",
      "proof": "eyJhbGciOiJFUzI1NiIs..."
    }
  }
}

The WTE attestation includes claims about:

ClaimDescription
key_typeHardware security level (e.g., "strong_box", "tee", "software")
user_authenticationRequired user auth (e.g., "biometric", "pin", "none")
device_keysInformation about device-bound keys
cnfThe public key that will be bound to the credential

How a Verifier Trusts a Wallet

When a wallet presents credentials to a verifier (relying party), the trust requirements differ from issuance. The verifier primarily needs to trust the credential and its issuer, but may also want assurance about the wallet.

Verifier Trust Flow (OpenID4VP)

┌──────────┐                                        ┌──────────┐
│  Wallet  │                                        │ Verifier │
│ Instance │                                        │   (RP)   │
└────┬─────┘                                        └────┬─────┘
     │                                                   │
     │ 1. Authorization Request                          │
     │   (presentation_definition)                       │
     │<──────────────────────────────────────────────────│
     │                                                   │
     │ 2. User consent                                   │
     │                                                   │
     │ 3. Create Verifiable Presentation                 │
     │    - Select credentials                           │
     │    - Apply selective disclosure                   │
     │    - Sign with holder key                         │
     │                                                   │
     │ 4. Authorization Response                         │
     │    (vp_token + optional wallet attestation)       │
     │──────────────────────────────────────────────────>│
     │                                                   │
     │                      5. Validate:                 │
     │                         - Credential signatures   │
     │                         - Issuer trust (Trust List)│
     │                         - Holder binding          │
     │                         - Credential status       │
     │                         - (Optional) Wallet attestation│
     │                                                   │
     │ 6. Access granted                                 │
     │<──────────────────────────────────────────────────│

What the Verifier Validates

CheckPrimary Trust SourcePurpose
Credential SignatureIssuer's keyConfirms credential authenticity
Issuer TrustEU Trust ListVerifies issuer is authorized
Holder BindingPresentation signatureConfirms presenter controls the credential
Credential StatusStatus listChecks for revocation/suspension
Wallet AttestationWallet Provider(Optional) Additional assurance about wallet security

When Verifiers Require Wallet Attestation

Wallet attestation during presentation is optional but may be required for:

ScenarioReason
High-value transactionsAdditional security assurance
Regulated industriesCompliance requirements
Government servicesPolicy mandates
Sensitive data accessRisk mitigation

Verifier Attestation (Reverse Trust)

OpenID4VP also supports Verifier Attestation, allowing wallets to verify the legitimacy of verifiers before sharing credentials:

{
  "client_id": "https://verifier.example.com",
  "client_id_scheme": "verifier_attestation",
  "verifier_attestation": "eyJhbGciOiJFUzI1NiIs..."
}

This enables wallets to:

  • Confirm the verifier is a legitimate organization
  • Check the verifier's authorization to request specific credentials
  • Display verified verifier information to users

Types of Wallet Attestations

Wallet Instance Attestation (WIA)

The WIA attests to the wallet application's integrity and authorization:

ClaimDescription
issWallet Provider identifier
subWallet instance/solution identifier
wallet_nameHuman-readable wallet name
wallet_versionApplication version
client_statusCurrent status (active, suspended, revoked)
cnfBound public key

Key Attestation

Proves properties of the cryptographic keys:

PropertyDescription
key_typeStorage type (STRONGBOX, TEE, SOFTWARE)
user_authenticationRequired authentication (BIOMETRIC, PIN, NONE)
key_storage_statusKey validity and revocation info

Attestation Lifecycle Models

ModelDescriptionUse Case
Long-livedReused across transactions; requires revocation checkingReduced latency; simpler wallet implementation
EphemeralSingle-use per transaction; no revocation neededMaximum privacy; no tracking across verifiers

Integration with OpenID Protocols

OpenID4VCI (Credential Issuance)

Wallet attestation is used at multiple points:

EndpointAttestation Use
PAR EndpointClient authentication via attestation
Token EndpointClient authentication via attestation
Credential EndpointKey attestation / WTE for credential binding

OpenID4VP (Credential Presentation)

ComponentAttestation Use
Authorization RequestVerifier attestation (optional)
Authorization ResponseWallet attestation (optional)

Privacy Considerations

Wallet attestations must be designed to protect user privacy:

RequirementImplementation
No unique identifiersAttestations must not contain values that enable user tracking
UnlinkabilityDifferent attestations should be used with different verifiers
Minimal disclosureOnly necessary claims should be included
Short validityLimits the window for correlation attacks

Privacy Risk: Using the same wallet attestation across multiple verifiers could enable correlation of user activity. Implementations should consider using ephemeral attestations or rotating attestations per verifier.

Regulatory Framework

Wallet attestations are mandated by the eIDAS 2.0 framework:

RegulationRequirement
eIDAS 2.0Wallet Providers must ensure wallet integrity and security
CIR 2024/2977Technical requirements for wallet attestations
CIR 2024/2979Certification requirements for wallet solutions
ETSI 119 476-3Technical specification for WUA and WIA (in development)

Level of Assurance

LoAKey StorageUser AuthenticationAttestation Requirements
LowSoftwareNone requiredBasic WIA
SubstantialHardware recommendedPIN or biometricWIA + Key attestation
HighHardware requiredStrong authenticationWIA + WTE + certified WSCD

Further Reading

Last updated on April 8, 2026