Skip to content

PID Presentation

This flow describes the PID presentation process as introduced here in the blueprint. The PID presentation flow uses the standards following the High-Assurance Interoperability Profile (HAIP) for OpenID4VP as defined in the blueprint:

The current flow allows both Wallets and Verifiers to only use same-device flows, as the cross-device using OpenID4VP redirect-based flows does not fulfil LoA high requirements. In future iterations, cross-device PID presentations may be supported.

Data Flow

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

Sequence Diagram

PID presentationPID presentationUserUser Device BrowserRelying Party .RP.Wallet Instance App .WI.Remote WSCD .RWSCD.UserUserUser Device BrowserUser Device BrowserRelying Party (RP)Relying Party (RP)Wallet Instance App (WI)Wallet Instance App (WI)Remote WSCD (RWSCD)Remote WSCD (RWSCD)(001)browse Relying Partieswebsite(002)[TLS] HTTP GET <rp-website>(003)generate rp_openid4vp_state ,rp_key_binding_nonce andencryption keys(rp_response_enc_prvk,rp_response_enc_pubk)(004)create OpenID4VPAuthorization Requestrp_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_requestwith rp_access_cert_priv(006)store rp_openid4vp_requestfor PAR under rp_request_uri(007)create rp_cookie_id and bindit to rp_openid4vp_request(008)[TLS] HTTP 200 <custom URLscheme linked rp_request_uri,Set-Cookie: rp_cookie_id>(009)initiate presentation of PID(010)launch WI with custom URLscheme openid4vp://(011)[TLS] HTTP GET<rp_request_uri>(012)[TLS] HTTP 200<rp_openid4vp_request>(013)verify rp_openid4vp_requestusing rp_access_cert andrp_registration_cert(014)check if stored credentialsmatch rp_dcql_query(015)apply selective disclosure topp_pid_credential accordingto rp_dcql_query(016)generate wi_key_binding_datafrom rp_key_binding_nonce,rp_client_id andSD-JWT/mdoc-specific data(017)generatewi_key_binding_data_hashfrom wi_key_binding_data(018)ask user for consent topresent PID to Relying Party(019)enter user_rwscd_pin(020)[TLS] request Remote WSCDSign operation forwi_key_binding_data_hashand rwscd_key_id(021)sign(wi_key_binding_data_hash,rwscd_pid_device_prvk)(022)[TLS] respond Sign operationrwscd_key_binding_signature(023)assemble wi_pid_presentationfrom selectively disclosedpp_pid_credential,wi_key_binding_data andrwscd_key_binding_signature(024)generate encryption keys(wi_response_enc_prvk,wi_response_enc_pubk)(025)encrypt wi_pid_presentationusing keys derived fromECDH(wi_response_enc_prvk,rp_response_enc_pubk)(026)createwi_openid4vp_response fromwi_pid_presentation andrp_openid4vp_state(027)delete presentedone-time-usepp_pid_credential(028)[TLS] HTTP POST<Authorization Response(wi_openid4vp_response)>(029)match OpenID4VP sessionusing rp_openid4vp_state andstore encryptedwi_pid_presentation(030)create unique rp_redirect_uriand bind it to OpenID4VPsession of rp_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 providedrp_cookie_id matches to thesession bound torp_redirect_uri(035)decrypt wi_pid_presentationusing keys derived fromECDH(wi_response_enc_pubk,rp_response_enc_prvk)(036)verify wi_pid_presentationusing pp_pid_auth_pubk andrwscd_pid_device_pubk(037)extract selectively disclosedes_eid_data(038)[TLS] HTTP 200 <continuewith authenticated user>

Detailed Description

No Description
001 The user browses to a Relying Party (RP) website using the browser on its Wallet Instance (WI).
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-008.
003 The RP generates random values for rp_openid4vp_state and rp_key_binding_nonce with sufficient entropy 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 PID presentation in step 019.
  • The rp_openid4vp_state encoded as state that is responded back by the Wallet to let the RP match the session in step 030.
  • 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 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 that provides the registration certificate of the RP provided by the Relying Party Registrar.
  • The rp_dcql_query encoded as dcql_query that describes the credentials requested by the RP, i.e. the PID and its attributes
  • 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 sign the Authorization Request rp_openid4vp_request with rp_access_cert_priv.
