Skip to content

3.3.2 EAA Presentation

This chapter describes the presentation of Electronic Attestations of Attributes (EAA) based on OpenID for Verifiable Presentations (OpenID4VP) 1.0 as presentation protocol, profiled by OpenID HAIP 1.0 and ETSI TS 119 472-2.

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.

The process implements the following protocol variants:

  • same-device flow and cross-device flow
  • redirect-based flow with custom URL schemes (no support for W3C Digital Credentials API as specified in Annex A)
  • cryptographic holder binding with keys managed in the local Hardware Key Store (HKS) and bound to the Platform Authenticator, or claims-based holder binding without any key binding
  • one-time policy for batch-issued EAA credentials to meet Verifier-Verifier unlinkability
  • ISO/IEC 18013-5 and SD-JWT VC as Credential formats

The form of Holder Binding is chosen by the EAA Provider during EAA issuance and determines how the presentation is protected:

  • Cryptographic Holder Binding: the WI proves legitimate possession of the EAA with a key binding proof over the Relying Party's challenge, signed with the holder binding key (wi_eaa_device_prvk) that was generated during issuance. As the key is bound to the Platform Authenticator, the user has to authenticate before the WI can create the proof.
  • Claims-based Holder Binding: the EAA carries identifying claims instead of being bound to a key. The WI creates no key binding proof and the user does not have to authenticate with the Platform Authenticator. This is only possible for SD-JWT VC, as mdoc always requires a key binding. The presentation is not cryptographically bound to the Relying Party's request.

A Relying Party may request several credentials in one rp_dcql_query, for example an EAA together with a PID or with another EAA. This is one of the ways a Relying Party can link a claims-based EAA to an identity, by comparing the identifying claims of the EAA with the attributes of a PID presented alongside it, but it is not a requirement for presenting an EAA. If a PID is part of such a combined request, the PID part of the presentation follows the PID presentation, including the signing of the key binding by the RWSCA and the entry of the user_rwsca_pin.

Data Flow

This section describes the data flow of the EAA presentation in a sequence diagram and a more detailed table. Artifacts in italics are further explained in the data register chapter.

Sequence Diagram

The sequence diagram contains the following variants, marked as alternatives when they diverge:

1) the Same-Device Flow, the green sections describe steps that are only relevant for this flow, 2) the Cross-Device Flow, the yellow sections describe steps that are only relevant for this flow.

The red section describes steps that are only relevant for cryptographic holder binding.

EAA Presentation solid line arrows represent technical functionality, dotted line arrows represent non-technical/user functionalityUserUser Device BrowserRelying Party .RP.Wallet Instance App .WI.UserUserUser Device BrowserUser Device BrowserRelying Party (RP)Relying Party (RP)Wallet Instance App (WI)Wallet Instance App (WI)(001)browse Relying Parties website(002)[TLS] HTTP GET <rp-website>(003)generate rp_openid4vp_state , rp_key_binding_nonce and encryption keys(rp_response_enc_prvk, rp_response_enc_pubk)(004)create OpenID4VP Authorization Request rp_openid4vp_request:(rp_client_id, rp_openid4vp_state, rp_dcql_query, rp_key_binding_nonce,rp_response_enc_pubk, rp_access_cert, rp_registration_cert)(005)sign rp_openid4vp_request with rp_access_cert_prvk(006)store rp_openid4vp_request for PAR under rp_request_urialt[Same-Device Flow](007)create rp_cookie_id and bind it to rp_openid4vp_request(008)[TLS] HTTP 200 <custom URL scheme linked rp_request_uri, Set-Cookie:rp_cookie_id>(009)initiate presentation of EAA(010)launch WI with custom URL scheme openid4vp://[Cross-Device Flow](011)[TLS] HTTP 200 <QR code encoding rp_request_uri>(012)scan QR code with the WI to initiate presentation of EAA(013)[TLS] HTTP GET <rp_request_uri>(014)[TLS] HTTP 200 <rp_openid4vp_request>(015)verify rp_openid4vp_request using rp_access_cert and rp_registration_cert,match rp_dcql_query against the claims registered in rp_registration_cert(016)check if stored credentials match rp_dcql_query(017)ask user for consent to present EAA to Relying Party(018)give consent(019)apply selective disclosure to ep_eaa_credential according to rp_dcql_queryalt[Cryptographic Holder Binding](020)generate wi_key_binding_data from rp_key_binding_nonce, rp_client_id andSD-JWT/mdoc-specific data(021)user authentication with Platform Authenticator to authorize signing withwi_eaa_device_prvk(022)sign(wi_key_binding_data, wi_eaa_device_prvk) using local HKS(023)assemble wi_eaa_presentation from selectively disclosed ep_eaa_credentialand, for cryptographic holder binding, the signed wi_key_binding_data(024)generate encryption keys (wi_response_enc_prvk, wi_response_enc_pubk)(025)encrypt wi_eaa_presentation using keys derived fromECDH(wi_response_enc_prvk, rp_response_enc_pubk)(026)create wi_openid4vp_response from wi_eaa_presentation andrp_openid4vp_stateopt[batch-issued EAA](027)delete presented one-time-use ep_eaa_credential and correspondingwi_eaa_device_prvk(028)[TLS] HTTP POST <Authorization Response (wi_openid4vp_response)>(029)match OpenID4VP session using rp_openid4vp_state and store encryptedwi_eaa_presentationalt[Same-Device Flow](030)create unique rp_redirect_uri and bind it to OpenID4VP session ofrp_openid4vp_state(031)[TLS] HTTP 200 <rp_redirect_uri>(032)launch browser with <rp_redirect_uri>(033)[TLS] HTTP GET <rp_redirect_uri>, Cookie: rp_cookie_id(034)verify that the provided rp_cookie_id matches to the session bound torp_redirect_uri[Cross-Device Flow](035)[TLS] HTTP 200(036)display success result, hint to check other device(037)[TLS] HTTP GET <poll status of OpenID4VP session>(038)decrypt wi_eaa_presentation using keys derived fromECDH(wi_response_enc_pubk, rp_response_enc_prvk)(039)verify wi_eaa_presentation using ep_eaa_auth_pubk andwi_eaa_device_pubk(040)extract selectively disclosed EAA attributes(041)[TLS] HTTP 200 <continue with authenticated user>

