EAA Issuance with OpenID4VCI
Basic Idea
The EAA Provider issues signed credentials to the Wallet which are stored for a longer period. The Wallet can then present the credentials (including a proof of possession by signing over a wallet-held key) to the Relying Party.
The flows include examples for the credential formats SD-JWT VC and mdoc, but other formats are not precluded.
The flows described in this document are examples demonstrating one
possible implementation approach. Applicable industry standards for
their implementation are:
TS 119 472-1: General requirements for electronic attestations of attributes.
TS 119 472-3: Issuance requirements and signature formats.
In the context of eIDAS, the following terminology applies:
- Wallet Instance Attestation (WIA), corresponding to Wallet Attestation (WA) in OID4VC terminology.
- Key Attestation (KA).
Unless explicitly stated otherwise, this document uses the eIDAS terminology throughout the following flows.
- Wallett Instance Attestion (WIA) and Key Attetation (KA) are different types of the Wallet Unit Attestation (WUA). TS3 provides more details.
The issuance of an Electronic Attestation of Attributes (EAA) is governed by the ETSI TS 119 472-3 specification. This standard mandates the use of the OID4VC High Assurance Interoperability Profile (OID4VC-HAIP) as the underlying protocol profile.
Cryptographic Formats
Long-Term keys:
- EAA Provider has long-term key pair which is used to sign the credential
- EUDI Wallet generates device key which is used to generate proof of possession of a credential
Transaction-specific keys:
- EUDI Wallet generates key pair which is used to encrypt the credential response
Artifacts:
- EUDI Wallet fetches a Wallet Instance Attestation (WIA) from Wallet Provider:
- EUDI Wallet fetches a Key Attestation (KA) from Wallet Provider:
- Credential format specific payload signed by the issuer:
- EAA Provider issues
- SD-JWT VC (plus Disclosures):
- ISO mdoc:
Remote Issuance with Authorization Code Flow
Sequence Diagram
User Journey: EAA Issuance - Authorization Code
Step-by-Step Description
| No | Description |
|---|---|
| 001 | (Wallet initiated) The user opens and unlocks their wallet. |
| 002 | (Wallet initiated) The user navigates to a credential catalog of pre-configured EAA Providers and is offered credentials in the Wallet. They selects an EAA and the Wallet continues the flow with the pre-configured Credential Issuer URL and credential identifier. |
| 003 | (Issuer initiated) User browses to the EAA Provider's website. |
| 004 | (Issuer initiated) Browser app on the user's device opens the EAA Provider's website |
| 005 | (Issuer initiated) EAA Provider returns an HTML page to the browser containing a Credential Offer with the following payload: - the Credential Issuer URL - an identifier to the offered credential - an optional `issuer_state parameter to bind this issuance to a pre-existing session |
| 006 | (Issuer initiated) The user clicks on the link, the Wallet launches, and they unlock the wallet |
| 007 | The Wallet fetches the Credential Issuer's metadata from the ./well-known files of the Credential Issuer URL |
| 008 | The EAA Provider (from here on named Issuer in his OpenID4VCI role) returns the Credential Issuer Metadata; containing: - technical information about the Issuer - translations and display data for the offered credentials |
| 009 | The Wallet verifies the signed metadata provided by the Credential Issuer by checking the signature (should be signed with valid access certificate) & existence and validity of the embedded Relying Party Registration Certificate as defined in ETSI TS 119 472-3 |
| 010 | The Wallet displays information about the EAA Provider and the offered EAA to the user and asks for consent |
| 011 | The Wallet requests a fresh nonce for the wallet instance attestation |
| 012 | The Issuer generates a fresh nonce linked to the issuance session |
| 013 | The Issuer returns the wallet instance attestation´nonce` to the Wallet |
| 014 | The Wallet fetches a fresh `wallet instance attestation from the Wallet Provider backend (could also happen in advance) |
| 015 | The Wallet generates a proof of possession (PoP) for wallet instance attestation using the nonce fetched in the previous step |
| 016 | The Wallet sends a Pushed Authorization Request (PAR) to the Issuer; containing:- the Wallet Provider's client_id- a PKCE code_challenge- the wallet instance attestation and associated proof of possession- a redirect_uri containing an app-link- either scope or an authorization_details parameter requesting the EAA |
| 017 | The Issuer verifies the wallet instance attestation and validates the status of the Wallet solution through a trust list |
| 018 | The Issuer stores the Authorization Request, generates a request_uri and sends it back to the Wallet |
| 019 | The Wallet uses the request_uri to create an Authorization Request and send this to the Authorization endpoint of the Issuer by issuing a HTTP GET request over the system's default browser. |
| 020 | The Browser sends the Authorization Request to the Issuer |
| 021 | In this authentication phase, the Issuer may exchange any information over the browser to the user, as he got the "screen control". This may be, but is not limited to: - username / password - OpenID4VP credential presentation of PID, other EAA, etc.. - taking a photo - any other mechanism enabled through the browser |
| 022 | The Issuer finalizes the authentication phase by responding with an Authorization Response containing: - the auth code - the redirect provided by the wallet in the PAR |
| 023 | The browser follows the redirect, re-launching the wallet |
| 024 | The wallet provides information about the offered EAA and asks the user for consent |
| 025 | The Wallet sends a Token Request to the EAA Provider containing: - the auth code from Authorization Response- the PKCE code_verifier matching the code_challenge from Authorization Request- the wallet instance attestation and Proof of possession- a DPoP proof JWT establishing possession of the client key |
| 026 | The Issuer verifies the wallet instance attestation and proof of possession |
| 027 | The Issuer matches the code, verifies the PKCE code_verifier to the previously received code_challenge and verifies the wallet instance attestation. It then generates an access token bound to the DPoP key. |
| 028 | The Issuer sends a Token Response; containing - DPoP-bound access token- a c_nonce- an authorization_details object, if the authorization_details parameter was used in the Authorization Request instead of a scope |
| 029 | (Proof type : jwt) The Wallet generates a key pair for the cryptographic binding of the EAA (device_pub, device_priv) and signs the c_nonce. A jwt is used for proof of possesion containing optional a key attestation. |
| 030 | (Proof type: attestation) The Wallet generates a jwt reperesenting a key attestion without using a proof of possession of the cryptographic key material that is being attested. |
| 031 | The Wallet may request an encrypted credential response. In order to do so, it generates a new ephemeral keypair (cre_eph_pub, cre_eph_priv). |
| 032 | The Wallet creates the credential_response_encryption JSON object containing the following information:- a jwk containing the cre_eph_pub- the JWE alg parameter - the JWE enc parameter |
| 033 | (Proof type : jwt) The Wallet sends the Credential Request to the Issuer; containing - the DPoP-bound access token - the credential information either through credential_identifier or credential_configuration_ids - the proof of cryptographic binding key device_pub signed c_nonce - and the credential_response_encryption object |
| 034 | (Proof type: attestation) The Wallet sends the Credential Request to the Issuer; containing - the DPoP-bound access token - the credential information either through credential_identifier or credential_configuration_ids - the proof of cryptographic binding key device_pub signed c_nonce - and the credential_response_encryption object |
| 035 | The Issuer validates the access_token and the proof (signed over the c_nonce) |
| 036 | (SD-JWT VC EAA) The Issuer creates the Disclosures from attestation data and signs the SD-JWT VC with ep_priv containing - attestation data and hashed Disclosures as the user claims - device_pub as cnf claim He then appends the Disclosures. |
| 037 | (mdoc EAA) The Issuer creates the hashed Releases from attestation data and signs the mdoc with ep_priv containing - attestation data and hashed Releases as issuerAuth - device_pub as deviceKeyInfo |
| 038 | In case credential_response_encryption information is present, the Issuer creates an encrypted JWT (JWE) using the values received in the credential_response_encryption object and adds (among others) the EAA credential to the payload. |
| 039 | The Issuer sends the Credential Response JWT; containing: - The EAA as credential |
| 040 | The Wallet decrypts the Credential Response JWT using the cre_eph_priv and retrieves the credential. |
| 041 | In case credential_response_encryption information are not present, the Issuer sends the plain Credential Response; containing:- The EAA as credential. |
| 042 | The Wallet stores the EAA and the associated keys. |
Remote Issuance Pre-Authorized Code Flow
Sequence Diagram
User Journey: EAA Issuance - Pre-Authorized Code
Step-by-Step Description
| No | Description |
|---|---|
| 001 | The user browses to EAA Provider's website. At this point it is assumed that the user authentication already took place before the OpenID4VCI protocols starts. This may happen through any mechanism, e.g. username/password, providing OTPs, etc.. |
| 002 | Browser app on the user's device opens the EAA Provider's website |
| 003 | EAA Provider returns a HTML page to the browser containing a Credential Offer with the following payload: - the Credential Issuer URL - an identifier to the offered credential - a pre-Authorized Code for authorization, linked to the identified user - the flag tx_code indicating whether the Wallet is expected to provide a Transaction Code in the Token Request. The Transaction Code is sent by the Issuer over a second channel, e.g., via e-mail or SMS, and helps to strengthen security by additional session binding. |
| 004 | (Same-Device) The user clicks on the link, the Wallet launches and he unlocks the wallet |
| 005 | (Cross-Device) The user opens and unlocks his wallet and scans the QR-Code |
| 006 | The Wallet fetches the Credential Issuer's metadata from the ./well-known files of the Credential Issuer URL |
| 007 | The EAA Provider (from here on named Issuer in his OpenID4VCI role) returns the Credential Issuer Metadata; containing: - technical information about the Issuer - translations and display data for the offered credentials |
| 008 | The Wallet verifies the signed metadata provided by the Credential Issuer by checking the signature (should be signed with valid access certificate) & existence and validity of the embedded Relying Party Registration Certificate as defined in ETSI TS 119 472-3 |
| 009 | The Wallet shows information about the EAA Provider and the offered EAA to the user and asks for consent |
| 010 | The Wallet requests a fresh for the |
| 011 | The Issuer generates a fresh linked to the issuance session |
| 012 | The Issuer returns the for the to the Wallet |
| 013 | The Wallet fetches fresh from the Wallet Provider backend |
| 014 | The Wallet generates proof of possession for using the fetched in the previous step |
| 015 | The Wallet sends a Token Request to the EAA Provider; containing: - the pre-authorized code from Authorization Response - the and Proof of possession - a proof JWT establishing possession of the client key - the Transaction Code that the user received over a second communication channel from the Issuer, if was present in the Credential Offer |
| 016 | The Issuer verifies the and validates the status of the Wallet solution through a trust list |
| 017 | The Issuer matches the pre-authorized code and generates an access token bound to the key. |
| 018 | The Issuer sends a Token Response; containing - - |
| 019 | The Wallet generates a key pair for the cryptographic binding of the EAA (device_pub, kb_eph_priv) and signs the c_nonce |
| 020 | The Wallet may request an encrypted credential response. In order to do so, it generates a new ephemeral keypair (cre_eph_pub, cre_eph_priv). |
| 021 | The Wallet creates the credential_response_encryption JSON object containing the following information:- a jwk containing the cre_eph_pub - the JWE alg parameter - the JWE enc parameter |
| 022 | The Wallet sends the Credential Request to the Issuer; containing - the DPoP-bound access token - the credential information either through credential_identifier or credential_configuration_ids- the proof of cryptographic binding key device_pub signed c_nonce - and the credential_response_encryption object |
| 023 | The Issuer validates the access_token and the proof |
| 024 | (SD-JWT VC EAA) The Issuer creates the Disclosures from attestation data and signs the SD-JWT VC with ep_priv containing - attestation data and hashed Disclosures as the user claims - device_pub as cnf claim He then appends the Disclosures. |
| 025 | (mdoc EAA) The Issuer creates the hashed Releases from attestation data and signs the mdoc with ep_priv containing - attestation data and hashed Releases as issuerAuth - device_pub as deviceKeyInfo |
| 026 | In case credential_response_encryption information is present, the Issuer creates an encrypted JWT (JWE) with the information and adds (among others) the EAA credential to the payload. |
| 027 | The Issuer sends the Credential Response JWT; containing: - The EAA as credential |
| 028 | The Wallet decrypts the Credential Response JWT using the cre_eph_priv and retrieves the credential. |
| 029 | In case credential_response_encryption information are not present, the Issuer sends the plain Credential Response; containing:- The EAA as credential. |
| 030 | The Wallet stores the EAA and the associated keys. |
Usability Considerations
Common Considerations
- EAA Provider / Credential catalog should inform users in advance of what is required for the successful issuance of the EAA and what steps follow
- For reasons of transparency and to increase trust, EAA Providers should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the provider itself.
- User must confirm the process with the Device Authenticator
- User can have a EAA credential on several end devices at the same time
Authorization Code Flow Considerations
- User needs to authenticate successfully on EAA Provider website
- If the user has to go through more than 2 context switches (issuer initiated flow), it can be confusing, might create unnecessary complexity and additional potential points of failure, and ultimately leads to friction.
Pre-Authorized Code Flow Considerations
- User is already authenticated on EAA Provider website or no authentication is required
- To obtain/copy the transaction code, an additional context switch may be necessary
Privacy Considerations
- Unlinkability has to be achieved with batch issuance
Security Considerations
- EAA Providers may choose to require a wallet instance attestation and a key attestation
- The security guarantees of the Pre-Authorized Code Flow, especially in the Cross-Device Flow, are not intended for higher security levels
Attestation Data and Signature Scope
The term attestation data refers to the attributes and claims contained in the credential that are covered by the issuer's signature. For EAA, the following clarifications apply:
| Credential Format | Signed Content | Signature Format |
|---|---|---|
| SD-JWT VC | All claims (hashed disclosures) + holder binding key (cnf) | JWS (JSON Web Signature) |
| ISO mdoc | All attributes in issuerAuth + device key binding (deviceKeyInfo) | COSE_Sign1 |