(Q)EAA Issuance with OpenID4VC¶
Basic Idea¶
The Q(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.
Cryptographic Formats¶
Long-Term keys:
- (Q)EAA Provider has long-term key pair \((ep\_pub, ep\_priv)\) which is used to sign the Credential
Transaction-specific keys:
- EUDIW generates device key \((device\_pub, device\_priv)\) which is used to generate proof of possession of a Credential
- EUDIW optionally generates key pair \((cre\_eph\_pub, cre\_eph\_priv)\) which is used to encrypt the credential response
Artifacts:
- EUDIW fetches Wallet Attestation from Wallet Provider: \(wallet\_attestation\)
- (Q)EAA Provider issues
- SD-JWT (plus Disclosures): \(sd\_jwt := \text{sign}(\mathit{hashed\_attestation\_data}, device\_pub)_{ep\_priv}\)
- ISO mdoc: \(mdoc := \text{sign}(\mathit{hashed\_attestation\_data}, device\_pub)_{ep\_priv}\)
Dependencies¶
TODO: May want to expand to include metadata.
Note: Wallet attestation not shown in this chart.
Sequence Diagram¶
Remote Issuance with Authorization Code Flow¶
User Journey: (Q)EAA Issuance - Authorization Code
Step-by-Step Description¶
- (Wallet initiated) The user opens and unlocks his wallet.
- (Wallet initiated) The user navigates to a credential catalog of pre-configured (Q)EAA Providers and offered credentials in the Wallet. He selects a (Q)EAA and the Wallet continues the flow with the preconfigured Credential Issuer URL and credential identifier.
- (Issuer initiated) User browses to (Q)EAA Provider's website.
- (Issuer initiated) Browser app on the user's device opens the (Q)EAA Provider's website
- (Issuer initiated) (Q)EAA Provider returns an HTML page to the browser containing a Credential Offer; containing
- the Credential Issuer URL
- an identifier to the offered credential
- an optional issuer_state parameter to bind this issuance to a pre-existing session
- (Issuer initiated) The user clicks on the link, the Wallet launches and he unlocks the wallet
- The Wallet fetches the Credential Issuer's metadata from the ./well-known files of the Credential Issuer URL
- The (Q)EAA Provider (from here on named Issuer in his OpenID4VCI role) return the Credential Issuer Metadata; containing:
- technical information about the Issuer
- translations and display data for the offered credentials
- The Wallet shows information about the (Q)EAA Provider and the offered (Q)EAA to the user and asks for consent
- The Wallet requests a fresh nonce for the wallet attestation nonce (wallet attestation)
- The Issuer generates a fresh nonce linked to the issuance session
- The Issuer returns the wallet attestation nonce to the Wallet
- The Wallet fetches fresh wallet attestation from the Wallet Provider backend
- The Wallet generates proof of possession (PoP) using the nonce fetched in the previous step
- The Wallet sends a Pushed Authorization Request (PAR) to the Issuer; containing:
- the Wallet Provider's client_id
- a PKCE code_challenge
- the wallet attestation and proof of possession
- a redirect_uri containing an app-link
- an identifier for the requested (Q)EAA
- The Issuer verifies the wallet attestation and validates the status of the Wallet solution through a trust list
- The Issuer stores the Authorization Request, generates a request_uri and sends this back to the Wallet
- 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.
- The Browser sends the Authorization Request to the Issuer
- 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 (Q)EAA, etc..
- taking a photo
- 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
- The browser follows the redirect, launching again the wallet
- The Wallet sends a Token Request to the PID Provider; containing:
- the auth code from Authorization Response
- the PKCE code_verifier matching the code_challenge from Authorization Request
- the wallet attestation and Proof of possession
- a DPoP key
- The Issuer matches the code, verifies the PKCE code_verifier to the previously received code_challenge and verifies the wallet attestation. It then generates an access token bound to the DPoP key.
- The Issuer verifies the wallet attestation and proof of possession
- The Issuer sends a Token Response; containing
- DPoP-bound access token
- a c_nonce
- The Wallet generates a key pair for the device binding of the (Q)EAA (kb_eph_pub, kb_eph_priv) and signs the c_nonce
- 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).
- 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
- The Wallet sends the Credential Request to the Issuer; containing
- the DPoP-bound access token
- the proof of device binding key kb_eph_pub signed c_nonce
- and optionally the
credential_response_encryption
object
- The Issuer validates the access_token and the proof
- (SD-JWT (Q)EAA) The Issuer creates the Disclosures from attestation data and signs the SD-JWT with ep_priv containing
- attestation data and hashed Disclosures as the user claims
- kb_eph_pub as cnf claim He then appends the Disclosures.
- (mdoc (Q)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
- kb_eph_pub as deviceKeyInfo
- In case
credential_response_encryption
information is present, the Issuer creates an encrypted JWT (JWE) using the values received in thecredential_response_encryption
object and adds it (among others) the (Q)EAA credential to the payload. - The Issuer sends the Credential Response JWT; containing:
- The (Q)EAA as credential
- The Wallet decrypts the Credential Response JWT using the cre_eph_priv and retrieves the credential.
- In case
credential_response_encryption
information are not present, the Issuer sends the plain Credential Response; containing:- The (Q)EAA as credential.
- The Wallet stores the (Q)EAA and the associated keys.
Remote Issuance Pre-Authorized Code Flow¶
User Journey: (Q)EAA Issuance - Pre-Authorized Code
Step-by-Step Description¶
- User browses to (Q)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..
- Browser app on the user's device opens the (Q)EAA Provider's website
- (Q)EAA Provider returns a HTML page to the browser containing a Credential Offer; containing
- 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.
- (Same-Device) The user clicks on the link, the Wallet launches and he unlocks the wallet
- (Cross-Device) The user opens and unlocks his wallet and scans the QR-Code
- The Wallet fetches the Credential Issuer's metadata from the ./well-known files of the Credential Issuer URL
- The (Q)EAA Provider (from here on named Issuer in his OpenID4VCI role) return the Credential Issuer Metadata; containing:
- technical information about the Issuer
- translations and display data for the offered credentials
- The Wallet shows information about the (Q)EAA Provider and the offered (Q)EAA to the user and asks for consent
- The Wallet requests a fresh nonce for the wallet attestation nonce (wallet attestation)
- The Issuer generates a fresh nonce linked to the issuance session
- The Issuer returns the wallet attestation nonce to the Wallet
- The Wallet fetches fresh wallet attestation from the Wallet Provider backend
- The Wallet generates proof of possession (PoP) using the nonce fetched in the previous step
- The Wallet sends a Token Request to the PID Provider; containing:
- the pre-authorized code from Authorization Response
- the wallet attestation and Proof of possession
- a DPoP key
- the Transaction Code that the user received over a second communication channel from the Issuer, if
tx_code
was present in the Credential Offer
- The Issuer verifies the wallet attestation and validates the status of the Wallet solution through a trust list
- The Issuer matches the pre-authorized code and generates an access token bound to the DPoP key.
- The Issuer sends a Token Response; containing
- DPoP-bound access token
- a c_nonce
- The Wallet generates a key pair for the device binding of the (Q)EAA (kb_eph_pub, kb_eph_priv) and signs the c_nonce
- 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).
- 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
- The Wallet sends the Credential Request to the Issuer; containing
- the DPoP-bound access token
- the proof of device binding key kb_eph_pub signed c_nonce
- and optionally the
credential_response_encryption
object
- The Issuer validates the access_token and the proof
- (SD-JWT (Q)EAA) The Issuer creates the Disclosures from attestation data and signs the SD-JWT with ep_priv containing
- attestation data and hashed Disclosures as the user claims
- kb_eph_pub as cnf claim He then appends the Disclosures.
- (mdoc (Q)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
- kb_eph_pub as deviceKeyInfo
- In case
credential_response_encryption
information is present, the Issuer creates an encrypted JWT (JWE) with the information and adds (among others) the (Q)EAA credential to the payload. - The Issuer sends the Credential Response JWT; containing:
- The (Q)EAA as credential
- The Wallet decrypts the Credential Response JWT using the cre_eph_priv and retrieves the credential.
- In case
credential_response_encryption
information are not present, the Issuer sends the plain Credential Response; containing:- The (Q)EAA as credential.
- The Wallet stores the (Q)EAA and the associated keys.
Usability Considerations¶
Common Considerations¶
- (Q)EAA Provider / Credential catalogue should inform users in advance of what is required for the successful issuance of the (Q)EAA and what steps follow
- For reasons of transparency and to increase trust, (Q)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 (Q)EAA credential on several end devices at the same time
Authorization Code Flow Considerations¶
- User needs to authenticate successfully on (Q)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 (Q)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¶
- (Q)EAA Providers may choose to require a wallet attestation
- the security guarantees of the Pre-Authorized Code Flow, especially in the Cross-Device Flow, are not intended for higher security levels
Implementation Consideration¶
TBD