006 The RP stores rp_openid4vp_request as a Pushed Authorization Request according to RFC9126 under rp_request_uri.
007 The RP creates an HTTP session ID cookie rp_cookie_id and binds it to rp_openid4vp_request.
008 The RP returns the rp_request_uri and sets 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.
009 - 010 The user initiates the PID presentation on the RP's website, likely by pushing a button. The WI is launched by the operating system, passing the rp_request_uri as a parameter within the app link/custom URL.
011 - 012 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.
013 The WI validates the fetched rp_openid4vp_request by:
  • verifying the JWS using the the rp_access_cert from the x5c header and matching the certificate chain to its internal Relying Party Registrar trust anchor
  • verifying the JWS of the rp_registration_cert and that it matches to the rp_access_cert
  • verifying that the intended use of the rp_access_cert matches the requested rp_dcql_query.
For details, please see Wallet-Relying Party Authentication in the blueprint.
014 The WI checks that the stored credentials (i.e. the PID and optionally additional credentials) match the requested credentials from rp_dcql_query. If the requested PID is available, the WI selects one pp_pid_credential and the corresponding rwscd_key_id from the batch for further processing. If the PID or other requested credentials are not available, the WI may offer the user an inline issuance to fulfil the presentation request.
015 The WI prepares the PID presentation and applies the selective disclosure to pp_pid_credential according to rp_dcql_query:
  • for mdoc: by removing unnecessary NameSpaceBytes
  • for SD-JWT: by removing unnecessary Disclosures
This is the first preparation step that matches flow of the Remote WSCD Sign operation.
016 The WI generates 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 KB-JWT payload using rp_client_id, rp_key_binding_nonce and the hash of pp_pid_credential and the disclosures
017 The WI generates the hash wi_key_binding_data_hash from the wi_key_binding_data, as only the hash is passed to the Remote WSCD for signing.
018 - 019 The WI displays the relevant information from rp_openid4vp_request to the user:
  • the identity of the RP from rp_access_cert,
  • the intended use from rp_registration_cert,
  • the data to be presented by applying rp_dcql_query to pp_pid_credential.
The WI then asks the user for consent to present its PID (or parts of it) to the Relying Party. The user consents by entering his user_rwscd_pin required to authorize the signing of the PID presentation with keys secured by the Remote WSCD.
020 - 022 The WI requests the Remote WSCD Sign operation authenticating with two factor authentication that was established during Remote WSCD registration to sign wi_key_binding_data_hash with the rwscd_pid_device_privk belonging to rwscd_key_id associated to the particular pp_pid_credential. The RWSCD ensures, based on the two factor authentication, that only the account which has created the wscd_pid_device_prvk is allowed to use this key for a single signing operation. The RWSCD then signs the hashed input data wi_key_binding_data_hash ( without knowing the payload) of wi_key_binding_data using rwscd_pid_device_prvk and responds the signature rwscd_key_binding_signature to the WI. If the presentation process was finished successfully and no further re-issuance is required, the cached wi_rwscd_pin_prvk should be flushed, as explained in the PIN caching section.
023 The WI assembles the PID presentation wi_pid_presentation from pp_pid_credential, wi_key_binding_data and rwscd_key_binding_signature and embeds it into the vp_token structure:
  • for mdoc: using pp_pid_credential as issuerAuth and using wi_key_binding_data and rwscd_key_binding_signature to assemble deviceSigned
  • for SD-JWT: using pp_pid_credential as Issuer-signed SD-JWT, selective Disclosures and using wi_key_binding_data and rwscd_key_binding_signature to assemble KB-JWT.
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_pid_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_pid_presentation and the unencrypted rp_openid4vp_state.
027 The WI deletes the presented pp_pid_credential, as the WI follows a one-time-use policy to enable unlinkability.
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 store the encrypted wi_pid_presentation without validating it yet. The RP must perform a redirect to the WI's browser first to prevent session fixation attacks.
030 - 031 The RP therefore creates a unique rp_redirect_uri and binds it to the OpenID4VP session of rp_openid4vp_state and responds to the WI with a HTTP 200 containing the rp_redirect_uri.
032 - 033 The WI launches the user device browser with rp_redirect_uri. 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.
034 The RP matches the browser session using the provided rp_cookie_id and can securely map it to the OpenID4VP session bound to rp_redirect_uri.
035 The RP decrypts the stored wi_openid4vp_response from Step 029 using keys derived from Elliptic Curve Diffie-Hellman using wi_response_enc_pubk and rp_response_enc_prvk, equivalent to what WI did in Step 025.
036 - 037 The RP verifies the contents of the wi_pid_presentation using pp_pid_auth_pubk and rwscd_pid_device_pubk and extracts the selectively disclosed es_eid_data:The RP should not permanently store the signed pp_pid_credential, but only the unsigned PID attributes.
038 The RP responds to the WI in the browser session.