3.3.1 EAA Issuance¶
This chapter describes the issuance of Electronic Attestations of Attributes (EAA) following OpenID for Verifiable Credential Issuance (OpenID4VCI) 1.0 according to the High-Assurance Interoperability Profile (HAIP) 1.0. The profile defines various constraints for the options in OpenID4VCI.
For the purpose of this flow no distinction is made between EAA, Qualified EAA (QEAA) and EAA issued by a Public Sector Body (PubEAA); the differences between these types are described in the blueprint and the term "EAA" is used hereafter to refer to all of them.
EAAs can be issued in different credential formats, which are defined as Credential Format Profiles in OpenID4VCI 1.0, Appendix A. EAA Providers choose the EAA's credential format and signal it using the format parameter in the Credential Issuer metadata. The WI supports two credential formats:
- ISO/IEC 18013-5 format (
mso_mdoc), - IETF SD-JWT VC format (
dc+sd-jwt).
EAAs may use different forms of Holder Binding, which describes how a credential is bound to a particular Wallet Instance or user. The EAA Provider chooses the Holder Binding mechanism for its issued credentials. The two options are:
- Cryptographic Holder Binding (also known as device binding) uses cryptographic keys held by the Wallet Instance to allow users proving legitimate possession of EAAs. EAA Providers signal requirements in the Credential Issuer metadata with
cryptographic_binding_methods_supportedbeing present and theproof_types_supported. During issuance the Wallet Instance generates cryptographic keys in the hardware-bound Keystore (HKS), bound to the Platform Authenticator so that the user must authenticate before the keys can be used for signing, and provides them in theproofsparameter of the Credential Request to the EAA Provider. Each presentation of an EAA with cryptographic holder binding likewise requires the user to authenticate with the Platform Authenticator. - Claims-based Holder Binding (also known as non-key-bound) uses claims contained in the EAA to allow users proving legitimate possession of EAAs, e.g. a name and birthdate that is proven by presenting the EAA together with a PID. The EAA Provider signals the absence of key-binding in the Credential Issuer metadata with
cryptographic_binding_methods_supportedandproof_types_supportedbeing omitted. During issuance the Wallet Instance doesn't generate cryptographic keys to bind the EAA and provides noproofsparameter in the Credential Request. Presentation of an EAA with claims-based holder binding do not require the user to authenticate with the Platform Authenticator. Note that claims-based Holder Binding currently only works for SD-JWT VC, not for mdoc.
Credentials can be issued as single instances or as batches. Batch issuance enhances the privacy for users by using different cryptographic key material (such as hashes, public keys and signatures) for each credential instance to use them in a one-time-use policy to prevent Verifier linkability. EAA Providers signal support for batch issuance in the Credential metadata by providing the batch_credential_issuance parameter and optionally the batch_size for the maximum possible batch size. If supported by the EAA Provider, the Wallet Instance uses batch issuance by sending up to batch_size proofs in the Credential Request. If not supported by the EAA Provider, the Wallet Instance must only send a single proof in the proofs parameter. Batch issuance is hidden from the user and should have minimal to no impacts on the user experience.
EAA Providers may require the Wallet Instance to authenticate itself using Attestation-based Client Authentication, so that only authorized and legitimate Wallets can request EAAs. The EAA Provider signals requirement for client authentication in the Authorization Server metadata with the token_endpoint_auth_methods_supported parameter containing the value attest_jwt_client_auth. If required, the Wallet Instance presents a Wallet Instance Attestation (WIA) and a corresponding Proof of Possession during issuance, as detailed in the Wallet Instance Attestation section of the PID issuance flow.
For the initial issuance of an EAA, OpenID4VCI 1.0 defines two grant types:
- The Pre-Authorized Code Flow, in which the EAA Provider has already authenticated the user and provides a Credential Offer containing a pre-authorized code to the Wallet Instance, optionally protected by a Transaction Code that the user has to enter.
- The Authorization Code Flow, in which the Issuer can either be wallet-initiated, where the user selects the credential from the Wallet's Credential Catalogue, or issuer-initiated, where the Issuer provides a (static) Credential Offer referencing the Authorization Code grant. In both cases, the WI opens the user agent (browser) to let the EAA Provider take control in order to perform the user authentication and authorization. As part of this step, the EAA Provider may perform a presentation during issuance to get authorization through a nested OpenID4VP flow. After the authorization the EAA Provider redirects the user back to the WI to continue the issuance.
Furthermore, a credential can be returned immediately in the Credential Response or, when it cannot yet be produced, via the Deferred Credential Endpoint (immediate vs. deferred issuance).
After the initial issuance, an EAA can be re-issued by exchanging a Refresh Token at the Token Endpoint for a new access token, without requiring the user to authenticate again.
Data Flow¶
This section describes the data flow of the EAA issuance in sequence diagrams and more detailed tables. Artifacts in italics are further explained in the data register chapter.
Unlike the PID issuance, the EAA issuance does not rely on the Remote WSCA (RWSCA): as EAAs generally do not require the Level of Assurance "High" key management mandated for the PID, the Wallet Instance manages the DPoP and Holder Binding keys locally in the device's Hardware Key Store (HKS).
The issuance is described in two separate flows: the Initial Issuance, in which the user obtains an EAA for the first time, and the Re-issuance, in which the WI obtains a new EAA by exchanging a previously issued refresh token (ep_refresh_token) at the Token Endpoint, without requiring the user to authenticate again. The Presentation during Issuance section details the nested OpenID4VP flow that EAA Providers may use within the Authorization Code Flow to authenticate the user.
Initial Issuance¶
The initial issuance uses one of the two OpenID4VCI grant types, marked as alternatives in the sequence diagram when they diverge:
1) the Authorization Code Flow, either wallet-initiated (the user selects the EAA from the Wallet's Credential Catalogue) or issuer-initiated (the user starts on the EAA Provider's website and receives a Credential Offer referencing the Authorization Code grant). The green section describes steps that are only relevant for this flow. 2) the Pre-Authorized Code Flow, in which the EAA Provider has already authenticated the user and provides a Credential Offer containing a pre-authorized code. The yellow section describes steps that are only relevant for this flow.
The red section describes steps that are only relevant for cryptographic holder binding.
The following table describes the steps of the sequence diagram in more detail:
| No | Description |
|---|---|
| 001 - 002 | Steps 001-002 only occur in the wallet-initiated Authorization Code Flow. The user selects the EAA to be issued from the Wallet's Credential Catalogue, a curated list of attestations offered by EAA Providers. The WI obtains the credential_issuer_url of the EAA Provider and the credential_configuration_id identifying the requested credential configuration from the Credential Catalogue API. |
| 003 - 006 | Steps 003-006 only occur in the issuer-initiated Authorization Code Flow. The user opens the EAA Provider's website in the browser. The website returns a Credential Offer referencing the Authorization Code grant, containing the credential_issuer_url and the credential_configuration_id. The Credential Offer is passed to the WI, e.g. by scanning a QR code or following a link, which launches the WI using a custom URI scheme or an HTTPS-based app link. |
| 007 - 010 | Steps 007-010 only occur in the Pre-Authorized Code Flow. Analogous to 003-006, but the EAA Provider has already authenticated the user (e.g. during an existing login session on its website) and the returned Credential Offer references the Pre-Authorized Code grant. It additionally contains the pre-authorized code (ep_pre-auth_code) and may indicate that a Transaction Code is required, which the user has to enter in the WI (step 032) to bind the offer to the user. |
| 011 | The Wallet Instance fetches OpenID4VCI Credential Issuer and Authorization Server metadata (ep_meta_data) from the EAA Provider. The WI and EP are always communicating via TLS and start a TLS session here. The trust relationship between the WI and the EP is established through the signed metadata provided by the EAA Provider and signed with ep_access_cert_prvk. The WI verifies the signed metadata with ep_access_cert_pubk contained in the ep_access_cert (encoded as x5c JOSE header, following ETSI TS 119 411-8), verifies the Certificate Revocation List (CRL) and verifies the certificate chain against the root certificate of the Access Certificate Provider. The signed metadata additionally contains the ep_registration_cert (following ETSI TS 119 475) as issuer_info, which lists the EAA Provider's registered attributes and purpose and is used to display information about the EAA Provider and the requested attributes to the user for consent. The WI verifies the Token Status List of the ep_registration_cert and verifies the certificate chain against the root certificate of the Registration Certificate Provider. Furthermore, the metadata serves to determine the following information about the EAA issuance:
|
| 012 | The WI fetches a fresh Wallet Instance Attestation ad-hoc from its Wallet Provider Backend as described in the Create WIA operation. A dedicated WIA is requested for each issuance. See PID issuance, step 005. |
| 013 - 015 | The Wallet Instance requests a challenge from the EAA Provider (EP) for the generation of the Wallet Instance Attestation PoP. The challenge guarantees freshness of the presentation to the EP. The process is described in detail in the challenge retrieval section of Attestation-Based Client Authentication. |
| 016 | The WI generates a proof of possession wi_wia_pop for the Wallet Instance Attestation wb_wia, as detailed in the Wallet Instance Attestation section of the PID issuance flow. |
| 017 | Steps 017-026 only occur in the Authorization Code Flow (both wallet-initiated and issuer-initiated). The WI generates a PKCE Verifier wi_pkce_code_verifier as a random string and a matching PKCE Challenge wi_pkce_code_challenge as the SHA-256 hash of the wi_pkce_code_verifier. Proof Key for Code Exchange (PKCE) ensures the binding between the Authorization Request and the Token Request. |
| 018 | The WI sends a Pushed Authorization Request (PAR) to the EP to start the OpenID4VCI issuance flow, it contains:
|
| 019 | The EP verifies the Wallet Instance Attestation (wb_wia) and its Proof-of-Possession (wi_wia_pop) and validates the wb_client_id and the wb_redirect_uri using a trusted list of authorized wallet solutions. |
| 020 | The EP creates an issuance session to store the wi_pkce_code_challenge and generates a ep_par_request_uri that references this session. |
| 021 | The EP responds with the ep_par_request_uri. |
| 022 - 023 | The WI opens the user agent (browser) and sends the Authorization Request by calling ep_par_request_uri to the EP's Authorization Endpoint. The front-channel invocation via the browser hands control over to the EP for user authentication and authorization. Following the recommendation from Section 6 of OAuth 2.0 for Native Apps (RFC 8252), the WI uses an in-app browser tab, so that the address bar remains visible for phishing resistance and the session is shared with the system browser:
|
| 024 | The EP performs its provider-specific user authentication and authorization steps, which may involve multiple round trips. This can be, for example, a presentation during issuance using a nested OpenID4VP flow (e.g. presenting a PID or another attestation as required by the EAA Provider) or a classic username & password login. |
| 025 | After successful authentication and authorization, the EP redirects the browser back to wb_redirect_uri with an Authorization Response containing the authorization code (ep_authorization_code). This Authorization Response in the context of OpenID4VCI is not to be confused with the OpenID4VP Authorization Response used during a nested presentation. |
| 026 | Steps 017-026 only occur in the Authorization Code Flow. The browser launches the WI, passing the Authorization Response with the ep_authorization_code back to the WI. To ensure the Authorization Response is delivered to the legitimate WI, the WI registers a claimed HTTPS URI as its wb_redirect_uri as described in Section 7.2 of RFC 8252, realized via Android App Links and iOS Universal Links, rather than a custom URI scheme. As the platform verifies domain ownership for claimed HTTPS URIs, the redirect cannot be intercepted by another app that has registered the same custom URI scheme. |
| 027 | The WI presents a consent screen to the user, displaying the identity of the EAA Provider and the requested attributes and purpose taken from the ep_registration_cert and ep_meta_data:
|
| 028 - 029 | The WI generates a DPoP key pair (wi_dpop_prvk, wi_dpop_pubk) in its local Hardware Key Store (HKS) to sender-constrain the access token. It then prepares the payload of the DPoP proof (wi_dpop). The DPoP Proof contains:
|
| 030 - 031 | Steps 030-031 only occur in the Authorization Code Flow. The WI sends a Token Request to exchange the authorization code for an access token, it contains:
|
| 032 | Step 032-035 only occurs in the Pre-Authorized Code Flow. Step 032 only occurs ifif the EAA Provider requires a Transaction Code. The user enters the Transaction Code (ep_tx_code), a short code communicated by the EAA Provider to the user out-of-band (e.g. displayed on its website or sent via SMS/email), into the WI. The Transaction Code binds the Credential Offer to the user who requested it and is sent together with the pre-authorized code in the Token Request (steps 033-035) to prove that the offer was retrieved by the legitimate user. |
| 033 - 035 | Steps 032-035 only occur in the Pre-Authorized Code Flow. The WI sends a Token Request to exchange the pre-authorized code for an access token, it contains:
|
| 036 | The EP verifies the DPoP Proof (wi_dpop) and generates an access token (ep_access_token), sender-constrained to the DPoP key (wi_dpop_pubk) contained in the DPoP Proof, that shall be used for immediate issuance of the EAA credentials, and a refresh token (ep_refresh_token), that may be used later for re-issuance without user authentication. As the WI already authenticates towards the EP using attestation-based client authentication, the refresh token is not sender-constrained via DPoP; its binding, if any, is to be defined as part of the Re-issuance flow. |
| 037 | The EP responds with the Token Response to the WI, containing the access token (ep_access_token) and the refresh token (ep_refresh_token). |
| 038 | The WI stores the refresh token (ep_refresh_token) for later use in re-issuance. The refresh token is opaque to the WI. |
| 039 - 041 | The WI sends a Nonce Request to the Credential Issuer's Nonce Endpoint. The EP generates two random nonces:
|
| 042 - 044 | Steps 042-044 only occur for Cryptographic Holder Binding, as determined from the EAA Provider metadata in step 011 (cryptographic_binding_methods_supported and proof_types_supported present). For Claims-based Holder Binding (both parameters omitted from the metadata), this branch is skipped entirely, as shown by the alternative in the sequence diagram: no holder binding key pair is generated, no Platform Authenticator authentication is requested and no proof of possession is created, since the EAA is instead bound to the user via claims contained in the credential itself (e.g. name and birthdate). The WI generates the holder binding key pairs (wi_eaa_device_prvk[], wi_eaa_device_pubk[]) in its local Hardware Key Store (HKS), configured so that each key can only be used for signing while the Platform Authenticator is set up on the device. If the EAA Provider supports batch issuance (batch_credential_issuance present in the metadata), the WI generates up to batch_size key pairs, so that each issued EAA instance can use distinct key material for a one-time-use policy that prevents Verifier linkability; otherwise a single key pair is generated. The underlying keystore enforces this Platform Authenticator authentication at the point the key is used for signing; the WI therefore asks the user to authenticate immediately before generating one proof of possession per key (wi_eaa_device_pop[]), signing the ep_c_nonce, a timestamp and the EAA Provider audience with the respective wi_eaa_device_prvk, proving legitimate possession of each holder binding key. |
| 045 | The WI prepares the payload of the DPoP proof used to proof the sender-constrained access token (wi_dpop) for the Credential Request. The DPoP Proof contains:
|
| 046 | The WI sends a Credential Request to exchange the access token for the EAA credentials, it contains:
|
| 047 | The EP validates the DPoP-bound access token (ep_access_token) and its corresponding DPoP Proof header (wi_dpop), and, for Cryptographic Holder Binding, verifies the holder binding proofs of possession (wi_eaa_device_pop[]). |
| 048 | The EP creates the EAAs in mdoc or SD-JWT VC format (ep_eaa_credential[]). For Cryptographic Holder Binding, one EAA is created per provided holder binding key, each bound to the respective key (wi_eaa_device_pubk[]). For Claims-based Holder Binding, a single EAA is created that is not bound to any key but contains the identifying claims. In both cases, the EAA is signed with the EP's signing key ep_eaa_auth_prvk. If the EAAs cannot be produced immediately, the EP instead returns a transaction_id and the WI later retrieves the credentials from the Deferred Credential Endpoint. |
| 049 | The EP responds with a Credential Response containing the EAA credentials (ep_eaa_credential[]). |
| 050 | The WI stores the EAA credentials (ep_eaa_credential[]) and the corresponding metadata (e.g. credential_metadata.display) data. |
Presentation during Issuance¶
During the Authorization Code Flow, the EAA Provider may require the user to present an existing credential (e.g. the PID or another EAA) as part of authenticating and authorizing the user for the requested EAA, for example to bind the issued EAA to an already-proven identity. OpenID4VCI 1.1 is expected to introduce an Interactive Authorization Endpoint for this purpose, allowing such a presentation to be integrated into the issuance flow without leaving the Authorization Endpoint. As this is not yet part of OpenID4VCI 1.0 and not yet supported by the WI, the Authorization Code Flow instead uses a nested OpenID4VP flow, in which the EAA Provider opens an OpenID4VP presentation session from its website during the EAA Provider-specific authorization steps (see step 024 of Initial Issuance).
This nested flow involves several context switches between the Browser and the WI, as the EAA Provider's website (rendered in the Browser) hands off to the WI for the presentation, and the WI has to hand control back to the Browser afterwards so that the original OpenID4VCI Authorization Request/Response exchange with the EAA Provider can complete normally. The following diagram depicts the essential steps for the nested OpenID4VP flow:
Re-issuance¶
tbd