Detailed Description

No Description
001 The user browses to a Relying Party (RP) website. In the same-device flow, this is the browser on the same device as the Wallet Instance (WI), in the cross-device flow this is a browser on a second device.
002 The browser calls the Relying Party website, most likely using one or multiple HTTP GET requests. One of these requests triggers the Relying Party's server to generate the OpenID4VP Authorization Request as described in steps 003-006.
003 The RP generates random values for rp_openid4vp_state and rp_key_binding_nonce with sufficient entropy (at least 128 bits) and an ephemeral response encryption key pair (rp_response_enc_prvk, rp_response_enc_pubk) used for additional application-level encryption with response mode direct_post.jwt.
004 - 005 The RP creates the OpenID4VP Authorization Request rp_openid4vp_request as a JWT-Secured Authorization Request (JAR) using RFC9101 including:
  • The rp_key_binding_nonce encoded as nonce that acts as a challenge for the key-binding of the EAA presentation in step 020. It is provided regardless of the holder binding mode, as the RP does not necessarily know upfront which mode the requested EAA uses. For claims-based holder binding no key binding proof is created, so the rp_key_binding_nonce is not returned in the response and provides no replay protection.
  • The rp_openid4vp_state encoded as state that is responded back by the Wallet to let the RP match the session in step 029. For claims-based holder binding it is the only means of binding the response to the request.
  • The rp_response_enc_pubk encoded as client_metadata.jwks in the Authorization Request.
  • The rp_client_id encoded as client_id that acts as an identifier for the RP
  • The rp_access_cert encoded as x5c JOSE header (following ETSI TS 119 411-8) that provides the access certificate of the RP provided by the Relying Party Registrar, which is also being used as the signing certificate.
  • The rp_registration_cert encoded as verifier_info (following ETSI TS 119 475) that provides the registration certificate of the RP provided by the Relying Party Registrar, conveying the RP's identity, the purpose of the request and the RP's registered data request.
  • The rp_dcql_query encoded as dcql_query that describes the credentials requested by the RP, i.e. the EAA and its attributes and optionally further credentials such as a PID. To accept an EAA with claims-based holder binding, the RP sets require_cryptographic_holder_binding to false for that credential query; the default true would make the WI reject an EAA without a key binding proof. Setting it to false does not exclude key-bound EAAs, which is why the rp_key_binding_nonce is sent regardless of the holder binding mode.
  • the response_mode is always direct_post.jwt
  • The rp_response_uri encoded as response_uri that provides the POST endpoint for the response
