PID/(Q)EAA Issuance¶
This section describes the PID and (Q)EAAs issuance flow with an high level of security. The relevant entities and interfaces involved in the issuance flow are:
Wallet Provider,
Wallet Solution,
Wallet Instance,
PID Provider,
National Identity Provider,
(Q)EAA Provider.
PID/(Q)EAA Providers are composed of:
Credential Issuer Component: based on the "OpenID for Verifiable Credential Issuance" specification [OpenID4VCI] to release the PID/(Q)EAA.
Relying Party Component: The component to authenticate the User. PID Providers authenticate users with the national Digital Identity Providers, based on OpenID Connect Core 1.0 or SAML2 while (Q)EAA Providers authenticate users with the PID.
The (Q)EAA Provider acts as a Verifier by sending a presentation request to the Wallet Instance, according to [OpenID4VP]. The Wallet Instance MUST have a valid PID, obtained in a previous time, to get authenticated with the (Q)EAA Provider.
High-Level PID flow¶
The Fig. 2 shows a general architecture and highlights the main operations involved in the issuance of a PID.
Below the description of the steps represented in the previous picture:
Wallet Instance Setup: the first time the Wallet Instance is started a preliminary setup phase is carried out. It consists of the release of the Wallet Attestation issued by Wallet Attestation Service asserting the genuineness and the compliance of the Wallet Instance with the shared trust framework. The Wallet Attestation binds the public key provided by the Wallet Instance, related to one of the private keys generated by the Wallet Instance.
PID/(Q)EAA Provider Discovery: the Wallet Instance discovers the trusted Digital Credential Issuers using the Federation API (e.g.: using the Subordinate Listing Endpoint of the Trust Anchor and its Intermediates), inspecting the Credential Issuer metadata and Trust Marks for filtering the PID Provider.
PID Provider Metadata: the Wallet Instance establishes the trust to the PID Provider according to the Trust Model and obtains the Metadata that discloses the formats of the PID, the algorithms supported, and any other parameter required for interoperability needs.
PID Request: using the Authorization Code Flow defined in [OpenID4VCI] the Wallet Instance requests the PID to the PID Provider.
User Authentication: the PID Provider authenticates the User with LoA High, acting as an Identity and Access Management Proxy to the National eID system.
PID Issuance: the User is authenticated with LoA High and the PID Provider releases a PID bound to the key material held by the requesting Wallet Instance.
In the following sections the steps from 1 to 5 are further expanded into more technical details.
High-Level (Q)EAA flow¶
The Fig. 3 shows a general architecture and highlights the main operations involved in the issuance of a (Q)EAA, following the assumptions listed below:
the User has a valid PID stored in their own Wallet Instance;
the (Q)EAA requires a high security implementation profile.
Below the description of the most relevant operations involved in the (Q)EAA issuance:
Discovery of the trusted (Q)EAA Provider: the Wallet Instance obtains the list of the trusted (Q)EAA Provider using the Federation API (e.g.: using the Subordinate Listing Endpoint of the Trust Anchor and its Intermediates), then inspects the metadata and Trust Mark looking for the Digital Credential capabilities of each (Q)EAA Provider.
(Q)EAA Provider Metadata: the Wallet Instance establishes the trust to the (Q)EAA Provider according to the Trust Model, obtaining the Metadata that discloses the formats of the (Q)EAA, the algorithms supported, and any other parameter required for interoperability needs.
(Q)EAA Request: using the Authorization Code Flow , defined in [OpenID4VCI], the Wallet Instance requests a (Q)EAA to the (Q)EAA Provider.
User Authentication: the (Q)EAA Provider, acting as a Verifier (Relying Party), authenticates the User evaluating the presentation of the PID.
(Q)EAA Issuance: the User is authenticated with a valid PID and the (Q)EAA Provider releases a (Q)EAA bound to the key material held by the requesting Wallet Instance.
Low-Level Issuance Flow¶
The PID/(Q)EAA Issuance flow is based on [OpenID4VCI] and the following main reference standards/specifications MUST be supported on top of OpenID4VCI:
The OAuth 2.0 Authorization Framework [RFC 6749], as recommended in Section 3 of [OpenID4VCI].
Pushed Authorization Requests (PAR) [RFC 9126], as recommended in Section 5 of [OpenID4VCI].
Proof Key for Code Exchange (PKCE) [RFC 7636], as recommended in Section 5 of [OpenID4VCI].
JWT Authorization Requests (JAR) [RFC 9101].
JWT Authorization Response Modes (JARM) [OAUTH-V2-JARM-04].
Rich Authorization Requests (RAR) [RFC 9396].
OAuth 2.0 Attestation-Based Client Authentication [OAUTH-ATTESTATION-CLIENT-AUTH].
OpenID Federation 1.0 [OID-FED].
The PID/(Q)EAA Provider MUST use OAuth 2.0 Authorization Server based on RFC 6749 to authorize the User to obtain a Credential. PID/(Q)EAA Providers MUST support
Authorization Code Flow: The PID/(Q)EAA Provider requires User authentication and consent at the Authorization Endpoint before collecting User information to create and provide a Credential.
Wallet Initiated Flow: The request from the Wallet Instance is sent to the PID/(Q)EAA Provider without any input from the latter.
Same-device Issuance flow: The User receives the Credential on the same device that initiated the flow.
Immediate Issuance flow: The PID/(Q)EAA Provider issues the Credential directly in response to the Credential Request.
Deferred Issuance flow: The PID/(Q)EAA Provider may require time to issue the requested Digital Credential, due to the Authentic Sources data provisioning rules, and allows the Wallet to retrieve the requested Credential in the future.
Steps 1-4 (Discovery): The User, using the Wallet Instance, selects the PID/(Q)EAA Provider from those listed in the list of trustworthy entities. The Wallet Instance then processes the Metadata for the selected PID/(Q)EAA Provider as defined in the Trust Model section of this specification.
Note
Federation Check: The Wallet Instance must verify whether the PID/(Q)EAA Provider is a member of the Federation, obtaining its protocol specific Metadata. A non-normative example of a response from the endpoint .well-known/openid-federation with the Entity Configuration and the Metadata of the PID/(Q)EAA Provider is represented within the section Entity Configuration of PID/(Q)EAA Providers.
Steps 5-6 (PAR Request): The Wallet Instance:
creates a fresh PKCE code verifier, Wallet Attestation Proof of Possession, and
state
parameter for the Pushed Authorization Request.provides to the PID/(Q)EAA Provider PAR endpoint the parameters previously listed above, using the
request
parameter (hereafter Request Object) according to RFC 9126 Section 3 to prevent Request URI swapping attack. The Pushed Authorization Request enables client authentication prior to any user interaction. This step allows for the early rejection of illegitimate requests, effectively preventing spoofing attacks, tampering, and improper use of authorization requests.MUST create the
code_verifier
with enough entropy random string using the unreserved characters with a minimum length of 43 characters and a maximum length of 128 characters, making it impractical for an attacker to guess its value. The value MUST be generated following the recommendation in Section 4.1 of RFC 7636.signs this request using the private key that is created during the setup phase to obtain the Wallet Attestation. The related public key that is attested by the Wallet Provider is provided within the Wallet Attestation
cnf
claim.MUST use the
OAuth-Client-Attestation
andOAuth-Client-Attestation-PoP
parameters according to OAuth 2.0 Attestation-based Client Authentication [OAUTH-ATTESTATION-CLIENT-AUTH], since in this flow the Pushed Authorization Endpoint is a protected endpoint.specifies the types of the requested credentials using the
authorization_details
[RAR RFC 9396] parameter and or scope parameter.
The PID/(Q)EAA Provider performs the following checks upon the receipt of the PAR request:
It MUST validate the signature of the Request Object using the algorithm specified in the
alg
header parameter (RFC 9126, RFC 9101) and the public key retrieved from the Wallet Attestation (cnf.jwk
) referenced in the Request Object, using thekid
JWS header parameter.It MUST check that the used algorithm for signing the request in the
alg
header is one of the listed within the Section Cryptographic Algorithms.It MUST check that the
client_id
in the request body of the PAR request matches theclient_id
claim included in the Request Object.It MUST check that the
iss
claim in the Request Object matches theclient_id
claim in the Request Object (RFC 9126, RFC 9101).It MUST check that the
aud
claim in the Request Object is equal to the identifier of the PID/(Q)EAA Provider (RFC 9126, RFC 9101).It MUST reject the PAR request, if it contains the
request_uri
parameter (RFC 9126).It MUST check that the Request Object contains all the mandatory parameters which values are validated according to Table of the HTTP parameters [derived from RFC 9126].
It MUST check that the Request Object is not expired, checking the
exp
claim.It MUST check that the Request Object was issued in a previous time than the value exposed in the
iat
claim. It SHOULD reject the request if theiat
claim is far from the current time (RFC 9126) of more than 5 minutes.It MUST check that the
jti
claim in the Request Object has not been used before by the Wallet Instance identified by theclient_id
. This allows the PID/(Q)EAA Provider to mitigate replay attacks (RFC 7519).It MUST validate the
OAuth-Client-Attestation-PoP
parameter based on Section 4 of [OAUTH-ATTESTATION-CLIENT-AUTH].
Below a non-normative example of the PAR.
POST /as/par HTTP/1.1
Host: eaa-provider.example.org
Content-Type: application/x-www-form-urlencoded
OAuth-Client-Attestation: eyJhbGciOiJFUzI1NiIsImtpZCI6IkVVRzBFdlRWaUk1RU5aQXdVQ0lVTWdQQVk4X1VISW5fMkhIWlMxN3RfQzAifQ.eyJpc3MiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCAiYXVkIjogImh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLCAibmJmIjogMTMwMDgxNTc4MCwgImV4cCI6IDEzMDA4MTkzODB9._v3bjJelKI0TNpbc4ysS7yJupwSZzMPQ0ZQ9N5zj8XGQ_T3NN9bghUyVzegR60xokqBnqmMS4iYgPOL7ekEspw
OAuth-Client-Attestation-PoP: eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiIgaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCJhdWQiOiIgaHR0cHM6Ly9hcy5leGFtcGxlLmNvbSIsImp0aSI6IjVlZmY5YzFiLWVkMGQtNDdlOC1hNTUzLWY3NGRmMWJiZWVkZCIsImlhdCI6MTcyMjI0OTQ0NywiZXhwIjoxNzIyMjQ5NzQ3fQ.aZpx7u7R-W8q7fJh9BEaRf8LM7RQRxAVc-okalAVqxHWqUMh3ehYukMLaCsiDQ33pyS41Y5PEsZ3HXwAXQ3nMg
&client_id=$thumprint-of-the-jwk-in-the-cnf-wallet-attestation$
&request=$SIGNED-JWT
Below an non-normative example of the Wallet Attestation Proof of Possession (WIA-PoP) header and body:
{
"typ": "jwt-client-attestation-pop",
"alg": "ES256",
"kid": "47b982369791d08003a7283f059cb0d1"
}
{
"iss": "47b982369791d08003a7283f059cb0d1",
"aud": "https://eaa-provider.example.org",
"iat": 1715842560,
"exp": 1778914560,
"jti": "f8555ceb-c65c-4025-9378-b6672b6149af"
}
Below an non-normative example of the signed Request Object without encoding and signature applied:
{
"typ": "jwt",
"alg": "ES256",
"kid": "b01b8208d9e6cc834d87dc356ab50170"
}
{
"jti": "f8555ceb-c65c-4025-9378-b6672b6149af",
"aud": "https://eaa-provider.example.org",
"iat": 1715842560,
"exp": 1715842860,
"response_type": "code",
"response_mode": "form_post.jwt",
"client_id": "47b982369791d08003a7283f059cb0d1",
"iss": "47b982369791d08003a7283f059cb0d1",
"state": "fyZiOL9Lf2CeKuNT2JzxiLRDink0uPcd",
"code_challenge": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM",
"code_challenge_method": "S256",
"scope": "EuropeanDisabilityCard",
"authorization_details": [
{
"type": "openid_credential",
"credential_configuration_id": "EuropeanDisabilityCard"
}
],
"redirect_uri": "https://client.example.com/cb"
}
Note
Federation Check: The PID/(Q)EAA Provider MUST check that the Wallet Provider is part of the federation.
Note
The PID/(Q)EAA Provider MUST validate the signature of the the Wallet Attestation and that it is not expired.
Step 7 (PAR Response): The PID/(Q)EAA Provider provides a one-time use request_uri
value. The issued request_uri
value must be bound to the client identifier (client_id
) that was provided in the Request Object.
Note
The entropy of the request_uri
MUST be sufficiently large. The adequate shortness of the validity and the entropy of the request_uri
depends on the risk calculation based on the value of the resource being protected. The validity time SHOULD be less than a minute, and the request_uri
MUST include a cryptographic random value of 128 bits or more (RFC 9101). The entire request_uri
SHOULD NOT exceed 512 ASCII characters due to the following two main reasons (RFC 9101):
Many phones on the market still do not accept large payloads. The restriction is typically either 512 or 1024 ASCII characters.
On a slow connection such as a 2G mobile connection, a large URL would cause a slow response; therefore, the use of such is not advisable from the user-experience point of view.
The PID/(Q)EAA Provider returns the issued request_uri
to the Wallet Instance. A non-normative example of the response is shown below.
HTTP/1.1 201 Created
Cache-Control: no-cache, no-store
Content-Type: application/json
{
"request_uri": "urn:ietf:params:oauth:request_uri:bwc4JK-ESC0w8acc191e-Y1LTC2",
"expires_in": 60
}
Steps 8-9 (Authorization Request): The Wallet Instance sends an authorization request to the PID/(Q)EAA Provider Authorization Endpoint. Since parts of this Authorization Request content, e.g., the code_challenge
parameter value, are unique to a particular Authorization Request, the Wallet Instance MUST only use a request_uri
value once (RFC 9126); The PID/(Q)EAA Provider performs the following checks upon the receipt of the Authorization Request:
It MUST treat
request_uri
values as one-time use and MUST reject an expired request. However, it MAY allow for duplicate requests due to a user reloading/refreshing their user-agent (derived from RFC 9126).It MUST identify the request as a result of the submitted PAR (derived from RFC 9126).
It MUST reject all the Authorization Requests that do not contain the
request_uri
parameter as the PAR is the only way to pass the Authorization Request from the Wallet Instance (derived from RFC 9126).
GET /authorize?client_id=$thumprint-of-the-jwk-in-the-cnf-wallet-attestation$&request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3Abwc4JK-ESC0w8acc191e-Y1LTC2 HTTP/1.1
Host: eaa-provider.example.org
Note
User Authentication and Consent: The PID Provider performs the User authentication based on the requirements of eIDAS LoA High by means of national notified eIDAS scheme and requires the User consent for the PID issuance. The (Q)EAA Provider performs the User authentication requesting a valid PID to the Wallet Instance. The (Q)EAA Provider MUST use [OpenID4VP] to dynamically request the presentation of the PID. From a protocol perspective, the (Q)EAA Provider acts as a Relying Party, providing the presentation request to the Wallet Instance. The Wallet Instance MUST have a valid PID obtained prior to start the transaction with the (Q)EAA Provider.
Steps 10-11 (Authorization Response): The PID/(Q)EAA Provider sends an authorization code
together with state
and iss
parameters to the Wallet Instance. The Wallet Instance performs the following checks on the Authorization Response:
It MUST check the Authorization Response contains all the defined parameters according to Table of the HTTP Response parameters.
It MUST check the returned value by the PID/(Q)EAA Provider for
state
parameter is equal to the value sent by Wallet Instance in the Request Object (RFC 6749).It MUST check that the URL of PID/(Q)EAA Provider in
iss
parameter is equal to the URL identifier of intended PID/(Q)EAA Provider that the Wallet Instance start the communication with (RFC 9027).
Note
The Wallet Instance redirect URI is a universal or app link registered with the local operating system, so this latter will resolve it and pass the response to the Wallet Instance.
HTTP/1.1 302 Found
Location: https://start.wallet.example.org?code=SplxlOBeZQQYbYS6WxSbIA&state=fyZiOL9Lf2CeKuNT2JzxiLRDink0uPcd&iss=https%3A%2F%2Feaa-provider.example.org
Steps 12-13 (DPoP Proof for Token Endpoint): The Wallet Instance MUST create a new key pair for the DPoP and a fresh DPoP Proof JWT following the instruction provided in the Section 4 of (RFC 9449) for the token request to the PID/(Q)EAA Provider. The DPoP Proof JWT is signed using the private key for DPoP created by Wallet Instance for this scope. DPoP binds the Access Token to a certain Wallet Instance (RFC 9449) and mitigates the misuse of leaked or stolen Access Tokens at the Credential Endpoint.
Step 14 (Token Request): The Wallet Instance sends a token request to the PID/(Q)EAA Provider Token Endpoint with a DPoP Proof JWT and the parameters: code
, code_verifier
, and OAuth 2.0 Attestation based Client Authentication (OAuth-Client-Attestation
and OAuth-Client-Attestation-PoP
).
The OAuth-Client-Attestation
is signed using the private key that is created during the setup phase to obtain the Wallet Attestation. The related public key that is attested by the Wallet Provider is provided within the Wallet Attestation (cnf
claim). The PID/(Q)EAA Provider performs the following checks on the Token Request:
It MUST ensure that the Authorization
code
is issued to the authenticated Wallet Instance (RFC 6749) and was not replied.It MUST ensure the Authorization
code
is valid and has not been previously used (RFC 6749).It MUST ensure the
redirect_uri
matches the value included in the previous Request Object (see Section 3.1.3.1. of [OIDC]).It MUST validate the DPoP Proof JWT, according to (RFC 9449) Section 4.3.
POST /token HTTP/1.1
Host: eaa-provider.example.org
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik
OAuth-Client-Attestation: eyJhbGciOiJFUzI1NiIsImtpZCI6IkVVRzBFdlRWaUk1RU5aQXdVQ0lVTWdQQVk4X1VISW5fMkhIWlMxN3RfQzAifQ.eyJpc3MiOiAiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCAiYXVkIjogImh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLCAibmJmIjogMTMwMDgxNTc4MCwgImV4cCI6IDEzMDA4MTkzODB9._v3bjJelKI0TNpbc4ysS7yJupwSZzMPQ0ZQ9N5zj8XGQ_T3NN9bghUyVzegR60xokqBnqmMS4iYgPOL7ekEspw
OAuth-Client-Attestation-PoP: eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiIgaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCJhdWQiOiIgaHR0cHM6Ly9hcy5leGFtcGxlLmNvbSIsImp0aSI6IjVlZmY5YzFiLWVkMGQtNDdlOC1hNTUzLWY3NGRmMWJiZWVkZCIsImlhdCI6MTcyMjI0OTQ0NywiZXhwIjoxNzIyMjQ5NzQ3fQ.aZpx7u7R-W8q7fJh9BEaRf8LM7RQRxAVc-okalAVqxHWqUMh3ehYukMLaCsiDQ33pyS41Y5PEsZ3HXwAXQ3nMg
grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
&redirect_uri=https://start.wallet.example.org/cb
Step 15 (Token Response): The PID/(Q)EAA Provider validates the request, if successful an Access Token (bound to the DPoP key) and a fresh c_nonce are provided by the Issuer to the Wallet Instance. The parameter c_nonce is a string value, which MUST be unpredictable and is used later by the Wallet Instance in Step 18 to create the proof of possession of the key (proof claim) and it is the primary countermeasure against key proof replay attack. Note that, the received c_nonce value can be used to create the proof as long as the Issuer provides the Wallet Instance with a new c_nonce value.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token": "eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImM5NTBjMGU2ZmRlYjVkZTUwYTUwMDk2YjI0N2FmMDNjIn0.eyJpc3MiOiJodHRwczovL2VhYS1wcm92aWRlci53YWxsZXQuaXB6cy5pdCIsInN1YiI6ImQ0ZTBiYjM4N2FhMjU1NmZmMzA2OTI1ZmRmYjlhNzY1IiwiYXVkIjoiaHR0cHM6Ly9lYWEtcHJvdmlkZXIud2FsbGV0LmlwenMuaXQvY3JlZGVudGlhbCIsImlhdCI6MTcxNTg0MjU2MCwiZXhwIjoxNzc4OTE0NTYwLCJqdGkiOiJmOTY1NWNlYi1jNjVjLTQwMjUtOTM3OC1iNjY3MmI2MTQ5YmciLCJjbGllbnRfaWQiOiI0N2I5ODIzNjk3OTFkMDgwMDNhNzI4M2YwNTljYjBkMSIsImNuZiI6eyJqa3QiOiI5NTE1NzRhZWUxYmI3OTA3YWUxZWMzMTA5ZGIyYjIyNSJ9fQ.3ZfQN6KuNtJHjbGiYxHYqXIe0WrFIqYXNUio2a0bFy4eWystd7ZNCcmfoRojmmHQwccjNADqBKG7beYwbQ4jPg",
"token_type": "DPoP",
"expires_in": 3600,
"c_nonce": "ts_EtUQs0ieiIS1NYNBHEQSoy3ct4gpy-4FZKwHilkY",
"c_nonce_expires_in": 86400,
"authorization_details": [
{
"type": "openid_credential",
"credential_configuration_id": "DisabilityCard"
}
]
}
The non-normative example of the DPoP Access Token is given below.
{
"typ": "at+jwt",
"alg": "ES256",
"kid": "c950c0e6fdeb5de50a50096b247af03c"
}
{
"iss": "https://eaa-provider.example.org",
"sub": "d4e0bb387aa2556ff306925fdfb9a765",
"aud": "https://eaa-provider.example.org",
"iat": 1715842560,
"exp": 1778914560,
"jti": "f9655ceb-c65c-4025-9378-b6672b6149bg",
"client_id": "47b982369791d08003a7283f059cb0d1",
"cnf": {
"jkt": "951574aee1bb7907ae1ec3109db2b225"
}
}
Steps 16-17 (DPoP Proof for Credential Endpoint): The Wallet Instance for requesting the Digital Credential creates a proof of possession with c_nonce
obtained in Step 15 and using the private key used for the DPoP, signing a DPoP Proof JWT according to (RFC 9449) Section 4. The jwk
value in the proof
parameter MUST be equal to the public key referenced in the DPoP.
Step 18 (Credential Request): The Wallet Instance sends a request for the Digital Credential to the PID/(Q)EAA Credential endpoint. This request MUST include the Access Token, DPoP Proof JWT, credential type, proof (which demonstrates possession of the key), and format parameters. The proof parameter MUST be an object that contains evidence of possession of the cryptographic key material to which the issued PID/(Q)EAA Digital Credential will be bound. To verify the proof, the PID/(Q)EAA Provider conducts the following checks at the Credential endpoint:
the JWT proof MUST include all required claims as specified in the table of Section Token Request;
The key proof MUST be explicitly typed using header parameters as defined for the respective proof type;
The header parameter alg MUST indicate a registered asymmetric digital signature algorithm, and MUST NOT be set to none;
The signature on the key proof MUST be verified using the public key specified in the header parameter.
The header parameter MUST NOT contain a private key.
If a c_nonce value was previously provided by the server, the nonce claim in the JWT MUST match this c_nonce value. Furthermore, the creation time of the JWT, as indicated by the iat claim or a server-managed timestamp via the nonce claim, MUST be within an acceptable window of time as determined by the server.
Note
PID/(Q)EAA Credential Schema and Status registration: The PID/(Q)EAA Provider MUST register all the issued Credentials for their later revocation, if needed.
Note
It is RECOMMENDED that the public key contained in the jwt_proof
be specifically generated for the requested Credential (fresh cryptographic key) to ensure that different issued Credentials do not share the same public key, thereby remaining unlinkable to each other.
A non-normative example of the Credential Request is provided below.
POST /credential HTTP/1.1
Host: eaa-provider.example.org
Content-Type: application/json
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik
VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR
nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R
1JEQSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj
oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z
WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF
c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E
OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA
{
"format": "vc+sd-jwt",
"vct": "EuropeanDisabilityCard",
"proof": {
"proof_type": "jwt",
"jwt": "eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoicFZVM2phdHU0YTN0azljOWFvd1ZnTHlCQl9ySjdNLTNXbGprMWVqVXoyRSIsInkiOiJUTDVPTnZSLUlnYXJuZ3J6NWpkdnNwb2ZmekZ3Y2pQUnRGVWtlbmVIRUkwIn19.eyJpc3MiOiI0N2I5ODIzNjk3OTFkMDgwMDNhNzI4M2YwNTljYjBkMSIsImF1ZCI6Imh0dHBzOi8vZWFhLXByb3ZpZGVyLndhbGxldC5pcHpzLml0L2NyZWRlbnRpYWwiLCJpYXQiOjE3MDU1NzAwNTUsImV4cCI6MTc3ODkxNDU2MCwibm9uY2UiOiJ0c19FdFVRczBpZWlJUzFOWU5CSEVRU295M2N0NGdweS00RlpLd0hpbGtZIn0.ILIEIk_mBJp8BHyngsPHIUyM3WGaOkt9hsdref3Qek4kYAtAfRRER6DgTeRURNAWKBem8m1mILYhBTNFfZcJjg"
}
}
Where a non-normative example of the decoded content of the jwt
parameter is represented below,
without encoding and signature. The JWS header:
{
"typ": "openid4vci-proof+jwt",
"alg": "ES256",
"jwk": {
"kty": "EC",
"crv": "P-256",
"x": "pVU3jatu4a3tk9c9aowVgLyBB_rJ7M-3Wljk1ejUz2E",
"y": "TL5ONvR-Igarngrz5jdvspoffzFwcjPRtFUkeneHEI0"
}
}
{
"iss": "47b982369791d08003a7283f059cb0d1",
"aud": "https://eaa-provider.example.org",
"iat": 1705570055,
"nonce": "ts_EtUQs0ieiIS1NYNBHEQSoy3ct4gpy-4FZKwHilkY"
}
Steps 19-21 (Credential Response): The PID/(Q)EAA Provider MUST validate the DPoP JWT Proof based on the steps defined in Section 4.3 of (RFC 9449) and whether the Access Token is valid and suitable for the requested PID/(Q)EAA. It also MUST validate the proof of possession for the key material the new credential SHALL be bound to, according to OpenID4VCI Section 7.2.2. If all checks succeed, the PID/(Q)EAA Provider creates a new Credential bound to the key material and provide it to the Wallet Instance. The Wallet Instance MUST perform the following checks before proceeding with the secure storage of the PID/(Q)EAA:
It MUST check that the PID Credential Response contains all the mandatory parameters and values are validated according to Table of the credential response parameters.
It MUST check the PID integrity by verifying the signature using the algorithm specified in the
alg
header parameter of SD-JWT (PID/(Q)EAA Data Model) and the public key that is identified using using thekid
header of the SD-JWT.It MUST check that the received PID (in credential claim) matches the schema defined in PID/(Q)EAA Data Model.
It MUST process and verify the PID in SD-JWT VC format (according to SD-JWT Section 6.) or MDOC CBOR format.
It MUST verify the Trust Chain in the header of SD-JWT VC to verify that the PID Provider is trusted.
If the checks defined above are successful the Wallet Instance proceeds with the secure storage of the PID/(Q)EAA.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"credential": "eyJ0eXAiOiJ2YytzZC1qd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImM5NTBjMGU2ZmRlYjVkZTUwYTUwMDk2YjI0N2FmMDNjIn0.eyJfc2QiOlsiQ1JJQkdpbWhhbE1TSzhLZUxmNzg2N0w4cHV6MEZnRTVaS1VXLW12N0hiYyIsIlhhZjVJZFVGc0UzYWtabEszT0E5d3dHcjJKcVAwUU01M3BBY2hiempRZmMiLCJjR2FuQVdySG9WQVoyalBhNXk0SzE3U0xpYWFKcGRNUF9PdnBmTGx0VWJjIiwiNEFuZU1ZVVAxRWh3emRHdkRQOEhobnRaRGN1ejZrOHhHWVJ0NXo0SHh0SSIsIjRuYTVXSHRMYzdrYnNxdHFVaHd6WXdVdUQtY3hKVmdENmRaLTl0ZUdhZ3MiLCJiZS10a2U3YVU0WmhDNWUxcGZqRjcxUWpFRzRsZG1IaFRoUFl1TnQyOHo0IiwiSnNkaHhTMWRVTTJaN29MUmZYWVJvOFFEaDJ4M1dQNkdILUJnY21DdzJGayIsIlVobXBRSy1HS3hzaHJwXzZwYVpfZzROVG5fX29aeVdOb01zTGNaMUhlMjgiLCJOdDdQU3RxMkEyWkliUHBHdTJpdmVSek9rbWpYUEN1V0RBdy0tdktSQTBjIiwiV3Rtck5JVzFTVkN0UnZNUF9UM2YtRGlhRUdHNS1iVk5rWGJRckowRnpzRSJdLCJleHAiOjE3NDY1MTU5NzIsImlzcyI6Imh0dHBzOi8vZWFhLXByb3ZpZGVyLmlwenMuaXQiLCJzdWIiOiJOemJMc1hoOHVEQ2NkN25vV1hGWkFmSGt4WnNSR0M5WHMiLCJzdGF0dXMiOnsic3RhdHVzX2F0dGVzdGF0aW9uIjp7ImNyZWRlbnRpYWxfaGFzaF9hbGciOiJzaGEtMjU2In19LCJ2Y3QiOiJEaXNhYmlsaXR5Q2FyZCIsIl9zZF9hbGciOiJzaGEtMjU2IiwiY25mIjp7Imp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6InBWVTNqYXR1NGEzdGs5Yzlhb3dWZ0x5QkJfcko3TS0zV2xqazFlalV6MkUiLCJ5IjoiVEw1T052Ui1JZ2FybmdyejVqZHZzcG9mZnpGd2NqUFJ0RlVrZW5lSEVJMCJ9fX0.v9ynFXhKXPOhQSMmuLvIBKRWfPEPDf4QwDoNmDOjMROxr5J4Hshh9mBEM5qohH_PDE62i1TLc36C65jFYa7x3A~WyIwQUx5SzRfUi1aVUpTekVKdW5HTFdRIiwiaWF0IiwiMTc0NzExOTU5NSJd~WyItT25uM29FcGh6TDNncHJUcVF0YUd3IiwiZG9jdW1lbnRfbnVtYmVyIiwiMDAwMDAwMDIiXQ~WyJ2bmtVX2tJV2RSa1dPZzBoNlRYcDd3IiwiZ2l2ZW5fbmFtZSIsIk1hcmlvIl~WyJvRUdnaVZQaXV1dEJVby1wcTd6WURBIiwiZmFtaWx5X25hbWUiLCJSb3NzaSJd~WyJGVU1iQm5hLWhlLUlaWTZkOVZ1UkNBIiwiYmlydGhfZGF0ZSIsIjE5ODAtMDEtMTAiXQ~WyJjQ0ZDeXljV1J4alZINkZURVR5OTd3IiwidGF4X2lkX2NvZGUiLCJSU1NNUkE4MFIwMUg1MDFCIl0~WyJVSEFhaWZ1bzloTW9pbkVDU0loOG9RIiwiZXhwaXJ5X2RhdGUiLCIyMDMwLTAxLTEwIl~WyJ3TW1xYkkzTFRPMDVLajFoLXNpWWhRIiwiY29uc3RhbnRfYXR0ZW5kYW5jZV9hbGxvd2FuY2UiLCIwIl0~WyJBODVjeFI1REZyOElfaFZFQTZqZGNBIiwibGlua19xcl9jb2RlIiwiaHR0cHM6Ly9xci5leGFtcGxlLmNvbSJd~WyJHWHRYNXNueTctVEVpblhZajNMdGdBIiwicG9ydHJhaXQiLCIvOWovNEFBUVNrWkpSZ0FCQVFFQkxBRXNBQUQvNFFCV1JYaHBaZ0FBVFUwQUtnQUFBQWdBQkFFYUFBVUFBQUFCQUFBQVBnRWJBQVVBQUFBQkFBQUFSZ0VvQUFNQUFBQUJBQUlBQUFJVEFBTUFBQUFCQUFFQUFBQUFBQUFBQUFFc0FBQUFBUUFBQVN3QUFBQUIvKzBBTEZCb2IzUnZjMmh2Y0NBekxqQUFPRUpKVFFRRUFBQUFBQUFQSEFGYUFBTWJKVWNjQVFBQUFnQUVBUC9oRElGb2RIUndPaTh2Ym5NdVlXUnZZbVV1WTI5dEwzaGhjQzh4TGpBdkFEdy9lSEJoWTJ0bGRDQmlaV2RwYmowbjc3dS9KeUJwWkQwblZ6Vk5NRTF3UTJWb2FVaDZjbVZUZWs1VVkzcHJZemxrSno4K0NqeDRPbmh0Y0cxbGRHRWdlRzFzYm5NNmVEMG5ZV1J2WW1VNmJuTTZiV1YwWVM4bklIZzZlRzF3ZEdzOUowbHRZV2RsT2pwRmVHbG1WRzl2YkNBeE1DNHhNQ2MrQ2p4eVpHWTZVa1JHSUhodGJHNXpPbkprWmowbmFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1UazVPUzh3TWk4eU1pMXlaR1l0YzNsdWRHRjRMVzV6SXljK0Nnb2dQSEprWmpwRVpYTmpjbWx3ZEdsdmJpQnlaR1k2WVdKdmRYUTlKeWNLSUNCNGJXeHVjenAwYVdabVBTZG9kSFJ3T2k4dmJuTXVZV1J2WW1VdVkyOXRMM1JwWm1Zdk1TNHdMeWMrQ2lBZ1BIUnBabVk2VW1WemIyeDFkR2x2YmxWdWFYUStNand2ZEdsbVpqcFNaWE52YkhWMGFXOXVWVzVwZEQ0S0lDQThkR2xtWmpwWVVtVnpiMngxZEdsdmJqNHpNREF2TVR3dmRHbG1aanBZVW1WemIyeDFkR2x2Ymo0S0lDQThkR2xtWmpwWlVtVnpiMngxZEdsdmJqNHpNREF2TVR3dmRHbG1aanBaVW1WemIyeDFkR2x2Ymo0S0lEd3ZjbVJtT2tSbGMyTnlhWEIwYVc5dVBnb0tJRHh5WkdZNlJHVnpZM0pwY0hScGIyNGdjbVJtT21GaWIzVjBQU2NuQ2lBZ2VHMXNibk02ZUcxd1RVMDlKMmgwZEhBNkx5OXVjeTVoWkc5aVpTNWpiMjB2ZUdGd0x6RXVNQzl0YlM4blBnb2dJRHg0YlhCTlRUcEViMk4xYldWdWRFbEVQbUZrYjJKbE9tUnZZMmxrT25OMGIyTnJPamxqTmpabVpUZGxMVFkzWTJRdE5ETTRZeTA1WlRobUxUSXdPREE1TkRObU9UWTJaVHd2ZUcxd1RVMDZSRzlqZFcxbGJuUkpSRDRLSUNBOGVHMXdUVTA2U1c1emRHRnVZMlZKUkQ1NGJYQXVhV2xrT2pSaE16ZzBZVFUxTFdJek1UZ3ROR05rWVMwNE4yVXpMVE14TVRZd00yTmhaVEUzT0R3dmVHMXdUVTA2U1c1emRHRnVZMlZKUkQ0S0lEd3ZjbVJtT2tSbGMyTnlhWEIwYVc5dVBnbzhMM0prWmpwU1JFWStDand2ZURwNGJYQnRaWFJoUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lBb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUFvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lBb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUFvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lBbzhQM2h3WVdOclpYUWdaVzVrUFNkM0p6OCsvOXNBUXdBRkF3UUVCQU1GQkFRRUJRVUZCZ2NNQ0FjSEJ3Y1BDd3NKREJFUEVoSVJEeEVSRXhZY0Z4TVVHaFVSRVJnaEdCb2RIUjhmSHhNWElpUWlIaVFjSGg4ZS85c0FRd0VGQlFVSEJnY09DQWdPSGhRUkZCNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlLzhBQUVRZ0JhQUZvQXdFUkFBSVJBUU1SQWYvRUFCMEFBUUFCQlFFQkFRQUFBQUFBQUFBQUFBQUdBUVVIQ0FrRUFnUC94QUJDRUFFQUFRTUNBZ01OQlFVSEJRQUFBQUFBQVFJREJBVUdCeEVoTVZFSUVoTVVGeUpCVm1GeG9hVFNRb0dSa3NFak1rT0NvaFVXWW5LRHNzSVlObEoxcy8vRUFCWUJBUUVCQUFBQUFBQUFBQUFBQUFBQUFBQUJBdi9FQUJZUkFRRUJBQUFBQUFBQUFBQUFBQUFBQUFBUkFmL2FBQXdEQVFBQ0VRTVJBRDhBM0xBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCNXRTejhMVE1HN25hamwyTVRGczA5OWN2WHJrVVVVUjJ6TTlFQXdudmZ1bHRwNlZjcnh0dDRPVHIxNm5uSGh1ZmdNZm43S3FvbXFyN3FlWHRJTVY2MTNTWEVQTnVUT0JScEdsMGVpTFdOTjJxUHZybVkrQ3dXWHk5Y1ZlLzc3KzgxUHU4UXNjdjloQmV0RjdwTGlIaFhJblBvMGpWS1BURjNHbTFWUDMwVEVmQWd5cHNqdWx0cDZyY294dHlZT1RvTjZybEhodWZoOGZuN2FxWWlxbjc2ZVh0U0RObW01K0ZxZUZhenRPeTdHWGkzcWUrdDNyTnlLNks0N1ltT2lRZWtBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFTTRyOFJkQzRlYUY0OXFkVTM4dTl6cHc4SzNWRVhMOVVmN2FZOU5VOUVlMmVVQTB2NGs4UXR6YisxT2NyWE15ZkZxS3BuSHdiVXpGaXhIc3A5TlgrS2VjKzdxVVJKUUFBQUJMZUczRUxjMndkVGpLMFBNbnhhdXFKeU1HN016WXZ4N2FmUlYvaWpsUHY2a0c2SENqaUxvWEVQUXZIdE1xbXhsMmVWT1poWEtvbTVZcW4vZFRQb3Fqb24yVHpoQk13QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVdQZm01OU4yZHRYTzNEcXRmTEh4YU9jVVJQblhhNTZLYUtmYlZQS1BqNkFhRWI4M1ZxKzg5elpXdjZ6ZTcvSXZ6eW90MHo1bGkzSDd0dWlQUlRIeG5uTTlNcUxFb0FBQUFBQXZ1dzkxYXZzemMyTHIralh1OHlMRThxN2RVK1pmdHorOWJyajAwejhKNVRIVENEZmZZZTU5TjNqdFhCM0RwVmZQSHlxT2MwVFBuV3E0NktxS3ZiVFBPUGo2VUY4QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQnFSM1l1OHE5VDNkajdReGJzK0o2VFRGM0ppSjZLOGl1bm5IUC9MUk1mZlhLNE1ES0FBQUFBQUFBTTg5eDF2S3ZUTjNaRzBNcTdQaWVxMHpkeG9tZWlqSW9wNXp5L3pVUlAzMFFtamJkQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCK2VUZHQyTWU1ZnUxZDdidDB6WFZQWkVSemtIT1RjK3JYdGUzSHFXdDVGVXpkejhxNWtWZnpWVE1SOTBjbys1UmJsQUFBQUFBQUFGeDJ4cTE3UWR4NmJyZVBWTVhjREt0NUZQOHRVVE1mZkhPUHZRZEc4YTdidjQ5dS9hcTc2M2NwaXVtZTJKam5DRDlBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVI3aVhmcXh1SFc1TWlpZVZWdlNzcXFtZmJGcW9ITytpT1ZGTWRrUkRRcUFBQUFBQUFBQ2xjYzZLbzdZbUFkRU9HbCtySjRkYmJ5SzU1MVhOS3hhcXA5czJxV1JJUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFXWGZtSlZxR3lOZHdhSTUxNUdtNUZxbVBiVmJxaUFjNktPbWltWjdJYUZRQUFBQUFBQUFVcjZLS3Bqc2tIUmZZZUpWcCt5TkN3YTQ1VjQrbTQ5cXFQYlRicGlXUmVnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVVxaUppWW1PY0E1NThUZHYzTnJjUU5iMEt1aWFhY1hNcjhEempydFZUMzF1ZnkxUW9qaWdBQUFBQUFBQ1I4TXR2M04wY1FORTBLaWlhcWNyTW84TnlqcXRVejMxeWZ5MHlnNkdVeEVSRVJIS0VGUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBYTNkMlRzV3UvalltKzlQc3pWT1BUR0xxVVV4L0Q1L3M3ays2Wm1tWi94VTlpNE5ZRkFBQUFBQUFBR3ovY2JiRnJzWTJYdnZVTE0wemtVemk2YkZVZncrZjdTNUh2bUlwai9BQzFkcWFOa1VBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFIbjFIQ3hkUndMK0JuV0tNakZ5TGRWcTlhcmpuVFhSVkhLWW4yVEFOSGVPWEREUDRkN2hud1ZGM0kwSExybWNIS21PZmUrbndWYytpdU8zN1VkUGJFVVk1VUFBQUFBQVpHNEc4TU0vaUp1R1BDMFhjZlFjU3VKenNxSTVkOTZmQlVUL3dDYzl2Mlk2ZXlKZzNpMDdDeGRPd0xHQmcyS01mRng3ZE5xemFvamxUUlJUSEtJajJSQ0QwQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE4RzRORzB2WDlJeU5KMWpDczV1RmtVOTdkczNZNXhWSDZUSFhFeDB4UFVEVTdpMzNQbXZiZXUzdFMyalRlMXZTZWMxZUx4MDVWaU96bC9FajJ4NTNiSHBXakNOeWl1M2NydDNLYXFLNko1VjAxUnlxcG5zbUo2WWxSOGdBQStyZEZkeTVSYnQwMVYxMXp5b3Bwam5WVlBaRVIweklNM2NKTzU4MTdjTjJ6cVc3cWIyaWFUemlyeGVlakt2eDJjdjRjZTJmTzdJOUtVYlk3ZjBiUzlBMGpIMG5SOEt6aFlXUFQzdHF6YWpsRk1mck05Y3pQVE05YUQzZ0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBY3dlRFU5WjBqVEtacTFMVk1IQ3Bqcm5JeUtMY2YxVEFJSnJPQndlNGxabHpGeWIyM2RYejZQTjhKajVWRk9SSHVyb21LcCtNQWhldGR5OXRYSXJtdlNkd2F4cDhUOWk3RkYrbVB4aUorSzBXYi9wV283Ly9BTDVxNzMvMWtjLy9BS0ZGNTBYdVh0cTQ5Y1Y2dHVEV05RaVBzV29vc1V6K0VWVDhTaWFhTmdjSHVHdVpieGNhOXQzU00rdnpmQ1pHVlJWa1Q3NjY1bXFQaENDZDZack9rYW5URldtNnBnNXRNOVU0K1JSY2orbVpCNytZQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFMSnZEZG0zZG82ZC9hRzR0V3h0UHNUUEtqd2xYT3E1UFpSVEhuVlQ3SWlRWWIxM3VvdHM0OTJxalJ0dTZycU1SMVhMMWRHUFRWN284NnJsNzRoWUlacTNkUmJvdmQ5R21iYjBqRXBucW0vZHVYNm8vRHZZSUlocTNIdmlobnhWVFRyOXJDb243T0poMjZPWDMxUlZQeElJanErK041NnZFeHFXNjlieXFaNjZhczJ1S2Z5eE1SOEFSKzVNM0s1cnVmdEtwKzFYNTAvaktpbnBpZlRIVlBZQ1JhUHZuZW1rVVJiMHpkbXQ0dHVPcWlqTnJtbVA1Wm1ZUVhmeXZjVGU4NzMrK3VxOHZmUnovQUI3MGd0R3NiNTNwcTlFMjlUM1pyZVZibnJvcnphNHBuK1dKaUFSMzB6UHBucm50VVZ0ek51dUs3ZjdPcVB0VWViUDR3Q1FhUnZqZWVrUkVhYnV2VzhXbU9xbW5Ocm1uOHN6TWZCQkx0SjQ5OFVNQ0thYXRmdFp0RWVqTHc3ZGZQNzZZcG40a0V2MG51b3QwV2U5alU5dDZSbDB4MXpZdTNMRlUvajMwRUV6MEx1b3RzNUYybWpXZHZhcnAwVDEzTE5kR1JUSDNlYlZ5OTBTUVprMmZ1emJ1N3RPL3REYnVyWTJvV0lubFg0T3JsVmJuc3JwbnpxWjlreENDOWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQWhuR0hmdUR3OTJmZDFqSW9wdjVkeXJ3T0ZqVFZ5OE5kbU9jUlBaVEVkTXoyUjJ6QU5HTjI3ajFuZFd1WHRaMTdPdVptWmRuOTZyb3BvcDlGRkZQVlRUSG9pUGpQU290S2dBQUFBQUFBQUFBQUFBQzdiUzNIck8xZGNzNnpvV2Rjdzh5MVA3MVBUVFhUNmFLNmVxcW1leWZoUFNnM240UGI5d2VJV3o3V3NZOUZOakx0MWVCemNhS3VmZ2JzUnptSTdhWmpwaWV5ZTJKUVRNQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUdtZmRkN2l2YXR4VHEwZUxremk2TmowV2FLWW5vOEpjaUs2NnZmeW1pUDVWd1liVUFBQUFBQUFBQUFBQUFBQUFabDdrVGNWN1NlS2RPanpjbU1YV2NldXpYVE05SGhMY1RYUlY3K1VWeC9NbWpjdEFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFucUJvRnh5ditNY1lkMTNPZlZxZHlqOHNSVC94WEJERkFBQUFBQUFBQUFBQUFBQUFFejRHMy9GK01PMUxuUHIxTzNSK2FKcC81Sm8zOWpxUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUpCenM0aDVIamUvOEFjV1Z6NStGMVhLcWlmOVdwUllsQUFBQUFBQUFBQUFBQUFBQUY5NGVaSGltLzl1NVhQbDRMVmNXcVovMWFVSFJPRUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUZLcGlLWm1laUk2UWMyZFV2VGthbmw1RTlNM2NpNWMvTlhNL3FvOHlnQUFBQUFBQUFBQUFBQUFBRDA2WGVuSDFQRXlJNkp0WkZ1NStXdUovUkIwbXBtSnBpWTZZbnBRVkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQjRkd1gvRmRDejhtWjVSYXhydGY0VVRQNkE1dVVUem9wcW5ybUlsb1ZBQUFBQUFBQUFBQUFBQUFBQlN1ZVZGVlVkY1JNZzZSN2Z2K05hRmdaTVR6aTdqV3EveG9pZjFaSHVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUJIT0tHUkdKdzMzTGs4K1hnOUp5WmlmYjRLb0hQR21PVk1SMlJFTkNvQUFBQUFBQUFBQUFBQUFBQUtWUnpwbU8ySmdIUTdoZmtSbDhOOXRaUFBuNFRTY2FabjIrQ3BaRWpBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUJCTzZDeVBGdURHNnJrVHk1NmZYYi9OTVUvcURRdWV1V2hRQUFBQUFBQUFBQUFBQUFBQUZZNjRCdnAzUHVSNHp3WTJyY21lZkxUNkxmNVptbjlHUk93QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFZLzdvckN5Yy9ndHViSHhLS3E3bE9MRjJhYVk1ek5OdXVtdXIrbW1RYUh0QUFBQUFBQUFBQUFBQUFBQUFBRGZEdWRjTEp3T0MyMmNmTG9xb3UxWXMzWXBxamxNVTNLNnE2ZjZhb1pHUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQWZOeWlpN2JxdDNLS2E2S29tS3FhbzV4TVQxeE1BMWI0cGR6ZHFsR3FYdFEySGN4NytGZXFtcU5PdjNmQjEySm43TkZjK2JWVDJSTXhNZFhPVm9nUGtINHErcS93QTlZK3NvZVFmaXI2ci9BRDFqNnloNUIrS3ZxdjhBUFdQcktIa0g0cStxL3dBOVkrc29lUWZpcjZyL0FEMWo2eWg1QitLdnF2OEFQV1ByS0hrSDRxK3Evd0E5WStzb2VRZmlyNnIvQUQxajZ5aDVCK0t2cXY4QVBXUHJLSGtINHErcS93QTlZK3NvZVFmaXI2ci9BRDFqNnloNUIrS3ZxdjhBUFdQcktIa0g0cStxL3dBOVkrc29lUWZpcjZyL0FEMWo2eWg1QitLdnF2OEFQV1ByS0hrSDRxK3Evd0E5WStzb2VRZmlyNnIvQUQxajZ5aWZjTGU1dTFTdlZMT29iOHVZOWpDczFSVk9uV0x2aEs3OHg5bXV1UE5wcDdZaVptZXJuQlJ0SmJvb3RXNmJkdWltaWltSWltbW1PVVJFZFVSQ0Q2QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCLy9aIl0",
"c_nonce": "ff_EtUQs0ieiIS1NYNBHEQSoy3ct4gpy-89JKwHilrT",
"c_nonce_expires_in": 86400,
"notification_id": "dab8ef51-fb43-43a5-a5c1-247c93ddb942"
}
Note
If the issuance of the requested Credential cannot be issued immediately and it requires more time to be issued, then the PID/(Q)EAA Provider MAY support the Deferred Flow (step 24) as specified in Section Deferred Flow.
Steps 22 (Notification Request): According to Section 10.1 of [OpenID4VCI], the Wallet sends an HTTP POST request to the Notification Endpoint using the application/json media type as in the following non-normative example.
POST /notification HTTP/1.1
Host: eaa-provider.example.org
Content-Type: application/json
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik
VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR
nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R
1JEQSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj
oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z
WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF
c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E
OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA
{
"notification_id": "dab8ef51-fb43-43a5-a5c1-247c93ddb942",
"event": "credential_accepted"
}
Steps 23 (Notification Response): When the Credential Issuer has successfully received the Notification Request from the Wallet, it MUST respond with an HTTP status code 204 as recommended in Section 10.2 of [OpenID4VCI]. Below is a non-normative example of response to a successful Notification Request:
HTTP/1.1 204 No Content
Deferred Flow¶
The PID/(Q)EAA Providers MAY support a Deferred Flow which has the aim of handling the cases where an immediate issuance is not possible for some reasons due to errors during the communication between the PID/(Q)EAA Provider and the Authentic Source (for example the Authentic Source is temporarily unavailable, etc.) or due to administrative or technical processes that do not allow the Credential to be provided immediately.
General Requirements¶
The Deferred Credential request MAY also happen several days after the initial Credential request.
The User MUST be informed that the Credential is available and ready to be issued.
The Wallet Provider MUST NOT be informed about which Credential is available to be issued or which Credential Provider the User needs to contact.
The Wallet Instance MUST be informed about the amount of time to wait before making a new Credential request.
As, in general, an unavailability may be an unexpected event, the PID/(Q)EAA Provider MUST be able to switch on the fly between a immediate and an deferred flow. This decision MUST be taken after the authorization step.
Technical Flow¶
If PID/(Q)EAA Providers, supporting this flow, are not able to immediately issue a requested Credential, they MUST provide the Wallet Instance with an HTTP Credential Response cointaining the amount of time to wait before making a new Credential request. The HTTP status code MUST be 202 (see Section 15.3.3 of [RFC 9110]). Below a non-normative example is given.
HTTP/1.1 202 Accepted
Content-Type: application/json
Cache-Control: no-store
{
"lead_time": 864000,
"c_nonce": "ff_EtUQs0ieiIS1NYNBHEQSoy3ct4gpy-89JKwHilrT",
"c_nonce_expires_in": 86400
}
The Wallet Instance MUST use the value given in the lead_time parameter to inform the User when the Credential becomes available (e.g. using a local notification triggered by the lead_time time value). PID/(Q)EAA Providers MAY send a notification to the User through a communication channel (e.g. email address), if available from the PID/(Q)EAA Provider.
Upon receipt of the notification (by the Wallet Instance and/or by the PID/(Q)EAA Provider), the User opens the Wallet Instance and start the Issuance Flow again from the beginning as defined in the previous section.
If the lead_time parameter is less than the expiration time of the Access Token, the Wallet Instance MAY use it along with the c_nonce provided in the Credential Response to perform a new Credential Request without requiring the User to submit a new authentication request.
In the case where the Authentic Source and the PID/(Q)EAA Provider are both enabled to use PDND, what is described in Section Authentic Sources MUST apply.
Token endpoint¶
The token endpoint is used by the Wallet Instance to obtain an Access Token by presenting an authorization grant, as defined in RFC 6749. The Token Endpoint is a protected endpoint with a client authentication based on the model defined in OAuth 2.0 Attestation-based Client Authentication [OAUTH-ATTESTATION-CLIENT-AUTH ].
Token Request¶
The request to the PID/(Q)EAA Token endpoint MUST be an HTTP request with method POST, with the body message encoded in application/x-www-form-urlencoded
format. The Wallet Instance sends the Token endpoint request with OAuth-Client-Attestation
and OAuth-Client-Attestation-PoP
as header parameters according to OAUTH-ATTESTATION-CLIENT-AUTH.
The Token endpoint is protected with OAuth 2.0 Attestation-based Client Authentication [OAUTH-ATTESTATION-CLIENT-AUTH], therefore the request to the PID/(Q)EAA authorization endpoint MUST use the following HTTP Headers parameters OAuth-Client-Attestation as OAuth-Client-Attestation-PoP as defined in the "Pushed Authorization Request (PAR) Endpoint".
The Token endpoint issues DPoP tokens, therefore it is REQUIRED that the request incluides in its HTTP header the DPoP proof parameter.
The Token endpoint MUST validate the DPoP proof according to Section 4.3 of the DPoP specifications (RFC 9449). This mitigates the misuse of leaked or stolen Access Tokens at the credential endpoint. If the DPoP proof is invalid, the Token endpoint returns an error response, according to Section 5.2 of [RFC 6749] with invalid_dpop_proof
as the value of the error parameter.
All the parameters listed below are REQUIRED:
Claim |
Description |
Reference |
---|---|---|
grant_type |
It MUST be set to |
[RFC 7521]. |
code |
Authorization code returned in the Authentication Response. |
[RFC 7521]. |
redirect_uri |
It MUST be set as in the Request Object Table of the JWT Request parameters. |
[RFC 7521]. |
code_verifier |
Verification code of the code_challenge. |
A DPoP Proof JWT is included in the HTTP request using the DPoP
header parameter containing a DPoP JWS.
The JOSE header of a DPoP JWT MUST contain at least the following parameters:
JOSE header |
Description |
Reference |
---|---|---|
typ |
It MUST be equal to |
|
alg |
A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section Cryptographic Algorithms and MUST NOT be set to |
[RFC 7515]. |
jwk |
It represents the public key chosen by the Wallet Instance, in JSON Web Key (JWK) [RFC 7517] format that the Access Token MUST be bound to, as defined in [RFC 7515] Section 4.1.3. It MUST NOT contain a private key. |
The payload of a DPoP JWT Proof MUST contain the following claims:
Claim |
Description |
Reference |
---|---|---|
jti |
Unique identifier for the DPoP proof JWT. The value SHOULD be set using a UUID v4 value according to [RFC 4122]. |
[RFC 7519. Section 4.1.7]. |
htm |
The value of the HTTP method of the request to which the JWT is attached. |
[RFC 9110. Section 9.1]. |
htu |
The HTTP target URI, without query and fragment parts, of the request to which the JWT is attached. |
[RFC 9110. Section 7.1]. |
iat |
UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in RFC 7519. |
[RFC 7519. Section 4.1.6]. |
Token Response¶
If the Token Request is successfully validated, the Authorization Server provides an HTTP Token Response with a 200 (OK) status code. The Token Response MUST contain the following mandatory claims.
Claim |
Description |
Reference |
---|---|---|
access_token |
The DPoP-bound Access Token, in signed JWT format, allows accessing the PID/(Q)EAA Credential Endpoint for obtaining the credential. |
|
token_type |
Type of Access Token returned. It MUST be equal to |
|
expires_in |
Expiry time of the Access Token in seconds. |
|
c_nonce |
JSON string containing a |
[OpenID4VCI]. |
c_nonce_expires_in |
JSON integer, it represents the lifetime in seconds of the c_nonce. |
[OpenID4VCI]. |
authorization_details |
Array of JSON Objects, used to identify Credentials with the same metadata but different claimset/claim values and/or simplify the Credential request even when only one Credential is being issued. |
[OpenID4VCI]. |
If any errors occur during the validation of the Token Request, the Authorization Server MUST return an error response as defined in RFC 6749#section-5.2.
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"error": "invalid_client",
"error_description": "Client authentication failed"
}
Access Token¶
A DPoP-bound Access Token is provided by the PID/(Q)EAA Token endpoint as a result of a successful token request. The Access Token is encoded in JWT format, according to [RFC 7519]. The Access Token MUST have at least the following mandatory claims and it MUST be bound to the public key that is provided by the DPoP proof. This binding can be accomplished based on the methodology defined in Section 6 of (RFC 9449).
The JOSE header of a DPoP JWT MUST contain the following claims.
JOSE header |
Description |
Reference |
---|---|---|
typ |
It MUST be equal to |
[RFC 7515]. |
alg |
A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section Cryptographic Algorithms and MUST NOT be set to |
[RFC 7515]. |
kid |
Unique identifier of the |
Claim |
Description |
Reference |
---|---|---|
iss |
It MUST be an HTTPS URL that uniquely identifies the PID/(Q)EAA Issuer. The Wallet Instance MUST verify that this value matches the PID/(Q)EAA Issuer where it has requested the credential. |
|
sub |
It identifies the subject of the JWT. It MUST be set to the value of the |
|
client_id |
The identifier for the Wallet Instance that requested the Access Token; it MUST be equal to the to kid of the public key of the Wallet Instance specified into the Wallet Attestation ( |
|
aud |
It MUST be set to the identifier of the PID/(Q)EAA Provider. |
[RFC 9068]. |
iat |
UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in RFC 7519. |
|
exp |
UNIX Timestamp with the expiry time of the JWT, coded as NumericDate as indicated in RFC 7519. |
|
jti |
It MUST be a String in uuid4 format. Unique Token ID identifier that the RP SHOULD use to prevent reuse by rejecting the Token ID if already processed. |
|
cnf |
It MUST contain a jkt claim being JWK SHA-256 Thumbprint Confirmation Method. The value of the jkt member MUST be the base64url encoding (as defined in [RFC 7515]) of the JWK SHA-256 Thumbprint of the DPoP public key (in JWK format) to which the Access Token is bound. |
Credential endpoint¶
The Credential Endpoint issues a Credential upon the presentation of a valid Access Token, as defined in OpenID4VCI.
Credential Request¶
The Wallet Instance when requests the PID/(Q)EAA to the PID/(Q)EAA Credential endpoint, MUST use the following parameters in the message body of the HTTP POST request, using the application/json media type.
The Credential endpoint MUST accept and validate the DPoP proof sent in the DPoP HTTP Header parameter, according to the steps defined in (RFC 9449) Section 4.3. The DPoP proof in addition to the values that are defined in the Token Endpoint section MUST contain the following claim:
ath: hash value of the Access Token encoded in ASCII. The value MUST use the base64url encoding (as defined in Section 2 of RFC 7515) with the SHA-256 algorithm.
If the DPoP proof is invalid, the Credential endpoint returns an error response per Section 5.2 of [RFC 6749] with invalid_dpop_proof as the value of the error parameter.
Warning
The Wallet Instance MUST create a new DPoP proof for the Credential request and MUST NOT use the previously created proof for the Token Endpoint.
Claim |
Description |
Reference |
---|---|---|
format |
Format of the Credential to be issued. This MUST be |
[OpenID4VCI]. |
vct |
CONDITIONAL. REQUIRED only if the format identifier is |
See Annex A3.4. of [OpenID4VCI] |
doctype |
CONDITIONAL. REQUIRED only if the format identifier is |
See Annex A2.4. of [OpenID4VCI] |
proof |
JSON object containing proof of possession of the key material the issued credential shall be bound to. The proof object MUST contain the following mandatory claims:
|
[OpenID4VCI]. |
The JWT proof type MUST contain the following parameters for the JOSE header and the JWT body:
JOSE Header |
Description |
Reference |
---|---|---|
alg |
A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. It MUST be one of the supported algorithms in Section Cryptographic Algorithms and MUST NOT be set to |
[OpenID4VCI], [RFC 7515], [RFC 7517]. |
typ |
It MUST be set to openid4vci-proof+jwt. |
[OpenID4VCI], [RFC 7515], [RFC 7517]. |
jwk |
Representing the public key chosen by the Wallet Instance, in JSON Web Key (JWK) [RFC 7517] format that the PID/(Q)EAA shall be bound to, as defined in Section 4.1.3 of [RFC 7515]. |
[OpenID4VCI], [RFC 7515], [RFC 7517]. |
Claim |
Description |
Reference |
---|---|---|
iss |
The value of this claim MUST be the client_id of the Wallet Instance. |
[OpenID4VCI], [RFC 7519, Section 4.1.1]. |
aud |
It MUST be set to the identifier of the PID/(Q)EAA Provider. |
[OpenID4VCI]. |
iat |
UNIX Timestamp with the time of JWT issuance, coded as NumericDate as indicated in RFC 7519. |
[OpenID4VCI], [RFC 7519. Section 4.1.6]. |
nonce |
The value type of this claim MUST be a string, where the value is a c_nonce provided by the PID/(Q)EAA Issuer in the Token response. |
[OpenID4VCI]. |
Credential Response¶
Credential Response to the Wallet Instance MUST be sent using application/json media type. If the Credential Request is successfully validated, and the Credential is immediately available, the PID/(Q)EAA Provider MUST return HTTP response with a 200 (OK) status code. If the Credential is not available and the deferred flow is supported by the PID/(Q)EAA Provider, an HTTP status code 202 MUST be returned.
The Credential Response contains the following parameters:
Claim |
Description |
Reference |
---|---|---|
credential |
CONDITIONAL. REQUIRED if |
Section 7.3, Annex A2.5 and Annex A3.5 of [OpenID4VCI]. |
lead_time |
CONDITIONAL. REQUIRED if |
This Specification |
c_nonce |
REQUIRED. JSON string containing a |
Section 7.3 of [OpenID4VCI]. |
c_nonce_expires_in |
REQUIRED. JSON integer corresponding to the |
Section 7.3 of [OpenID4VCI]. |
notification_id |
OPTIONAL. String identifying an issued Credential that the Wallet includes in the Notification Request as defined in Section Notification Request. It MUST NOT be present if the |
Section 7.3 of [OpenID4VCI]. |
If the Credential Request is invalid, the PID/(Q)EAA Provider MUST return an error response as defined in Section 7.3.1 of [OpenID4VCI]. The response MUST use the content type application/json and MUST include the following parameters:
error. The error code.
error_description. Text in human-readable form providing further details to clarify the nature of the error encountered.
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "invalid_proof",
"error_description": "The proof field is not present or the provided key proof is invalid or not bound to a nonce provided by the Credential Issuer."
}
Notification endpoint¶
The Notification Endpoint is used by the Wallet to notify the PID/(Q)EAA Provider of certain events for issued Credentials, such as if the Credential was successfully stored in the Wallet Instance or in case of unsuccessful Credential issuance caused by a User action.
This endpoint MUST be protected using a DPoP Access Token. TLS for the confidentiality of the HTTP transport is REQUIRED according to Section 10 of [OpenID4VCI].
Notification Request¶
The Notification Request MUST be an HTTP POST using the application/json media type with the following parameters.
Claim |
Description |
Reference |
---|---|---|
notification_id |
REQUIRED. It MUST be equal to the |
Section 10.1 of [OpenID4VCI]. |
event |
REQUIRED. Type of the notification event. It MUST be a case sensitive string and it MUST support the following values:
|
Section 10.1 of [OpenID4VCI]. |
event_description |
OPTIONAL. Human-readable ASCII [USASCII] text providing additional information, used to inform about the event that occurred. Values for the event_description parameter MUST NOT include characters outside the set %x20-21 / %x23-5B / %x5D-7E. |
Section 10.1 of [OpenID4VCI]. |
Notification Response¶
The Notification Response MUST be use an HTTP status code 204 (No Content), as recommended in Section 10.2 of [OpenID4VCI].
In case of errors, what is described in Section 10.3 of [OpenID4VCI] MUST apply.