Skip to content

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_supported being present and the proof_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 the proofs parameter 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_supported and proof_types_supported being omitted. During issuance the Wallet Instance doesn't generate cryptographic keys to bind the EAA and provides no proofs parameter 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.

EAA Issuance (Initial Issuance) solid line arrows represent technical functionality, dotted line arrows represent non-technical/user functionalityUserWallet Provider Backend .WB.Wallet Instance . App .WI.Browser .B.EAA Provider .EP.UserUserWallet Provider Backend (WB)Wallet Provider Backend (WB)Wallet Instance / App (WI)Wallet Instance / App (WI)Browser (B)Browser (B)EAA Provider (EP)EAA Provider (EP)alt[Wallet-initiated Authorization Code Flow](001)Select EAA from Credential Catalogue(002)fetch credential_issuer_url and credential_configuration_id from CredentialCatalogue API[Issuer-initiated Authorization Code Flow](003)Open Issuer's Website(004)Query website: HTTP GET <EAA Provider website>(005)HTTP 200 <Credential Offer>(Grant-Type: Authorization Code,credential_issuer_url, credential_configuration_id)(006)launch Wallet Instance with <Credential Offer> using custom URI scheme orHTTPS-based app link[Pre-Authorized Code Flow](007)Open Issuer's Website(008)Query website: HTTP GET <EAA Provider website>(009)HTTP 200 <Credential Offer>(Grant-Type: Pre-Authorized Code,ep_pre-auth_code, credential_issuer_url, credential_configuration_id)(010)launch Wallet Instance with <Credential Offer> using custom URI scheme orHTTPS-based app link(011)[TLS] fetch and verify EAA Provider metadata ep_meta_data(012)[TLS] authenticate towards Wallet Provider Backend and receive freshwallet attestation wb_wia(013)[TLS] HTTP POST <challenge endpoint> request for client attestationchallenge(014)generate random ep_wia_pop_nonce(015)[TLS] HTTP 200 <ep_wia_pop_nonce>(016)generate wallet attestation PoP wi_wia_pop using audience andep_wia_pop_noncealt[Authorization Code Flow](017)generate wi_pkce_code_verifier and wi_pkce_code_challenge(018)[TLS] HTTP POST <Pushed Authorization Request(wb_client_id,wb_redirect_uri, wi_pkce_code_challenge, wb_wia, wi_wia_pop)>(019)verify wb_wia and wi_wia_pop, validate wb_client_id against a trust list(020)create issuance session based on wi_pkce_code_challenge, generateep_par_request_uri(021)[TLS] HTTP 201 ep_par_request_uri(022)launch browser with <Authorization Request(ep_par_request_uri)>(023)[TLS] HTTP GET <Authorization Request(ep_par_request_uri)>loop[EAA Provider-specific authorization steps](024)[TLS] HTTP communication to authenticate the user, e.g. nested OpenID4VPpresentation or username&password(025)[TLS] HTTP 302 <Authorization Response(wb_redirect_uri,ep_authorization_code)>(026)[TLS] launch Wallet Instance with claimed HTTPS URI (app link / universallink) <Authorization Response(ep_authorization_code)>(027)user consent for receiving the EAA(028)generate DPoP keypair wi_dpop_prvk, wi_dpop_pubk using local HKS(029)generate DPoP proof wi_dpop: sign(wi_dpop_pubk, authorization server URL,timestamp)wi_dpop_prvkalt[Authorization Code Flow](030)[TLS] HTTP POST <Token Request(ep_authorization_code,wi_pkce_code_verifier, wi_dpop)>(031)verify wi_pkce_code_verifier with wi_pkce_code_challenge[Pre-Authorized Code Flow]opt[Transaction Code required](032)enter Transaction Code ep_tx_code(033)[TLS] HTTP POST <Token Request(ep_pre-auth_code, ep_tx_code, wb_wia,wi_wia_pop, wi_dpop)>(034)verify wb_wia and wi_wia_pop, validate wb_client_id against a trust list(035)validate ep_pre-auth_code and ep_tx_code(036)verify wi_dpop, generate ep_access_token bound to wi_dpop_pubk andep_refresh_token(037)[TLS] HTTP 200 <Token Response(ep_access_token, ep_refresh_token)>(038)store ep_refresh_token(039)[TLS] HTTP POST <Nonce Request()>(040)create random ep_c_nonce and ep_dpop_nonce(041)[TLS] HTTP 200 <Nonce Response(ep_c_nonce, ep_dpop_nonce)>alt[Cryptographic Holder Binding](042)generate holder binding keypair(s) (wi_eaa_device_prvk[],wi_eaa_device_pubk[]) using local HKS, bound to the Platform Authenticator(043)user authentication with Platform Authenticator to authorize signing withholder binding key pair(s)(044)generate proof(s) of possession for holder binding key pair(s)wi_eaa_device_pop[]: sign(ep_c_nonce, timestamp, EAA Provideraudience)wi_eaa_device_prvk[](045)generate DPoP proof wi_dpop: sign(wi_dpop_pubk, ep_dpop_nonce, hash ofep_access_token, authorization server URL, timestamp)wi_dpop_prvk(046)[TLS] HTTP POST <Credential Request(ep_access_token, wi_dpop,wi_eaa_device_pop[])>wi_eaa_device_pop are only providedfor cryptographic holder binding(047)validate DPoP-bound access token, verify proofs of possession if present(048)create EAAs ep_eaa_credential[] in mdoc or SD-JWT VC, either one per keyand bound to wi_eaa_device_pubk[] (Cryptographic Holder Binding) or asingle instance containing the identifying claims and not bound to a key(Claims-based Holder Binding), signed with ep_eaa_auth_prvk(049)[TLS] HTTP 200 <Credential Response(ep_eaa_credential[])>(050)store ep_eaa_credential[] and corresponding metadata

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:
  • whether a Wallet Instance Attestation is required, by checking whether token_endpoint_auth_methods_supported contains attest_jwt_client_auth. If so, steps 012-016 are performed to obtain and prove possession of the WIA
  • whether cryptographic holder binding is required, by checking whether cryptographic_binding_methods_supported and proof_types_supported are present (cryptographic holder binding) or omitted (claims-based holder binding). This determines whether the holder binding key pair and proof of possession are generated in steps 042-044 and sent in the Credential Request
  • whether batch issuance is required, by checking whether batch_credential_issuance (and optionally batch_size) is present. This determines how many holder binding keys and proofs are generated
  • the display information of the EAA, used in the consent screen and stored after successful issuance to be displayed in the dashboard (credential_metadata.display).
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:
  • the OAuth Client identifier wb_client_id as an identifier for the Wallet Solution (pre-configured by the Wallet app)
  • the redirect URI wb_redirect_uri, the claimed HTTPS URI (pre-configured by the Wallet app) to which the EP redirects the browser after authorization
  • the Wallet Attestation wb_wia and its corresponding Proof of Possession wi_wia_pop
  • the PKCE Challenge wi_pkce_code_challenge