The RP then signs the Authorization Request rp_openid4vp_request with rp_access_cert_prvk.
006 The RP stores rp_openid4vp_request as a Pushed Authorization Request according to RFC9126 under rp_request_uri.
007 - 010 Steps 007-010 only occur in the Same-Device Flow.
The RP creates an HTTP session ID cookie rp_cookie_id, binds it to rp_openid4vp_request and returns the rp_request_uri while setting the rp_cookie_id (using Set-Cookie HTTP headers). The request is embedded into the HTML code of the website, likely as a button using either the WI's app link or a custom URL scheme such as haip-vp:// for wallet invocation. The user initiates the EAA presentation on the RP's website, likely by pushing that button, and the WI is launched by the operating system, passing the rp_request_uri as a parameter within the app link/custom URL.
011 - 012 Steps 011-012 only occur in the Cross-Device Flow.
As the browser runs on a second device, the WI cannot be invoked by the operating system. The RP therefore renders the rp_request_uri as a QR code on its website, which the user scans with the WI to initiate the EAA presentation. No rp_cookie_id is created, as the response is not delivered through the browser session in this flow (see steps 035-037).
013 - 014 The WI requests the rp_request_uri as a Pushed Authorization Request using a HTTP GET call according to RFC9126. The RP responds with the rp_openid4vp_request as a Pushed Authorization Response that corresponds to the rp_request_uri.
015 The WI validates the fetched rp_openid4vp_request by:
  • verifying the JWS using the rp_access_cert_pubk from the rp_access_cert from the x5c header
  • verify the certificate chain against the root certificate of the Access Certificate Provider
  • verifying the Certificate Revocation List (CRL) of rp_access_cert
  • verifying the JWS of the rp_registration_cert
  • verifying the certificate chain against the root certificate of the Registration Certificate Provider
  • verifying the Token Status List of the rp_registration_cert
  • matching the requested rp_dcql_query against the claims parameter of the rp_registration_cert and rejecting the request if it asks for attributes beyond the registered ones, thereby protecting the user against over-asking
  • extracting the RP's identity and purpose from the rp_registration_cert to be displayed to the user in step 017 - 018.
016 The WI matches the available, stored credentials (i.e. the requested EAA and optionally additional credentials such as a PID) against the RP's requested credentials from rp_dcql_query. The following situations may appear:
  • the available credentials do not match the query and the WI has no information to get the requested credential(s) ad-hoc. The WI shows an error and aborts the flow.
  • the available credentials do not match the query but the WI has information how to get the requested credential(s) ad-hoc, e.g. through EAA issuance of a credential from the Credential Catalogue or through PID issuance. The WI halts the flow and offers the user to issue the missing credential(s).
  • the available credentials have exactly 1 match with the query. The WI continues for the user's consent
  • the available credentials have more than 1 match with the query. The WI prepares the options to be displayed to and chosen by the user and continues for the user's consent.
The WI selects one ep_eaa_credential and, for cryptographic holder binding, the corresponding wi_eaa_device_prvk for further processing. If the EAA was issued as a batch, the WI selects an unused credential instance of the batch; if the EAA Provider does not support batch issuance, the WI holds a single instance that is presented repeatedly and is therefore linkable across Relying Parties.
017 - 018 The WI presents a consent screen to the user, displaying the identity of the Relying Party, the requested attributes, the purpose, and stored display information about the ep_eaa_credential:
  • information about the RP from the rp_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)
    • the intended use of the RP for requesting this data (purpose)
  • display information of the EAA stored during EAA issuance from the ep_meta_data (credential_configurations_supported.credential_metadata.display)
    • the EAA name (name)
    • optional display information (logo, background_color, background_image)
  • the requested, selectively disclosed attributes of the EAA from the rp_dcql_query
    • language-specific claim names from the ep_meta_data (credential_configurations_supported.credential_metadata.claims)
    • claim values from the ep_eaa_credential
Based on this information, the WI asks the user for consent to present its EAA (or parts of it, and potentially other credentials) to the Relying Party. If there is more than 1 match to the rp_dcql_query, the WI offers the user to choose between the options. Unlike the PID presentation, no user_rwsca_pin is collected here, as no RWSCA operation is involved.
019 The WI prepares the EAA presentation and applies the selective disclosure to ep_eaa_credential according to rp_dcql_query:
  • for mdoc: by removing unnecessary NameSpaceBytes
  • for SD-JWT: by removing unnecessary Disclosures
020 - 022 Steps 020-022 only occur for Cryptographic Holder Binding. For Claims-based Holder Binding this branch is skipped entirely, as shown by the alternative in the sequence diagram: no wi_key_binding_data is generated, no user authentication with the Platform Authenticator is requested and no signature is created, since the EAA is instead bound to the user via the identifying claims contained in the credential itself.
The WI generates the wi_key_binding_data:
  • for mdoc: by calculating the SessionTranscript using the rp_client_id, rp_key_binding_nonce, rp_response_enc_pubk and the RP's response_uri and generating the deviceAuth structure
  • for SD-JWT: by generating the KB-JWT payload using rp_client_id, rp_key_binding_nonce and the hash of ep_eaa_credential and the disclosures
The wi_eaa_device_prvk was generated during EAA issuance in the local HKS, configured so that it can only be used for signing while the Platform Authenticator is set up on the device. The underlying keystore enforces this user authentication at the point the key is used for signing, so the WI asks the user to authenticate immediately before signing the wi_key_binding_data with the wi_eaa_device_prvk. As the key is managed locally, the WI signs the key binding itself instead of delegating the operation to the RWSCA as in the PID presentation.
023 The WI assembles the EAA presentation wi_eaa_presentation from the selectively disclosed ep_eaa_credential and, for cryptographic holder binding, the signed wi_key_binding_data, and embeds it into the vp_token structure:
  • for mdoc: using ep_eaa_credential as issuerAuth and using wi_key_binding_data and its signature to assemble deviceSigned
  • for SD-JWT with cryptographic holder binding: using ep_eaa_credential as Issuer-signed SD-JWT, selective Disclosures and using wi_key_binding_data and its signature to assemble the KB-JWT
  • for SD-JWT with claims-based holder binding: using ep_eaa_credential as Issuer-signed SD-JWT and selective Disclosures, without a KB-JWT
If the RP requested further credentials in the rp_dcql_query, the vp_token contains one entry per requested credential.
024 - 025 The WI generates an ephemeral response encryption key pair (wi_response_enc_prvk, wi_response_enc_pubk) used for additional application-level encryption with response mode direct_post.jwt. The WI then encrypts wi_eaa_presentation using keys derived from Elliptic Curve Diffie-Hellman using wi_response_enc_prvk and rp_response_enc_pubk using JWE.
026 The WI creates the wi_openid4vp_response from the encrypted wi_eaa_presentation and the unencrypted rp_openid4vp_state.
027 If the EAA was issued as a batch, the WI deletes the presented ep_eaa_credential and the corresponding wi_eaa_device_prvk, as the WI follows a one-time-use policy to enable unlinkability. If the EAA Provider does not support batch issuance, the single credential instance is retained and may be presented again.
028 The WI sends the OpenID4VP Authorization Response wi_openid4vp_response as a HTTP POST request to the RP's rp_response_uri.
029 The RP matches the OpenID4VP session using rp_openid4vp_state and stores the encrypted wi_eaa_presentation without validating it yet.
030 - 034 Steps 030-034 only occur in the Same-Device Flow.
The RP must perform a redirect to the WI's browser first to prevent session fixation attacks. It therefore creates a unique rp_redirect_uri, binds it to the OpenID4VP session of rp_openid4vp_state and responds to the WI with a HTTP 200 containing the rp_redirect_uri. The WI launches the user device browser with rp_redirect_uri and the browser then makes the HTTP GET request to rp_redirect_uri. As the browser has been in this session before, it provides the rp_cookie_id, so that the RP can match the browser session and securely map it to the OpenID4VP session bound to rp_redirect_uri.
035 - 037 Steps 035-037 only occur in the Cross-Device Flow.
The RP acknowledges the Authorization Response and the WI displays the result of the presentation to the user. As the browser runs on a second device, the response cannot be delivered through the browser session and the RP does not return an rp_redirect_uri. The RP's website instead learns the outcome by polling the status of the OpenID4VP session, e.g. through a periodic request or server-sent events. Consequently, the rp_cookie_id-based binding of the browser session to the OpenID4VP session used in the same-device flow does not apply here, so the RP cannot rely on it to protect against session fixation and has to bind the session by other means, e.g. by displaying a transaction identifier alongside the QR code.
038 The RP decrypts the stored wi_eaa_presentation from step 029 using keys derived from Elliptic Curve Diffie-Hellman using wi_response_enc_pubk and rp_response_enc_prvk, equivalent to what the WI did in step 025.
039 - 040 The RP verifies the contents of the wi_eaa_presentation using ep_eaa_auth_pubk and, for cryptographic holder binding, the wi_eaa_device_pubk contained in the credential, and extracts the selectively disclosed EAA attributes: For claims-based holder binding, there is no key binding proof to verify and the RP instead evaluates the identifying claims of the EAA, e.g. by comparing them with the attributes of another credential presented alongside it. The RP verifies that the rp_openid4vp_state of its own session was returned (step 029) and accepts the residual risk replay attacks (which may be fine for their use case). The RP should not permanently store the signed ep_eaa_credential, but only the unsigned EAA attributes.
041 The RP responds to the browser session and continues with the authenticated user.

Batch Credential Refresh

If the EAA Provider supports batch issuance, the WI consumes exactly one ep_eaa_credential per EAA presentation (see step 027) and eventually has to refresh the batch through an EAA re-issuance using the ep_refresh_token. The conditions and thresholds for this refresh depend on that flow.

tbd