The wb_client_id should match the subject of wb_wia.
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:
  • on Android via Custom Tabs
  • on iOS via ASWebAuthenticationSession (non-ephemeral session with prefersEphemeralWebBrowserSession = false is used, so that cookies are shared with the system browser and the EAA Provider can re-use an existing login session to authenticate the user.
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:
  • information about the EAA Provider from the ep_registration_cert
    • the trade name (name)
    • the legal name (sub_ln)
    • the identifier (sub)
    • the country (country)
    • the URI to the privacy policy (privacy_policy)
    • the URI for support, can be either email or website address (support_uri)
  • information on the EAA credential from the ep_meta_data (credential_configurations_supported.credential_metadata.display)
    • the EAA name (name)
    • optional display information (logo, background_color, background_image)
Based on this information, the user gives the final consent to receive and store the offered EAA.
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:
  • the JOSE header typ containing the dpop+jwt
  • the JOSE header alg containing the algorithm of wi_dpop_pubk
  • the JOSE header jwk containing the JWK encoding of wi_dpop_pubk
  • the payload claim jti containing a string of at least 96bits randomness
  • the payload claim htm containing the HTTP METHOD POST
  • the payload claim htu containing the target URI of the Authorization Server's Token Endpoint
  • the payload claim iat containing the current timestamp
. The WI prepares the hash of the DPoP Proof and signs it with wi_dpop_prvk using ECDSA. Unlike the PID issuance, the WI generates and manages the DPoP key locally in the HKS and signs the proof itself instead of delegating to the Remote WSCA, as EAAs generally do not require the Level of Assurance "High" key management provided by the Remote WSCA.
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:
  • the authorization code (ep_authorization_code) binding it to the issuance session
  • the PKCE Code Verifier (wi_pkce_code_verifier) to prove that the Token Request and the Pushed Authorization Request originate from the same client
  • the DPoP Proof header (wi_dpop) to provide a secure key for access token binding
The EP verifies that the wi_pkce_code_verifier matches the wi_pkce_code_challenge provided during the Pushed Authorization Request.
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:
  • the pre-authorized code (ep_pre-auth_code)
  • the Transaction Code (ep_tx_code), if required by the EAA Provider
  • the Wallet Attestation wb_wia and its corresponding Proof of Possession wi_wia_pop
  • the DPoP Proof header (wi_dpop) to provide a secure key for access token binding
As there was no Pushed Authorization Request in this flow, the EP verifies the wallet attestation (wb_wia) and its PoP (wi_wia_pop) here and validates the wb_client_id against a trust list of authorized Wallet Solutions, and validates the pre-authorized code (ep_pre-auth_code) together with the Transaction Code (ep_tx_code), if required.
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:
  • ep_c_nonce: used to validate the freshness of the holder binding proofs of possession provided by the WI at the Credential Endpoint
  • ep_dpop_nonce: used to validate the freshness of the DPoP proofs provided by the WI at the Credential Endpoint
and responds with the Nonce Response containing both nonces. The nonces may be self-contained with a limited lifetime to increase scalability; their main purpose is to guarantee freshness of the cryptographic proofs.
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:
  • the JOSE header typ containing the dpop+jwt
  • the JOSE header alg containing the algorithm of wi_dpop_pubk
  • the JOSE header jwk containing the JWK encoding of wi_dpop_pubk
  • the payload claim jti containing a string of at least 96bits randomness
  • the payload claim htm containing the HTTP METHOD POST
  • the payload claim htu containing the target URI of the Credential Endpoint
  • the payload claim iat containing the current timestamp
  • the payload claim nonce containing ep_dpop_nonce from the Nonce Endpoint
  • the payload claim ath containing the hash of the access token ep_access_token
. The WI prepares the hash of the DPoP Proof and signs it with wi_dpop_prvk using ECDSA. This step is independent of the Holder Binding mode.
046 The WI sends a Credential Request to exchange the access token for the EAA credentials, it contains:
  • the access token (ep_access_token) as the authorization for the issuance session
  • the DPoP Proof header (wi_dpop) to provide a proof of possession for the access token binding
  • for Cryptographic Holder Binding: the proofs of possession (wi_eaa_device_pop[]) of the holder binding keys, sent in the proofs parameter. For batch issuance, up to batch_size proofs are sent; if batch issuance is not supported, a single proof is sent.
  • for Claims-based Holder Binding: the proofs parameter is omitted entirely, as no holder binding key material exists to prove possession of.
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:

EAA Issuance - Presentation during Issuance (nested OpenID4VP) solid line arrows represent technical functionality, dotted line arrows represent non-technical/user functionalityUserWallet Instance . App .WI.Browser .B.EAA Provider .EP.UserUserWallet Instance / App (WI)Wallet Instance / App (WI)Browser (B)Browser (B)EAA Provider (EP)EAA Provider (EP)launch Browser with OpenID4VCI Authorization RequestOpenID4VCI Authorization Requestoptional further authenticationOpenID4VP Authorization Request for PID/EAA presentationlaunch Wallet Instance with OpenID4VP Authorization Requestuser consent for the presentationOpenID4VP Authorization Response directly to the EP's response endpointOpenID4VP redirectlaunch Browser with OpenID4VP redirectfetch EAA Provider's websiteoptional further authenticationAuthorization Responselaunch Wallet Instance with Authorization Response

Re-issuance

tbd