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. 5 shows a general architecture and highlights the main operations involved in the issuance of a PID.

_images/High-Level-Flow-ITWallet-PID-Issuance.svg

Fig. 5 PID Issuance - General architecture and high level flow.

Below the description of the steps represented in the previous picture:

  1. 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.

  2. 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.

  3. 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.

  4. PID Request: using the Authorization Code Flow defined in [OpenID4VCI] the Wallet Instance requests the PID to the PID Provider.

  5. User Authentication: the PID Provider authenticates the User with LoA High, acting as an Identity and Access Management Proxy to the National eID system.

  6. 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. 6 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.

_images/High-Level-Flow-ITWallet-QEAA-Issuance.svg

Fig. 6 (Q)EAA Issuance - General architecture and high level flow

Below the description of the most relevant operations involved in the (Q)EAA issuance:

  1. 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.

  2. (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.

  3. (Q)EAA Request: using the Authorization Code Flow , defined in [OpenID4VCI], the Wallet Instance requests a (Q)EAA to the (Q)EAA Provider.

  4. User Authentication: the (Q)EAA Provider, acting as a Verifier (Relying Party), authenticates the User evaluating the presentation of the PID.

  5. (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 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 PID/(Q)EAA Provider.

  • Immediate Issuance flow: The PID/(Q)EAA Provider issues the Credential directly in response to the Credential Request.

In addition, the PID/(Q)EAA Providers MAY support:

  • Issuer Initiated Flow: The Wallet Instance sends its request to the PID/(Q)EAA Provider based on the input provided by the PID/(Q)EAA Provider.

    • Same-device Issuance flow: The User receives the Credential on the same device used to initiate the flow.

    • Cross-device Issuance flow: The User receives the Credential on another device than the one that initiated the flow.

  • Refresh Token flow: The Wallet Instance requests a new Access Token at the Token Endpoint of the PID/(Q)EEA.

  • Re-issuance flow: Following updates to an already stored Digital Credential, the Wallet Instance requests a refresh of the Digital Credential at the Credential Endpoint of the PID/(Q)EAA Provider.

  • 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.

The entire Issuance flow can be divided into two sub-flows:

  • User Request flow, describing the modes through which the User can request the Credential. It can be:

    1) On the initiative of the User (Wallet Initiated)

    2) Upon proposal of the PID/(Q)EAA Issuer (Issuer Initiated)

  • Issuance flow, describing interactions between Wallet Instance and PID/(Q)EAA Provider.

The following diagram shows the User request flow.

_images/Low-Level-Flow-ITWallet-PID-QEAA-User-Request.svg

Steps 1.1-1.4 (Wallet Initiated Flow): The User, using the Wallet Instance, selects the PID/(Q)EAA Provider from those listed in the list of trustworthy entities.

Steps 2.1-2.3 (Issuer Initiated Flow): The User while browsing the PID/(Q)EAA Provider website finds a link to obtain a Digital Credential.

Steps 2.4-2.7 (Cross-Device): The Credential Offer is presented as a QR Code displayed to the User. The User scans the QR Code using the Wallet Instance which retrieves the parameters defined in the Table of Credential Offer parameters.

Steps 2.8-2.10 (Same-Device): The Credential Offer is presented as an href button containing the URL that allows the User to invoke the Wallet Instance using the Credential Offer Endpoint.

Below a non-normative example of a URL related to a Credential Offer that can be included in a QR Code or in html page with an href button:

openid-credential-offer://?credential_offer%3D%7B%22credential_issuer%22%3A%22https%3A%2F%2Feaa-provider.example.org%22%2C%22credential_configuration_ids%22%3A%5B%22EuropeanDisabilityCard%22%5D%2C%22grants%22%3A%7B%22authorization_code%22%3A%7B%22issuer_state%22%3A%22oaKazRN8I0IbtZ0C7JuMn5%22%7D%7D%7D

The following diagram shows the Issuance flow.

_images/Low-Level-Flow-ITWallet-PID-QEAA-Issuance.svg

Fig. 7 PID/(Q)EAA Issuance - Detailed flow

Once User Request flow is completed, the Wallet Instance processes the Metadata of the PID/(Q)EAA Provider as defined in Section Trust Evaluation Mechanism .

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.

In case of Issuer Initiated flow, in addition to the Federation Check defined above, the Wallet Instance MUST execute the following checks on the Credential Offer parameters:

  • For each Credential identifier contained in the credential_configuration_ids array verify if it is supported by the PID/(Q)EAA Provider.

  • The Authorization Server identifier (if present) is contained in the authorization_servers PID/(Q)EAA Provider metadata parameter.

Steps 1-2 (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 and OAuth-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:

  1. 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 the kid JWT header parameter.

  2. 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.

  3. It MUST check that the client_id in the request body of the PAR request matches the client_id claim included in the Request Object.

  4. It MUST check that the iss claim in the Request Object matches the client_id claim in the Request Object (RFC 9126, RFC 9101).

  5. 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).

  6. It MUST reject the PAR request, if it contains the request_uri parameter (RFC 9126).

  7. 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].

  8. It MUST check that the Request Object is not expired, checking the exp claim.

  9. 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 the iat claim is far from the current time (RFC 9126) of more than 5 minutes.

  10. It MUST check that the jti claim in the Request Object has not been used before by the Wallet Instance identified by the client_id. This allows the PID/(Q)EAA Provider to mitigate replay attacks (RFC 7519).

  11. 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: eyJhbGciOiJFUzI1NiIsImtpZCI6IjBiNDk4ZGRlMDkxNzJhZGE3MDFkMDdlYjZmOTg2N2FkIiwidHlwIjoid2FsbGV0LWF0dGVzdGF0aW9uK2p3dCJ9.eyJpc3MiOiJodHRwczovL3dhbGxldC1wcm92aWRlci5leGFtcGxlLm9yZyIsInN1YiI6InZiZVhKa3NNNDV4cGh0QU5uQ2lHNm1DeXVVNGpmR056b3BHdUt2b2dnOWMiLCJhYWwiOiJodHRwczovL3RydXN0LWxpc3QuZXUvYWFsL2hpZ2giLCJjbmYiOnsiandrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiNEhOcHRJLXhyMnBqeVJKS0dNbno0V21kblFEX3VKU3E0Ujk1Tmo5OGI0NCIsInkiOiJMSVpuU0IzOXZGSmhZZ1MzazdqWEU0cjMtQ29HRlF3WnRQQklScXBObHJnIn19LCJhdXRob3JpemF0aW9uX2VuZHBvaW50IjoiaHR0cHM6Ly93YWxsZXQtc29sdXRpb24uZGlnaXRhbC1zdHJhdGVneS5ldXJvcGEuZXUvYXV0aG9yaXphdGlvbiIsInJlc3BvbnNlX3R5cGVzX3N1cHBvcnRlZCI6WyJ2cF90b2tlbiJdLCJyZXNwb25zZV9tb2Rlc19zdXBwb3J0ZWQiOlsiZm9ybV9wb3N0Lmp3dCJdLCJ2cF9mb3JtYXRzX3N1cHBvcnRlZCI6eyJkYytzZC1qd3QiOnsic2Qtand0X2FsZ192YWx1ZXMiOlsiRVMyNTYiLCJFUzM4NCJdfX0sInJlcXVlc3Rfb2JqZWN0X3NpZ25pbmdfYWxnX3ZhbHVlc19zdXBwb3J0ZWQiOlsiRVMyNTYiXSwicHJlc2VudGF0aW9uX2RlZmluaXRpb25fdXJpX3N1cHBvcnRlZCI6ZmFsc2UsImNsaWVudF9pZF9zY2hlbWVzX3N1cHBvcnRlZCI6WyJlbnRpdHlfaWQiXSwiaWF0IjoxNzQwMTU4MDQ3LCJleHAiOjE3NDAxNTgxNjd9.paU3FOET8nraQxuesBXD9gw57DL5HfDzkeboKAOinyh5L2MmLwqvRtrSWK8S7qMRWYmdzR-gHMpmebIH7gGE5w
OAuth-Client-Attestation-PoP: eyJhbGciOiJFUzI1NiIsInR5cCI6Im9hdXRoLWNsaWVudC1hdHRlc3RhdGlvbi1wb3Arand0In0.eyJpc3MiOiIgaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCJhdWQiOiJodHRwczovL2FzLmV4YW1wbGUuY29tIiwianRpIjoiZDI1ZDAwYWItNTUyYi00NmZjLWFlMTktOThmNDQwZjI1MDY0IiwiaWF0IjoxNzQwMTU4NjE3LCJleHAiOjE3NDAxNTg3Mzd9.B0KOkGi9vMxf3H2Y8rrF-mdLNsuluTvAUbjFfL1Hi-gdaPW7-8ziS9uVh7aTnSAHKWzMfkZLv5q-bxhkglR4PA

&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 3 (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):

  1. Many phones on the market still do not accept large payloads. The restriction is typically either 512 or 1024 ASCII characters.

  2. 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 4-5 (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 use a request_uri value once (RFC 9126); The PID/(Q)EAA Provider performs the following checks upon the receipt of the Authorization Request:

  1. 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).

  2. It MUST identify the request as a result of the submitted PAR (derived from RFC 9126).

  3. 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 request the presentation of the PID. In this circumstance, 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 beforehand, to initiate the transaction with the (Q)EAA Provider. During this step, PID/(Q)EAA Providers MAY ask the User's contact details (e.g., their email address) to send notifications about the issued Digital Credential(s).

Steps 6-7 (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:

  1. It MUST check the Authorization Response contains all the defined parameters according to Table of the HTTP Response parameters.

  2. 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).

  3. 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 8-9 (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, and optionally the Refresh Token, to a certain Wallet Instance (RFC 9449) and mitigates the misuse of leaked or stolen tokens at the Credential Endpoint.

Step 10 (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 bound to the Wallet Instance. 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:

  1. It MUST ensure that the Authorization code is issued to the authenticated Wallet Instance (RFC 6749) and was not replied.

  2. It MUST ensure the Authorization code is valid and has not been previously used (RFC 6749).

  3. It MUST ensure the redirect_uri matches the value included in the previous Request Object (see Section 3.1.3.1. of [OIDC]).

  4. 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: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwieCI6IjR2dDhNdEFISmlsMzBDNnpUTmt2c0VVcnlHTEUtQW5BNkc5LV8xa3l5Rk0iLCJ5IjoiTWdiNTFfbjNSRjNtbHNtS3dMd0xtRUFqVmlJM3Q1bTVWNTI2MFA5MzR3RSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIjoiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0ZWRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOH0.3Tp1ZlZ05PQYeZUHhiZwaQ1etqnwYwoiJHFR_JHb32381lMJL-8o2rE3VZ8X3yuqrGFfCVeP90Ln4J5r8ASIBg
OAuth-Client-Attestation: eyJhbGciOiJFUzI1NiIsImtpZCI6IjBiNDk4ZGRlMDkxNzJhZGE3MDFkMDdlYjZmOTg2N2FkIiwidHlwIjoid2FsbGV0LWF0dGVzdGF0aW9uK2p3dCJ9.eyJpc3MiOiJodHRwczovL3dhbGxldC1wcm92aWRlci5leGFtcGxlLm9yZyIsInN1YiI6InZiZVhKa3NNNDV4cGh0QU5uQ2lHNm1DeXVVNGpmR056b3BHdUt2b2dnOWMiLCJhYWwiOiJodHRwczovL3RydXN0LWxpc3QuZXUvYWFsL2hpZ2giLCJjbmYiOnsiandrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiNEhOcHRJLXhyMnBqeVJKS0dNbno0V21kblFEX3VKU3E0Ujk1Tmo5OGI0NCIsInkiOiJMSVpuU0IzOXZGSmhZZ1MzazdqWEU0cjMtQ29HRlF3WnRQQklScXBObHJnIn19LCJhdXRob3JpemF0aW9uX2VuZHBvaW50IjoiaHR0cHM6Ly93YWxsZXQtc29sdXRpb24uZGlnaXRhbC1zdHJhdGVneS5ldXJvcGEuZXUvYXV0aG9yaXphdGlvbiIsInJlc3BvbnNlX3R5cGVzX3N1cHBvcnRlZCI6WyJ2cF90b2tlbiJdLCJyZXNwb25zZV9tb2Rlc19zdXBwb3J0ZWQiOlsiZm9ybV9wb3N0Lmp3dCJdLCJ2cF9mb3JtYXRzX3N1cHBvcnRlZCI6eyJkYytzZC1qd3QiOnsic2Qtand0X2FsZ192YWx1ZXMiOlsiRVMyNTYiLCJFUzM4NCJdfX0sInJlcXVlc3Rfb2JqZWN0X3NpZ25pbmdfYWxnX3ZhbHVlc19zdXBwb3J0ZWQiOlsiRVMyNTYiXSwicHJlc2VudGF0aW9uX2RlZmluaXRpb25fdXJpX3N1cHBvcnRlZCI6ZmFsc2UsImNsaWVudF9pZF9zY2hlbWVzX3N1cHBvcnRlZCI6WyJlbnRpdHlfaWQiXSwiaWF0IjoxNzQwMTU4MDQ3LCJleHAiOjE3NDAxNTgxNjd9.paU3FOET8nraQxuesBXD9gw57DL5HfDzkeboKAOinyh5L2MmLwqvRtrSWK8S7qMRWYmdzR-gHMpmebIH7gGE5w
OAuth-Client-Attestation-PoP: eyJhbGciOiJFUzI1NiIsInR5cCI6Im9hdXRoLWNsaWVudC1hdHRlc3RhdGlvbi1wb3Arand0In0.eyJpc3MiOiIgaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCJhdWQiOiJodHRwczovL2FzLmV4YW1wbGUuY29tIiwianRpIjoiZDI1ZDAwYWItNTUyYi00NmZjLWFlMTktOThmNDQwZjI1MDY0IiwiaWF0IjoxNzQwMTU4NjE3LCJleHAiOjE3NDAxNTg3Mzd9.B0KOkGi9vMxf3H2Y8rrF-mdLNsuluTvAUbjFfL1Hi-gdaPW7-8ziS9uVh7aTnSAHKWzMfkZLv5q-bxhkglR4PA

grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
&redirect_uri=https://start.wallet.example.org/cb

Step 11 (Token Response): The PID/(Q)EAA Provider validates the request. If successful, the Issuer provides the Wallet Instance with an Access Token and, optionally, a Refresh Token, both bound to the DPoP key.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
    "access_token": "eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImM5NTBjMGU2ZmRlYjVkZTUwYTUwMDk2YjI0N2FmMDNjIn0.eyJpc3MiOiJodHRwczovL2VhYS1wcm92aWRlci53YWxsZXQuaXB6cy5pdCIsInN1YiI6ImQ0ZTBiYjM4N2FhMjU1NmZmMzA2OTI1ZmRmYjlhNzY1IiwiYXVkIjoiaHR0cHM6Ly9lYWEtcHJvdmlkZXIud2FsbGV0LmlwenMuaXQvY3JlZGVudGlhbCIsImlhdCI6MTczOTk1Mjk0OCwiZXhwIjoxNzM5OTUzNTQ4LCJqdGkiOiJmOTY1NWNlYi1jNjVjLTQwMjUtOTM3OC1iNjY3MmI2MTQ5YmciLCJjbGllbnRfaWQiOiI0N2I5ODIzNjk3OTFkMDgwMDNhNzI4M2YwNTljYjBkMSIsImNuZiI6eyJqa3QiOiI5NTE1NzRhZWUxYmI3OTA3YWUxZWMzMTA5ZGIyYjIyNSJ9fQ.XQ3TAo69f2iPNJuMYAS5HdOSN8G5wmIRMcSR6ocLEHdDgTUNI0TrMk-KapG4fvu5_bdZkjWBJvbjXeuP-Jngpg",
    "refresh_token": "eyJ0eXAiOiJydCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImM5NTBjMGU2ZmRlYjVkZTUwYTUwMDk2YjI0N2FmMDNjIn0.eyJpc3MiOiJodHRwczovL2VhYS1wcm92aWRlci53YWxsZXQuaXB6cy5pdCIsImNsaWVudF9pZCI6IjQ3Yjk4MjM2OTc5MWQwODAwM2E3MjgzZjA1OWNiMGQxIiwiYXVkIjoiaHR0cHM6Ly9lYWEtcHJvdmlkZXIud2FsbGV0LmlwenMuaXQiLCJpYXQiOjE3Mzk5NTI5NDgsIm5iZiI6MTczOTk1MzU0OCwiZXhwIjoxNzQyMzcyNzQ4LCJhdGgiOiJmVUh5TzJyMlozRFo1M0VzTnJXQmIweFdYb2FOeTU5SWlLQ0Fxa3NtUUVvIiwianRpIjoiYzY5NTVjZWItYzY1Zi00MDI1LTkzNzgtYjY2NzJiNjE0NWNmIiwiY25mIjp7ImprdCI6Ijk1MTU3NGFlZTFiYjc5MDdhZTFlYzMxMDlkYjJiMjI1In19.qiGM6E-7zci2-3Nnk4OMD7Tv_leUcRPsFsqaBHDHxEEzsGXLNh9qDbLIBk9sujZGVT9xs-28jZhwD6VT-MGTGw",
    "token_type": "DPoP",
    "expires_in": 3600,
    "authorization_details": [
      {
        "type": "openid_credential",
        "credential_configuration_id": "EuropeanDisabilityCard",
        "credential_identifiers": [ "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": 1739952948,
    "exp": 1739953548,
    "jti": "f9655ceb-c65c-4025-9378-b6672b6149bg",
    "client_id": "47b982369791d08003a7283f059cb0d1",
    "cnf": {
      "jkt": "951574aee1bb7907ae1ec3109db2b225"
    }
}

The non-normative example of the DPoP Refresh Token is given below.

{
    "typ": "rt+jwt",
    "alg": "ES256",
    "kid": "c950c0e6fdeb5de50a50096b247af03c"
}
{
  "iss": "https://eaa-provider.example.org",
  "sub": "d4e0bb387aa2556ff306925fdfb9a765",
  "aud": "https://eaa-provider.example.org",
  "iat": 1739952948,
  "exp": 1742372748,
  "nbf": 1739953548,
  "ath": "fUHyO2r2Z3DZ53EsNrWBb0xWXoaNy59IiKCAqksmQEo",
  "jti": "c6955ceb-c65f-4025-9378-b6672b6145cf",
  "client_id": "47b982369791d08003a7283f059cb0d1",
  "cnf": {
    "jkt": "951574aee1bb7907ae1ec3109db2b225"
  }
}

Step 12 (Nonce Request): According to Section 7.1 of [OpenID4VCI], the Wallet Instance sends an HTTP POST request to the Nonce Endpoint to obtain a fresh c_nonce that can be used to create the proof of possession of key material for the subsequent request to the Credential Endpoint.

Below is a non-normative example of a Nonce Request:

POST /nonce HTTP/1.1
Host: eaa-provider.example.org
Content-Length: 0

Step 13 (Nonce Response): The PID/(Q)EAA Provider provides the c_nonce 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 16 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.

Below is a non-normative example of a Nonce Response:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
    "c_nonce": "ts_EtUQs0ieiIS1NYNBHEQSoy3ct4gpy-4FZKwHilkY"
}

Steps 14-15 (DPoP Proof for Credential Endpoint): The Wallet Instance for requesting the Digital Credential creates a proof of possession with c_nonce obtained in Step 13 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 16 (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). 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:

  1. the JWT proof MUST include all required claims as specified in the table of Section Token Request;

  2. The key proof MUST be explicitly typed using header parameters as defined for the respective proof type;

  3. The header parameter alg MUST indicate a registered asymmetric digital signature algorithm, and MUST NOT be set to none;

  4. The signature on the key proof MUST be verified using the public key specified in the header parameter.

  5. The header parameter MUST NOT contain a private key.

  6. 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
{
    "credential_identifier": "DisabilityCard",
    "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 JWT 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 17-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. The PID/(Q)EAA Provider MUST validate the proof of possession for the key material the new Credential SHALL be bound to, according to OpenID4VCI Section 8.2.2. If all checks succeed, the PID/(Q)EAA Provider creates a new Credential bound to the key material and provides it to the Wallet Instance. The Wallet Instance MUST perform the following checks before proceeding with the secure storage of the PID/(Q)EAA:

  1. It MUST check that the PID/(Q)EAA Credential Response contains all the mandatory parameters and values are validated according to Table of the Credential response parameters.

  2. It MUST check the PID/(Q)EAA 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 the kid header of the SD-JWT.

  3. It MUST check that the received PID/(Q)EAA (in credential claim) matches the requested credential type and complies with the specific schema of that Credential defined in PID/(Q)EAA Data Model.

  4. It MUST process and verify the PID/(Q)EAA in SD-JWT VC format (according to SD-JWT Section 5.) or MDOC CBOR format.

  5. It MUST verify the Trust Chain in the header of SD-JWT VC to verify that the PID/(Q)EAA Provider is trusted.

If the checks above are successful, the Wallet Instance requests the User's consent to store the Digital Credential. Upon receiving consent, the Wallet Instance securely stores the PID/(Q)EAA.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
    "credentials": [
        {
            "credential": "eyJ0eXAiOiJ2YytzZC1qd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImM5NTBjMGU2ZmRlYjVkZTUwYTUwMDk2YjI0N2FmMDNjIn0.eyJfc2QiOlsiQ1JJQkdpbWhhbE1TSzhLZUxmNzg2N0w4cHV6MEZnRTVaS1VXLW12N0hiYyIsIlhhZjVJZFVGc0UzYWtabEszT0E5d3dHcjJKcVAwUU01M3BBY2hiempRZmMiLCJjR2FuQVdySG9WQVoyalBhNXk0SzE3U0xpYWFKcGRNUF9PdnBmTGx0VWJjIiwiNEFuZU1ZVVAxRWh3emRHdkRQOEhobnRaRGN1ejZrOHhHWVJ0NXo0SHh0SSIsIjRuYTVXSHRMYzdrYnNxdHFVaHd6WXdVdUQtY3hKVmdENmRaLTl0ZUdhZ3MiLCJiZS10a2U3YVU0WmhDNWUxcGZqRjcxUWpFRzRsZG1IaFRoUFl1TnQyOHo0IiwiSnNkaHhTMWRVTTJaN29MUmZYWVJvOFFEaDJ4M1dQNkdILUJnY21DdzJGayIsIlVobXBRSy1HS3hzaHJwXzZwYVpfZzROVG5fX29aeVdOb01zTGNaMUhlMjgiLCJOdDdQU3RxMkEyWkliUHBHdTJpdmVSek9rbWpYUEN1V0RBdy0tdktSQTBjIiwiV3Rtck5JVzFTVkN0UnZNUF9UM2YtRGlhRUdHNS1iVk5rWGJRckowRnpzRSJdLCJleHAiOjE3NDY1MTU5NzIsImlzcyI6Imh0dHBzOi8vZWFhLXByb3ZpZGVyLmlwenMuaXQiLCJzdWIiOiJOemJMc1hoOHVEQ2NkN25vV1hGWkFmSGt4WnNSR0M5WHMiLCJzdGF0dXMiOnsic3RhdHVzX2F0dGVzdGF0aW9uIjp7ImNyZWRlbnRpYWxfaGFzaF9hbGciOiJzaGEtMjU2In19LCJ2Y3QiOiJEaXNhYmlsaXR5Q2FyZCIsIl9zZF9hbGciOiJzaGEtMjU2IiwiY25mIjp7Imp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6InBWVTNqYXR1NGEzdGs5Yzlhb3dWZ0x5QkJfcko3TS0zV2xqazFlalV6MkUiLCJ5IjoiVEw1T052Ui1JZ2FybmdyejVqZHZzcG9mZnpGd2NqUFJ0RlVrZW5lSEVJMCJ9fX0.v9ynFXhKXPOhQSMmuLvIBKRWfPEPDf4QwDoNmDOjMROxr5J4Hshh9mBEM5qohH_PDE62i1TLc36C65jFYa7x3A~WyIwQUx5SzRfUi1aVUpTekVKdW5HTFdRIiwiaWF0IiwiMTc0NzExOTU5NSJd~WyItT25uM29FcGh6TDNncHJUcVF0YUd3IiwiZG9jdW1lbnRfbnVtYmVyIiwiMDAwMDAwMDIiXQ~WyJ2bmtVX2tJV2RSa1dPZzBoNlRYcDd3IiwiZ2l2ZW5fbmFtZSIsIk1hcmlvIl~WyJvRUdnaVZQaXV1dEJVby1wcTd6WURBIiwiZmFtaWx5X25hbWUiLCJSb3NzaSJd~WyJGVU1iQm5hLWhlLUlaWTZkOVZ1UkNBIiwiYmlydGhfZGF0ZSIsIjE5ODAtMDEtMTAiXQ~WyJjQ0ZDeXljV1J4alZINkZURVR5OTd3IiwidGF4X2lkX2NvZGUiLCJSU1NNUkE4MFIwMUg1MDFCIl0~WyJVSEFhaWZ1bzloTW9pbkVDU0loOG9RIiwiZXhwaXJ5X2RhdGUiLCIyMDMwLTAxLTEwIl~WyJ3TW1xYkkzTFRPMDVLajFoLXNpWWhRIiwiY29uc3RhbnRfYXR0ZW5kYW5jZV9hbGxvd2FuY2UiLCIwIl0~WyJBODVjeFI1REZyOElfaFZFQTZqZGNBIiwibGlua19xcl9jb2RlIiwiaHR0cHM6Ly9xci5leGFtcGxlLmNvbSJd~WyJHWHRYNXNueTctVEVpblhZajNMdGdBIiwicG9ydHJhaXQiLCIvOWovNEFBUVNrWkpSZ0FCQVFFQkxBRXNBQUQvNFFCV1JYaHBaZ0FBVFUwQUtnQUFBQWdBQkFFYUFBVUFBQUFCQUFBQVBnRWJBQVVBQUFBQkFBQUFSZ0VvQUFNQUFBQUJBQUlBQUFJVEFBTUFBQUFCQUFFQUFBQUFBQUFBQUFFc0FBQUFBUUFBQVN3QUFBQUIvKzBBTEZCb2IzUnZjMmh2Y0NBekxqQUFPRUpKVFFRRUFBQUFBQUFQSEFGYUFBTWJKVWNjQVFBQUFnQUVBUC9oRElGb2RIUndPaTh2Ym5NdVlXUnZZbVV1WTI5dEwzaGhjQzh4TGpBdkFEdy9lSEJoWTJ0bGRDQmlaV2RwYmowbjc3dS9KeUJwWkQwblZ6Vk5NRTF3UTJWb2FVaDZjbVZUZWs1VVkzcHJZemxrSno4K0NqeDRPbmh0Y0cxbGRHRWdlRzFzYm5NNmVEMG5ZV1J2WW1VNmJuTTZiV1YwWVM4bklIZzZlRzF3ZEdzOUowbHRZV2RsT2pwRmVHbG1WRzl2YkNBeE1DNHhNQ2MrQ2p4eVpHWTZVa1JHSUhodGJHNXpPbkprWmowbmFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1UazVPUzh3TWk4eU1pMXlaR1l0YzNsdWRHRjRMVzV6SXljK0Nnb2dQSEprWmpwRVpYTmpjbWx3ZEdsdmJpQnlaR1k2WVdKdmRYUTlKeWNLSUNCNGJXeHVjenAwYVdabVBTZG9kSFJ3T2k4dmJuTXVZV1J2WW1VdVkyOXRMM1JwWm1Zdk1TNHdMeWMrQ2lBZ1BIUnBabVk2VW1WemIyeDFkR2x2YmxWdWFYUStNand2ZEdsbVpqcFNaWE52YkhWMGFXOXVWVzVwZEQ0S0lDQThkR2xtWmpwWVVtVnpiMngxZEdsdmJqNHpNREF2TVR3dmRHbG1aanBZVW1WemIyeDFkR2x2Ymo0S0lDQThkR2xtWmpwWlVtVnpiMngxZEdsdmJqNHpNREF2TVR3dmRHbG1aanBaVW1WemIyeDFkR2x2Ymo0S0lEd3ZjbVJtT2tSbGMyTnlhWEIwYVc5dVBnb0tJRHh5WkdZNlJHVnpZM0pwY0hScGIyNGdjbVJtT21GaWIzVjBQU2NuQ2lBZ2VHMXNibk02ZUcxd1RVMDlKMmgwZEhBNkx5OXVjeTVoWkc5aVpTNWpiMjB2ZUdGd0x6RXVNQzl0YlM4blBnb2dJRHg0YlhCTlRUcEViMk4xYldWdWRFbEVQbUZrYjJKbE9tUnZZMmxrT25OMGIyTnJPamxqTmpabVpUZGxMVFkzWTJRdE5ETTRZeTA1WlRobUxUSXdPREE1TkRObU9UWTJaVHd2ZUcxd1RVMDZSRzlqZFcxbGJuUkpSRDRLSUNBOGVHMXdUVTA2U1c1emRHRnVZMlZKUkQ1NGJYQXVhV2xrT2pSaE16ZzBZVFUxTFdJek1UZ3ROR05rWVMwNE4yVXpMVE14TVRZd00yTmhaVEUzT0R3dmVHMXdUVTA2U1c1emRHRnVZMlZKUkQ0S0lEd3ZjbVJtT2tSbGMyTnlhWEIwYVc5dVBnbzhMM0prWmpwU1JFWStDand2ZURwNGJYQnRaWFJoUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lBb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUFvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lBb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUFvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lBbzhQM2h3WVdOclpYUWdaVzVrUFNkM0p6OCsvOXNBUXdBRkF3UUVCQU1GQkFRRUJRVUZCZ2NNQ0FjSEJ3Y1BDd3NKREJFUEVoSVJEeEVSRXhZY0Z4TVVHaFVSRVJnaEdCb2RIUjhmSHhNWElpUWlIaVFjSGg4ZS85c0FRd0VGQlFVSEJnY09DQWdPSGhRUkZCNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlLzhBQUVRZ0JhQUZvQXdFUkFBSVJBUU1SQWYvRUFCMEFBUUFCQlFFQkFRQUFBQUFBQUFBQUFBQUdBUVVIQ0FrRUFnUC94QUJDRUFFQUFRTUNBZ01OQlFVSEJRQUFBQUFBQVFJREJBVUdCeEVoTVZFSUVoTVVGeUpCVm1GeG9hVFNRb0dSa3NFak1rT0NvaFVXWW5LRHNzSVlObEoxcy8vRUFCWUJBUUVCQUFBQUFBQUFBQUFBQUFBQUFBQUJBdi9FQUJZUkFRRUJBQUFBQUFBQUFBQUFBQUFBQUFBUkFmL2FBQXdEQVFBQ0VRTVJBRDhBM0xBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCNXRTejhMVE1HN25hamwyTVRGczA5OWN2WHJrVVVVUjJ6TTlFQXdudmZ1bHRwNlZjcnh0dDRPVHIxNm5uSGh1ZmdNZm43S3FvbXFyN3FlWHRJTVY2MTNTWEVQTnVUT0JScEdsMGVpTFdOTjJxUHZybVkrQ3dXWHk5Y1ZlLzc3KzgxUHU4UXNjdjloQmV0RjdwTGlIaFhJblBvMGpWS1BURjNHbTFWUDMwVEVmQWd5cHNqdWx0cDZyY294dHlZT1RvTjZybEhodWZoOGZuN2FxWWlxbjc2ZVh0U0RObW01K0ZxZUZhenRPeTdHWGkzcWUrdDNyTnlLNks0N1ltT2lRZWtBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFTTRyOFJkQzRlYUY0OXFkVTM4dTl6cHc4SzNWRVhMOVVmN2FZOU5VOUVlMmVVQTB2NGs4UXR6YisxT2NyWE15ZkZxS3BuSHdiVXpGaXhIc3A5TlgrS2VjKzdxVVJKUUFBQUJMZUczRUxjMndkVGpLMFBNbnhhdXFKeU1HN016WXZ4N2FmUlYvaWpsUHY2a0c2SENqaUxvWEVQUXZIdE1xbXhsMmVWT1poWEtvbTVZcW4vZFRQb3Fqb24yVHpoQk13QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVdQZm01OU4yZHRYTzNEcXRmTEh4YU9jVVJQblhhNTZLYUtmYlZQS1BqNkFhRWI4M1ZxKzg5elpXdjZ6ZTcvSXZ6eW90MHo1bGkzSDd0dWlQUlRIeG5uTTlNcUxFb0FBQUFBQXZ1dzkxYXZzemMyTHIralh1OHlMRThxN2RVK1pmdHorOWJyajAwejhKNVRIVENEZmZZZTU5TjNqdFhCM0RwVmZQSHlxT2MwVFBuV3E0NktxS3ZiVFBPUGo2VUY4QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQnFSM1l1OHE5VDNkajdReGJzK0o2VFRGM0ppSjZLOGl1bm5IUC9MUk1mZlhLNE1ES0FBQUFBQUFBTTg5eDF2S3ZUTjNaRzBNcTdQaWVxMHpkeG9tZWlqSW9wNXp5L3pVUlAzMFFtamJkQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCK2VUZHQyTWU1ZnUxZDdidDB6WFZQWkVSemtIT1RjK3JYdGUzSHFXdDVGVXpkejhxNWtWZnpWVE1SOTBjbys1UmJsQUFBQUFBQUFGeDJ4cTE3UWR4NmJyZVBWTVhjREt0NUZQOHRVVE1mZkhPUHZRZEc4YTdidjQ5dS9hcTc2M2NwaXVtZTJKam5DRDlBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVI3aVhmcXh1SFc1TWlpZVZWdlNzcXFtZmJGcW9ITytpT1ZGTWRrUkRRcUFBQUFBQUFBQ2xjYzZLbzdZbUFkRU9HbCtySjRkYmJ5SzU1MVhOS3hhcXA5czJxV1JJUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFXWGZtSlZxR3lOZHdhSTUxNUdtNUZxbVBiVmJxaUFjNktPbWltWjdJYUZRQUFBQUFBQUFVcjZLS3Bqc2tIUmZZZUpWcCt5TkN3YTQ1VjQrbTQ5cXFQYlRicGlXUmVnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVVxaUppWW1PY0E1NThUZHYzTnJjUU5iMEt1aWFhY1hNcjhEempydFZUMzF1ZnkxUW9qaWdBQUFBQUFBQ1I4TXR2M04wY1FORTBLaWlhcWNyTW84TnlqcXRVejMxeWZ5MHlnNkdVeEVSRVJIS0VGUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBYTNkMlRzV3UvalltKzlQc3pWT1BUR0xxVVV4L0Q1L3M3ays2Wm1tWi94VTlpNE5ZRkFBQUFBQUFBR3ovY2JiRnJzWTJYdnZVTE0wemtVemk2YkZVZncrZjdTNUh2bUlwai9BQzFkcWFOa1VBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFIbjFIQ3hkUndMK0JuV0tNakZ5TGRWcTlhcmpuVFhSVkhLWW4yVEFOSGVPWEREUDRkN2hud1ZGM0kwSExybWNIS21PZmUrbndWYytpdU8zN1VkUGJFVVk1VUFBQUFBQVpHNEc4TU0vaUp1R1BDMFhjZlFjU3VKenNxSTVkOTZmQlVUL3dDYzl2Mlk2ZXlKZzNpMDdDeGRPd0xHQmcyS01mRng3ZE5xemFvamxUUlJUSEtJajJSQ0QwQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE4RzRORzB2WDlJeU5KMWpDczV1RmtVOTdkczNZNXhWSDZUSFhFeDB4UFVEVTdpMzNQbXZiZXUzdFMyalRlMXZTZWMxZUx4MDVWaU96bC9FajJ4NTNiSHBXakNOeWl1M2NydDNLYXFLNko1VjAxUnlxcG5zbUo2WWxSOGdBQStyZEZkeTVSYnQwMVYxMXp5b3Bwam5WVlBaRVIweklNM2NKTzU4MTdjTjJ6cVc3cWIyaWFUemlyeGVlakt2eDJjdjRjZTJmTzdJOUtVYlk3ZjBiUzlBMGpIMG5SOEt6aFlXUFQzdHF6YWpsRk1mck05Y3pQVE05YUQzZ0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBY3dlRFU5WjBqVEtacTFMVk1IQ3Bqcm5JeUtMY2YxVEFJSnJPQndlNGxabHpGeWIyM2RYejZQTjhKajVWRk9SSHVyb21LcCtNQWhldGR5OXRYSXJtdlNkd2F4cDhUOWk3RkYrbVB4aUorSzBXYi9wV283Ly9BTDVxNzMvMWtjLy9BS0ZGNTBYdVh0cTQ5Y1Y2dHVEV05RaVBzV29vc1V6K0VWVDhTaWFhTmdjSHVHdVpieGNhOXQzU00rdnpmQ1pHVlJWa1Q3NjY1bXFQaENDZDZack9rYW5URldtNnBnNXRNOVU0K1JSY2orbVpCNytZQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFMSnZEZG0zZG82ZC9hRzR0V3h0UHNUUEtqd2xYT3E1UFpSVEhuVlQ3SWlRWWIxM3VvdHM0OTJxalJ0dTZycU1SMVhMMWRHUFRWN284NnJsNzRoWUlacTNkUmJvdmQ5R21iYjBqRXBucW0vZHVYNm8vRHZZSUlocTNIdmlobnhWVFRyOXJDb243T0poMjZPWDMxUlZQeElJanErK041NnZFeHFXNjlieXFaNjZhczJ1S2Z5eE1SOEFSKzVNM0s1cnVmdEtwKzFYNTAvaktpbnBpZlRIVlBZQ1JhUHZuZW1rVVJiMHpkbXQ0dHVPcWlqTnJtbVA1Wm1ZUVhmeXZjVGU4NzMrK3VxOHZmUnovQUI3MGd0R3NiNTNwcTlFMjlUM1pyZVZibnJvcnphNHBuK1dKaUFSMzB6UHBucm50VVZ0ek51dUs3ZjdPcVB0VWViUDR3Q1FhUnZqZWVrUkVhYnV2VzhXbU9xbW5Ocm1uOHN6TWZCQkx0SjQ5OFVNQ0thYXRmdFp0RWVqTHc3ZGZQNzZZcG40a0V2MG51b3QwV2U5alU5dDZSbDB4MXpZdTNMRlUvajMwRUV6MEx1b3RzNUYybWpXZHZhcnAwVDEzTE5kR1JUSDNlYlZ5OTBTUVprMmZ1emJ1N3RPL3REYnVyWTJvV0lubFg0T3JsVmJuc3JwbnpxWjlreENDOWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQWhuR0hmdUR3OTJmZDFqSW9wdjVkeXJ3T0ZqVFZ5OE5kbU9jUlBaVEVkTXoyUjJ6QU5HTjI3ajFuZFd1WHRaMTdPdVptWmRuOTZyb3BvcDlGRkZQVlRUSG9pUGpQU290S2dBQUFBQUFBQUFBQUFBQzdiUzNIck8xZGNzNnpvV2Rjdzh5MVA3MVBUVFhUNmFLNmVxcW1leWZoUFNnM240UGI5d2VJV3o3V3NZOUZOakx0MWVCemNhS3VmZ2JzUnptSTdhWmpwaWV5ZTJKUVRNQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUdtZmRkN2l2YXR4VHEwZUxremk2TmowV2FLWW5vOEpjaUs2NnZmeW1pUDVWd1liVUFBQUFBQUFBQUFBQUFBQUFabDdrVGNWN1NlS2RPanpjbU1YV2NldXpYVE05SGhMY1RYUlY3K1VWeC9NbWpjdEFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFucUJvRnh5ditNY1lkMTNPZlZxZHlqOHNSVC94WEJERkFBQUFBQUFBQUFBQUFBQUFFejRHMy9GK01PMUxuUHIxTzNSK2FKcC81Sm8zOWpxUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUpCenM0aDVIamUvOEFjV1Z6NStGMVhLcWlmOVdwUllsQUFBQUFBQUFBQUFBQUFBQUY5NGVaSGltLzl1NVhQbDRMVmNXcVovMWFVSFJPRUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUZLcGlLWm1laUk2UWMyZFV2VGthbmw1RTlNM2NpNWMvTlhNL3FvOHlnQUFBQUFBQUFBQUFBQUFBRDA2WGVuSDFQRXlJNkp0WkZ1NStXdUovUkIwbXBtSnBpWTZZbnBRVkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQjRkd1gvRmRDejhtWjVSYXhydGY0VVRQNkE1dVVUem9wcW5ybUlsb1ZBQUFBQUFBQUFBQUFBQUFBQlN1ZVZGVlVkY1JNZzZSN2Z2K05hRmdaTVR6aTdqV3EveG9pZjFaSHVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUJIT0tHUkdKdzMzTGs4K1hnOUp5WmlmYjRLb0hQR21PVk1SMlJFTkNvQUFBQUFBQUFBQUFBQUFBQUtWUnpwbU8ySmdIUTdoZmtSbDhOOXRaUFBuNFRTY2FabjIrQ3BaRWpBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUJCTzZDeVBGdURHNnJrVHk1NmZYYi9OTVUvcURRdWV1V2hRQUFBQUFBQUFBQUFBQUFBQUZZNjRCdnAzUHVSNHp3WTJyY21lZkxUNkxmNVptbjlHUk93QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFZLzdvckN5Yy9ndHViSHhLS3E3bE9MRjJhYVk1ek5OdXVtdXIrbW1RYUh0QUFBQUFBQUFBQUFBQUFBQUFBRGZEdWRjTEp3T0MyMmNmTG9xb3UxWXMzWXBxamxNVTNLNnE2ZjZhb1pHUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQWZOeWlpN2JxdDNLS2E2S29tS3FhbzV4TVQxeE1BMWI0cGR6ZHFsR3FYdFEySGN4NytGZXFtcU5PdjNmQjEySm43TkZjK2JWVDJSTXhNZFhPVm9nUGtINHErcS93QTlZK3NvZVFmaXI2ci9BRDFqNnloNUIrS3ZxdjhBUFdQcktIa0g0cStxL3dBOVkrc29lUWZpcjZyL0FEMWo2eWg1QitLdnF2OEFQV1ByS0hrSDRxK3Evd0E5WStzb2VRZmlyNnIvQUQxajZ5aDVCK0t2cXY4QVBXUHJLSGtINHErcS93QTlZK3NvZVFmaXI2ci9BRDFqNnloNUIrS3ZxdjhBUFdQcktIa0g0cStxL3dBOVkrc29lUWZpcjZyL0FEMWo2eWg1QitLdnF2OEFQV1ByS0hrSDRxK3Evd0E5WStzb2VRZmlyNnIvQUQxajZ5aWZjTGU1dTFTdlZMT29iOHVZOWpDczFSVk9uV0x2aEs3OHg5bXV1UE5wcDdZaVptZXJuQlJ0SmJvb3RXNmJkdWltaWltSWltbW1PVVJFZFVSQ0Q2QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCLy9aIl0"
        }
    ],
    "notification_id": "dab8ef51-fb43-43a5-a5c1-247c93ddb942"
}

Note

If the requested Credential cannot be issued immediately and requires more time, the PID/(Q)EAA Provider SHOULD support the Deferred Flow (step 24) as specified in Section Deferred Endpoint.

Step 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"
}

Step 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

Refresh Token Flow

To use the the Deferred, Credential Request, and Notification endpoints, the Wallet Instance MUST present a valid DPoP Access Token to the Credential Issuer. However, when these endpoints are used in the Deferred Flow, for re-issuing or notifying the deletion of a Digital Credential, the Access Token might expire, as it is designed to be short-lived and these actions MAY occur days later. To address this, the specification RECOMMENDS the use of Refresh Tokens.

An Access Token obtained as a result of a Refresh Token flow MUST be limited to:

  • the Deferred endpoint to obtain a new Digital Credential after time set in the parameter lead_time or when it is notified as ready to be issued;

  • the Notification endpoint, to notify the deletion of a Digital Credential to the Credential Issuer;

  • the Credential endpoint, to refresh a Digital Credential that is already present in the Wallet Instance (also called Digital Credential re-issuance, see section Re-Issuance Flow).

To mitigate the impact of a stolen Refresh Token, the Refresh Tokens MUST be DPoP. These aspects are detailed and discussed in section Security Considerations.

Figure below shows how to obtain a new DPoP Access Token and a new DPoP Refresh Token to the Token Endpoint.

_images/Refresh-Token-Flow.svg

Fig. 8 Refresh Token Flow

Note

The refresh of a Token may be triggered by different actions (e.g., User deletion of a Digital Credential). In each case, Wallet Instances are supposed to be running and the corresponding cryptographic material unlocked.

Step 1. The Wallet Instance MUST create a fresh DPoP Proof JWT and a fresh Wallet Attestation proof of possession for the token request of the PID/(Q)EAA Provider.

Step 2. To refresh a DPoP-bound Access Token, the Wallet Instance sends a token request using the parameter grant_type set to refresh_token, including the DPoP header and the OAuth Client Attestation headers. A non-normative example of the token request for a DPoP Access Token using a Refresh Token is shown below.

POST /token HTTP/1.1
Host: eaa-provider.example.org
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwieCI6IjR2dDhNdEFISmlsMzBDNnpUTmt2c0VVcnlHTEUtQW5BNkc5LV8xa3l5Rk0iLCJ5IjoiTWdiNTFfbjNSRjNtbHNtS3dMd0xtRUFqVmlJM3Q1bTVWNTI2MFA5MzR3RSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIjoiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0ZWRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOH0.3Tp1ZlZ05PQYeZUHhiZwaQ1etqnwYwoiJHFR_JHb32381lMJL-8o2rE3VZ8X3yuqrGFfCVeP90Ln4J5r8ASIBg
OAuth-Client-Attestation: eyJhbGciOiJFUzI1NiIsImtpZCI6IjBiNDk4ZGRlMDkxNzJhZGE3MDFkMDdlYjZmOTg2N2FkIiwidHlwIjoid2FsbGV0LWF0dGVzdGF0aW9uK2p3dCJ9.eyJpc3MiOiJodHRwczovL3dhbGxldC1wcm92aWRlci5leGFtcGxlLm9yZyIsInN1YiI6InZiZVhKa3NNNDV4cGh0QU5uQ2lHNm1DeXVVNGpmR056b3BHdUt2b2dnOWMiLCJhYWwiOiJodHRwczovL3RydXN0LWxpc3QuZXUvYWFsL2hpZ2giLCJjbmYiOnsiandrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiNEhOcHRJLXhyMnBqeVJKS0dNbno0V21kblFEX3VKU3E0Ujk1Tmo5OGI0NCIsInkiOiJMSVpuU0IzOXZGSmhZZ1MzazdqWEU0cjMtQ29HRlF3WnRQQklScXBObHJnIn19LCJhdXRob3JpemF0aW9uX2VuZHBvaW50IjoiaHR0cHM6Ly93YWxsZXQtc29sdXRpb24uZGlnaXRhbC1zdHJhdGVneS5ldXJvcGEuZXUvYXV0aG9yaXphdGlvbiIsInJlc3BvbnNlX3R5cGVzX3N1cHBvcnRlZCI6WyJ2cF90b2tlbiJdLCJyZXNwb25zZV9tb2Rlc19zdXBwb3J0ZWQiOlsiZm9ybV9wb3N0Lmp3dCJdLCJ2cF9mb3JtYXRzX3N1cHBvcnRlZCI6eyJkYytzZC1qd3QiOnsic2Qtand0X2FsZ192YWx1ZXMiOlsiRVMyNTYiLCJFUzM4NCJdfX0sInJlcXVlc3Rfb2JqZWN0X3NpZ25pbmdfYWxnX3ZhbHVlc19zdXBwb3J0ZWQiOlsiRVMyNTYiXSwicHJlc2VudGF0aW9uX2RlZmluaXRpb25fdXJpX3N1cHBvcnRlZCI6ZmFsc2UsImNsaWVudF9pZF9zY2hlbWVzX3N1cHBvcnRlZCI6WyJlbnRpdHlfaWQiXSwiaWF0IjoxNzQwMTU4MDQ3LCJleHAiOjE3NDAxNTgxNjd9.paU3FOET8nraQxuesBXD9gw57DL5HfDzkeboKAOinyh5L2MmLwqvRtrSWK8S7qMRWYmdzR-gHMpmebIH7gGE5w
OAuth-Client-Attestation-PoP: eyJhbGciOiJFUzI1NiIsInR5cCI6Im9hdXRoLWNsaWVudC1hdHRlc3RhdGlvbi1wb3Arand0In0.eyJpc3MiOiIgaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb20iLCJhdWQiOiJodHRwczovL2FzLmV4YW1wbGUuY29tIiwianRpIjoiZDI1ZDAwYWItNTUyYi00NmZjLWFlMTktOThmNDQwZjI1MDY0IiwiaWF0IjoxNzQwMTU4NjE3LCJleHAiOjE3NDAxNTg3Mzd9.B0KOkGi9vMxf3H2Y8rrF-mdLNsuluTvAUbjFfL1Hi-gdaPW7-8ziS9uVh7aTnSAHKWzMfkZLv5q-bxhkglR4PA

grant_type=refresh_token
&refresh_token=eyJ0eXAiOiJydCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImM5NTBjMGU2ZmRlYjVkZTUwYTUwMDk2YjI0N2FmMDNjIn0.eyJpc3MiOiJodHRwczovL2VhYS1wcm92aWRlci53YWxsZXQuaXB6cy5pdCIsImNsaWVudF9pZCI6IjQ3Yjk4MjM2OTc5MWQwODAwM2E3MjgzZjA1OWNiMGQxIiwiYXVkIjoiaHR0cHM6Ly9lYWEtcHJvdmlkZXIud2FsbGV0LmlwenMuaXQiLCJpYXQiOjE3Mzk5NTI5NDgsIm5iZiI6MTczOTk1MzU0OCwiZXhwIjoxNzQyMzcyNzQ4LCJhdGgiOiJmVUh5TzJyMlozRFo1M0VzTnJXQmIweFdYb2FOeTU5SWlLQ0Fxa3NtUUVvIiwianRpIjoiYzY5NTVjZWItYzY1Zi00MDI1LTkzNzgtYjY2NzJiNjE0NWNmIiwiY25mIjp7ImprdCI6Ijk1MTU3NGFlZTFiYjc5MDdhZTFlYzMxMDlkYjJiMjI1In19.qiGM6E-7zci2-3Nnk4OMD7Tv_leUcRPsFsqaBHDHxEEzsGXLNh9qDbLIBk9sujZGVT9xs-28jZhwD6VT-MGTGw

Step 3. The PID/(Q)EAA Provider validates the request according to the following checks:

  • It MUST validate the OAuth-Client-Attestation-PoP parameter based on Section 4 of [OAUTH-ATTESTATION-CLIENT-AUTH].

  • It MUST validate the DPoP Proof JWT, according to (RFC 9449) Section 4.3.

  • It MUST check that the Refresh Token is not expired, not revoked and is bound to the same set of DPoP key as the ones used in the DPoP Proof JWT.

If the request checks are successful, the PID/(Q)EAA Provider generates a new Access Token and a new Refresh Token and these MUST be both bound to the DPoP key. Both the Access Token and the Refresh Token are then sent back to the Wallet Instance.

A non-normative example of a successful response is shown below.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
    "access_token": "eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFU..",
    "refresh_token": "eyC3fiLdCtqd3QiLCJhbGciOiCL3..",
    "token_type": "DPoP",
    "expires_in": 3600,
}

If the Refresh Token is expired or invalid, the PID/(Q)EAA Provider MUST issue an error, using the error type member set to invalid_grant. Therefore, to obtain the Digital Credential an issuance flow authenticating the User is required, as defined in Section Low-Level Issuance Flow.

Security Considerations

To mitigate the risks of Refresh Token compromise, the following protections are required:

  • Confidentiality of Refresh Tokens MUST be guaranteed in transit and storage.

  • TLS-protected connections MUST be used for token transmission.

  • Refresh tokens MUST be unguessable and secure from modification.

  • Authorization Servers MUST implement the following mechanism to detect replay attacks:

    • Sender-Constrained Tokens: Crypto-graphically bind the Refresh Token to the Wallet Instance according to RFC 9449. Access Tokens and Refresh Tokens MUST be bound to the same DPoP key. The DPoP Proof of the refresh token is required to refresh an Access Token. The same DPoP key MUST be used to generate Access Token DPoP Proofs in all the Credential Requests.

  • Limiting the use of Refresh Token: As specified in OPENID4VC-HAIP: “Credential Issuers should be mindful of how long the usage of the refresh token is allowed to refresh a Credential, as opposed to starting the issuance flow from the beginning. For example, if the User is trying to refresh a Credential more than a year after its original issuance, the usage of the refresh tokens is NOT RECOMMENDED.” In this specification a new Digital Credential obtained performing the re-issuance flow SHOULD have the same expiration of the refreshed one. Thus, this specification does not allow for infinite refresh of Digital Credential with a Refresh Token. Once a Digital Credential expires, the User MUST complete the entire issuance process again, to obtain a new Digital Credential. This specification recommends to set a Refresh Token expiration duration, based on the sensitivity of the associated grant.

Note

Short-lived Wallet Attestations and DPoP: Following the specification draft OAuth 2.0 Attestation Based Client Authentication (OAUTH-ATTESTATION-CLIENT-AUTH), the Authorization Server MUST bind the Refresh Token to the Client Instance. To prove this binding the Client Instance MUST use the Client Attestation mechanism when refreshing the Access Token and the Client Instance MUST use the same key that was presented in the cnf claim of the Client Attestation that was used when the Refresh Token was issued. However this requires that all issued Client Attestations MUST be bound to the same key, thus opening to unlinkability issues. In this specification, both OAUTH-ATTESTATION-CLIENT-AUTH and OAuth 2.0 Demonstrating Proof of Possession (DPoP) (RFC 9449) MUST be used. Using DPoP guarantees the binding of the Refresh Token with the Client Instance as stated in section 5 of RFC 9449 "the Refresh Token MUST be bound to the respective public key [...] a Client MUST present a DPoP proof for the same key that was used to obtain the Refresh Token each time that Refresh Token is used to obtain a new Access Token". DPoP ensures that the Refresh Token is bound to the Wallet Instance.

Re-Issuance Flow

Re-issuance involves replacing Digital Credentials already stored in a Wallet Instance with new ones of the same document type. The new Digital Credentials MUST be issued by the same Credential Issuers that originally provided the existing ones to the same Wallet Instance.

To facilitate this, particularly in scenarios where User authentication is not strictly required, a Refresh Token (RT) flow MAY be used (see Section Refresh Token Flow for more details). An Access Token obtained as a result of a Refresh Token flow MUST NOT be used to issue a Digital Credential that is not present in the Wallet Instance (first-time-issuance). The Refresh Token mechanism enables automated Credential replacement, streamlining the process for both the Credential Issuer and the User.

The re-issuance process outlined in this section is limited to the following scenarios:

  • Data model/format technical update;

  • User's attribute set update.

In the first case, the new Digital Credential's Users attribute set will match the original one. For example, a Credential Issuer may need to update the Digital Credential metadata or data format without changing the User's attribute set. In this case, the direct involvement of the User is not mandatory for the replacement and storage of a Digital Credential.

In the second case, Credential Issuers may also need to modify one or more User's attribute values during re-issuance. In this case, the Wallet Instance MUST inform the User that the attribute data set has been changed and MUST then request the User's authorization to store the new Digital Credential.

In both cases, the newly issued Digital Credential MUST have the same expiry date as the previous one.

Re-issuance after Digital Credential expiration MUST always require User authentication.

The following diagram describes the Digital Credential re-issuance flow.

_images/Re-Issuance-Flow.svg

Fig. 9 Re-Issuance Flow Diagram

  1. The flow starts when the User opens the Wallet Instance: this step MAY be triggered by a notification sent by the Credential Issuer, using one of the out-of-band communication contacts registered during the Issuance flow.

  2. A Wallet Instance without valid Status Assertions for a stored Digital Credential MUST retrieve them following the flow described in Section Validity Verification Mechanisms. If one or more Digital Credentials have the credential_status_type set to INVALID, the Wallet Instance MUST verify the credential_status_detail.state claim. If this claim is set to UPDATED or ATTRIBUTE_UPDATED, then the Wallet Instance MUST check if the related Access Tokens are still valid. If the Access Token is valid, then step 3 MAY be skipped.

  3. If the Access Token is expired and the Wallet Instance still has a valid Refresh Token, the Wallet Instance MUST obtain a new Access Token starting a Refresh Token Flow, according to Section Refresh Token Flow. The Refresh Token Flow enables the Wallet Instance to obtain a new Refresh Token and a new DPoP Access Token to refresh the Digital Credential. If the Refresh Token is expired, a new Issuance Flow authenticating the User is required.

  4. The Wallet Instance MUST use a valid DPoP Access Token to retrieve the new Digital Credential requesting it to the Credential endpoint following the steps from 12 to 22 of Figure 9 in Section Low-Level Issuance Flow. When the new Digital Credential is successfully stored in the secure storage, the Wallet Instance MUST delete the previous one.

Note

The credential_status_detail.state set to ATTRIBUTE_UPDATE demonstrates that the User's attribute set, about the refreshed Digital Credential, doesn't match with the stored Digital Credential. In this case, the Wallet Instance MUST request the User's authorization to store the new refreshed Digital Credential. If the credential_status_detail.state is set to UPDATED, only the Credential metadata parameters have changed. In this case, the Wallet Instance SHOULD store the new Digital Credential without requiring explicit user authorization and consent.

Security Considerations

To ensure the integrity and security of the re-issuance process, the following security considerations apply.

  • Access Token limitations: An Access Token obtained as a result of a Refresh Token flow MUST NOT be used for the first-time issuance of a Digital Credential. This ensures that only existing Credentials in the Wallet Instance are updated.

  • Credential expiry: The Credential Issuer MUST set the same expiry date for the re-issued Digital Credential as the previous one. This prevents indefinite Credential renewals without proper User authentication.

  • User consent: For re-issuance processes triggered by attribute changes, User consent MUST be obtained before storing the new Digital Credential. This ensures that the User is aware of and agrees to the updated information.

  • Sender-constrained Refresh Token: Refresh Tokens MUST be cryptographically bound to the Wallet Instance using DPoP protocol. This mitigates the risk of token misuse by ensuring that only the intended Wallet Instance (the same that originally has obtained the Digital Credential) can use that Refresh Token.

Credential Offer Endpoint

The Credential Offer endpoint of a Wallet is used by PID/(Q)EAA Issuer to interact with the User to initiate a Credential Issuance. The custom URL scheme openid-credential-offer:// MUST be used.

Credential Offer

The Credential Offer made by PID/(Q)EAA Issuer consists of a single URI query parameter credential_offer. The Credential Offer URL MAY be included in a QR Code or in an html page with an href button and MUST contain the following mandatory parameters:

Claim

Description

Reference

credential_issuer

It MUST be set with an HTTPS URL that uniquely identifies the PID/(Q)EAA Issuer. The Wallet uses this parameter value to obtain the PID/(Q)EAA Issuer's metadata.

Section 4.1.1 of [OpenID4VCI].

credential_configuration_ids

Array of Strings, each of them specifying a unique identifier of the Credential being described in the credential_configurations_supported map in the PID/(Q)EAA Issuer Metadata.

Section 4.1.1 of [OpenID4VCI].

grants

It MUST contain authorization_code object with the following parameters:

  • issuer_state: REQUIRED. Opaque string created by the PID/(Q)EAA Issuer used to bind the subsequent Authorization Request with the PID/(Q)EAA Issuer. The Wallet MUST include it in the subsequent Authorization Request.

  • authorization_server: CONDITIONAL. String identifying the Authorization Server to use. The value MUST match with one of the values mapped in the authorization_servers array of the PID/(Q)EAA Issuer metadata. It MUST NOT be used if authorization_servers is absent or has no multiple entries.

Section 4.1.1 of [OpenID4VCI].

Credential Offer Response

No response is expected from the Wallet.

Pushed Authorization Request Endpoint

Pushed Authorization Request (PAR) Request

The request to the PID/(Q)EAA authorization endpoint MUST use HTTP Headers parameters and HTTP POST parameters.

The HTTP POST method MUST use the parameters in the message body encoded in application/x-www-form-urlencoded format.

Table 3 PAR http request parameters

Claim

Description

Reference

client_id

MUST be set to the thumbprint of the jwk value in the cnf parameter inside the Wallet Attestation.

RFC 6749

request

It MUST be a signed JWT. The private key corresponding to the public one in the cnf parameter inside the Wallet Attestation MUST be used for signing the Request Object.

OpenID Connect Core. Section 6

The Pushed Authorization 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:

Table 4 http request header parameters

OAuth-Client-Attestation

It MUST be set to a value containing the Wallet Attestation JWT.

OAUTH-ATTESTATION-CLIENT-AUTH.

OAuth-Client-Attestation-PoP

It MUST be set to a value containing the Wallet Attestation JWT Proof of Possession.

OAUTH-ATTESTATION-CLIENT-AUTH.

The JWT Request Object has the following JOSE header parameters:

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 listed in the Section Cryptographic Algorithms and MUST NOT be set to none or any symmetric algorithm (MAC) identifier.

RFC 7516#section-4.1.1.

kid

Unique identifier of the jwk inside the cnf claim of Wallet Attestation as base64url-encoded JWK Thumbprint value.

RFC 7638#section_3.

Note

The parameter typ, if omitted, assumes the implicit value JWT.

The request JWT payload contained in the HTTP POST message is given with the following parameters:

Claim

Description

Reference

iss

It MUST be set to the client_id.

RFC 9126 and RFC 7519.

aud

It MUST be set to the identifier of the PID/(Q)EAA Provider.

RFC 9126 and RFC 7519.

exp

UNIX Timestamp with the expiry time of the JWT. The claim value MUST be not greater than 300 seconds from the issuance time.

RFC 9126 and RFC 7519.

iat

UNIX Timestamp with the time of JWT issuance.

RFC 9126 and RFC 7519.

response_type

MUST be set to code.

RFC 6749

response_mode

It MUST be a string indicating the "response_mode", as specified in [OAUTH-MULT-RESP-TYPE]. It MUST be one of the supported values (response_modes_supported) provided in the metadata of the PID/(Q)EAA Provider. It informs the PID/(Q)EAA Provider of the mechanism to be used for returning parameters from the Authorization Endpoint. In case of HTTP 302 Redirect Response the value MUST be query. In this mode, Authorization Response parameters are encoded in the query string added to the redirect_uri when redirecting back to the Wallet Instance. In case of HTTP POST Response the value MUST be form_post.jwt according to [JARM]. In this mode, Authorization Response parameters are specified into a JWT encoded as HTML form value that is auto-submitted in the user-agent, and thus is transmitted via the HTTP POST method to the Wallet Instance, with the result parameters being encoded in the body using the application/x-www-form-urlencoded format. The action attribute of the form MUST be the Redirection URI of the Wallet Instance. The method of the form attribute MUST be POST.

See [OAUTH-MULT-RESP-TYPE] and [JARM].

client_id

It MUST be set as in the Table of the HTTP parameters.

See Table of the HTTP parameters.

state

Unique session identifier at the client side. This value will be returned to the client in the response, at the end of the authentication. It MUST be a random string composed by alphanumeric characters and with a minimum length of 32 digits. Special characters MUST be considered non-alphanumeric characters as defined in [NIST].

See [OIDC] Section 3.1.2.1.

code_challenge

A challenge derived from the code verifier that is sent in the authorization request.

RFC 7636#section-4.2.

code_challenge_method

A method that was used to derive code challenge. It MUST be set to S256.

RFC 7636#section-4.3.

scope

JSON String. String specifying a unique identifier of the Credential being described in the credential_configurations_supported map in the Credential Issuer Metadata. For example, in the case of the PID, it MUST be set to PersonIdentificationData. It MAY be multivalued, each value MUST be separated by a space.

RFC 6749

authorization_details

Array of JSON Objects. Each JSON Object MUST include the following claims:

  • type: it MUST be set to openid_credential,

  • credential_configuration_id: JSON String. String specifying a unique identifier of the Credential being described in the credential_configurations_supported map in the Credential Issuer Metadata. For example, in the case of the PID, it MUST be set to PersonIdentificationData.

See [RAR RFC 9396] and [OpenID4VCI].

redirect_uri

Redirection URI to which the response is intended to be sent. It MUST be an universal or app link registered with the local operating system, so this latter will provide the response to the Wallet Instance.

See [OIDC] Section 3.1.2.1.

jti

Unique identifier of the JWT that, together with the value contained in the iss claim, prevents the reuse of the JWT (replay attack). Since the jti value alone is not collision resistant, it MUST be identified uniquely together with its issuer.

[RFC 7519].

issuer_state

It MUST be present only in case of issuer initiated flow. It MUST contain the same value contained in the Credential Offer.

[RFC 7519].

Note

If the request cointains scope value and the authorization_details parameter the Credential Issuer MUST interpret these individually. However, if both request the same Credential type, then the Credential Issuer MUST follow the request as given by the authorization details object.

The JOSE header of the Wallet Attestation proof of possession, contained in the HTTP Request headers, MUST contain:

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 listed in the Section Cryptographic Algorithms and MUST NOT be set to none or any symmetric algorithm (MAC) identifier.

RFC 7516#section-4.1.1.

The body of the Wallet Attestation proof of possession JWT, contained in the HTTP Request headers, MUST contain:

Claim

Description

Reference

iss

Thumbprint of the JWK in the cnf parameter.

RFC 9126 and RFC 7519.

aud

It MUST be set to the identifier of the PID/(Q)EAA Provider.

RFC 9126 and RFC 7519.

exp

UNIX Timestamp with the expiry time of the JWT.

RFC 9126 and RFC 7519.

iat

UNIX Timestamp with the time of JWT issuance.

RFC 9126 and RFC 7519.

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].

Pushed Authorization Request (PAR) Response

If the verification is successful, the PID/(Q)EAA Issuer MUST provide the response with a 201 HTTP status code. The following parameters are included as top-level members in the HTTP response message body, using the application/json media type as defined in [RFC 8259].

Claim

Description

Reference

request_uri

The request URI corresponding to the authorization request posted. This URI MUST be a single-use reference to the respective authorization request. It MUST contain some part generated using a cryptographically strong pseudorandom algorithm. The value format MUST be urn:ietf:params:oauth:request_uri:<reference-value> with <reference-value> as the random part of the URI that references the respective authorization request data.

[RFC 9126].

expires_in

A JSON number that represents the lifetime of the request URI in seconds as a positive integer.

[RFC 9126].

If any errors occur during the PAR Request, the Authorization Server MUST return an error response as defined in RFC 9126#section-2.3. The response MUST use application/json as the content type 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.

Below is a non-normative example of an error response.

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "error": "invalid_request",
    "error_description": "The redirect_uri is not valid for the given client"
}

In the following table are listed HTTP Status Codes and related error codes that are supported for the error response:

Status Code

error code

Description

400 Bad Request [REQUIRED]

invalid_request

The PID/(Q)EAA Issuer cannot fulfill the request because of missing parameters, invalid parameters or request malformed. (RFC 6749#section-5.2).

400 Bad Request [REQUIRED]

invalid_scope

The PID/(Q)EAA Issuer cannot fulfill the request because the requested scope is invalid or unknown. (RFC 6749#section-5.2).

401 Unauthorized [REQUIRED]

invalid_client

The PID/(Q)EAA Issuer cannot fulfill the request because of Client Authentication failed (for example in case of unknown client, no parameters Client Authentication included, or unsupported authentication method). (RFC 6749#section-5.2).

405 Method not allowed [OPTIONAL]

-

The PID/(Q)EAA Issuer cannot fulfill the request because POST method was not used in the request. (RFC 9126#section-2.3).

413 Payload Too Large [OPTIONAL]

-

The PID/(Q)EAA Issuer cannot fulfill the request because of the size of the request is higher than permitted limit.(RFC 9126#section-2.3).

429 Too Many Requests [OPTIONAL]

-

The PID/(Q)EAA Issuer cannot fulfill the request because of the numbers requests received is higher than permitted limit.(RFC 9126#section-2.3).

500 Internal Server Error [REQUIRED]

server_error

The PID/(Q)EAA Issuer encountered an internal problem. (RFC 6749#section-4.1.2.1).

503 Service Unavailable [REQUIRED]

temporarily_unavailable

The PID/(Q)EAA Issuer is temporary unavailable. (RFC 6749#section-4.1.2.1).

504 Gateway Timeout [OPTIONAL]

-

The PID/(Q)EAA Issuer cannot fulfill the request within the defined time interval.

Authorization endpoint

The authorization endpoint is used to interact with the PID/(Q)EAA Issuer and obtain an authorization grant. The authorization server MUST first verify the identity of the User that own the credential.

Authorization Request

The Authorization request is issued by the Web Browser in use by the Wallet Instance, the HTTP methods POST or GET are used. When the method POST is used, the parameters MUST be sent using the Form Serialization. When the method GET is used, the parameters MUST be sent using the Query String Serialization. For more details see Section 13 of [OIDC].

The mandatory parameters in the HTTP authentication request are specified in the following table.

Claim

Description

Reference

client_id

It MUST be set as in the Table of the HTTP parameters.

See Table of the HTTP parameters.

request_uri

It MUST be set to the same value as obtained by PAR Response. See Table of the HTTP PAR Response parameters.

[RFC 9126].

Note

In the case of PID issuance, the Wallet Instance MAY include the idphinting parameter as a URL encoded string. This parameter specifies the Identity Provider where the User wishes to authenticate.. See AARC-G061 - A specification for IdP hinting. for more details.

Authorization Response

The authentication response is returned by the PID/(Q)EAA authorization endpoint at the end of the authentication flow.

If the authentication is successful the PID/(Q)EAA Issuer redirects the User by adding the following query parameters as required to the redirect_uri. The redirect URI MUST be an universal or app link registered with the local operating system, so this latter is able to provide the response to the Wallet Instance.

Claim

Description

Reference

code

Unique Authorization Code that the Wallet Instance submits to the Token Endpoint.

[RFC 6749#section-4.1.2], [RFC 7521].

state

The Wallet Instance MUST check the correspondence with the state parameter value in the Request Object. It is defined as in the Table of the JWT Request parameters.

[RFC 6749#section-4.1.2].

iss

Unique identifier of the PID/(Q)EAA Issuer who created the Authentication Response. The Wallet Instance MUST validate this parameter.

[RFC 9207], [RFC 7519, Section 4.1.1.].

If any errors occur during the Authorization Request, the Authorization Server MUST return an error response as defined in RFC 6749#section-4.1.2.1. In case of invalid/missing redirect_uri or client_id Authorization Server MUST inform the User with the error and MUST NOT redirect the User to the redirection URI. If any other error occurs the Authorization Server MUST redirect the User by adding the following query parameters as required to the redirect_uri using the application/x-www-form-urlencoded format:

  • error. The error code.

  • error_description. Text in human-readable form providing further details to clarify the nature of the error encountered.

  • state. The exact value of state parameter contained in the Request Object.

Below is a non-normative example of an error response.

HTTP/1.1 302 Found
Location: https://client.example.com/cb?
 error=invalid_request
 &error_description=Unsupported%20response_type%20value
 &state=fyZiOL9Lf2CeKuNT2JzxiLRDink0uPcd

In case of Authorization Server redirects the User to the redirect_uri HTTP status code 302 (Found) MUST be used. The following error codes are supported for the error response:

Status Code

error code

Description

302 Found [REQUIRED]

invalid_request

The PID/(Q)EAA Issuer cannot fulfill the request because of missing parameters, invalid parameters or request malformed. (RFC 6749#section-4.1.2.1).

302 Found [REQUIRED]

unauthorized_client

The PID/(Q)EAA Issuer cannot fulfill the request because the client is not authorized to request an authorization code. (RFC 6749#section-4.1.2.1).

302 Found [REQUIRED]

server_error

The PID/(Q)EAA Issuer encountered an internal problem. (RFC 6749#section-4.1.2.1).

302 Found [REQUIRED]

temporarily_unavailable

The PID/(Q)EAA Issuer is temporary unavailable. (RFC 6749#section-4.1.2.1).

In case of Authorization Server doesn't redirect the User to the redirect_uri the following HTTP Status Codes are supported for the error response:

Status Code

Description

400 Bad Request [REQUIRED]

The PID/(Q)EAA Issuer cannot fulfill the request because of invalid/missing redirect_uri or client_id parameter.

500 Internal Server Error [REQUIRED]

The PID/(Q)EAA Issuer encountered an internal problem.

503 Service Unavailable [REQUIRED]

The PID/(Q)EAA Issuer is temporary unavailable.

504 Gateway Timeout [OPTIONAL]

The PID/(Q)EAA Issuer cannot fulfill the request within the defined time interval.

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 includes in its HTTP header the DPoP proof parameter. The Authorization Server MUST validate the DPoP proof received at the Token endpoint, according to RFC 9449 Section 4.3. This mitigates the misuse of leaked or stolen Access Tokens/Refresh Tokens at the Credential/Token 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.

The token request contains the following claims:

Claim

Description

Reference

grant_type

REQUIRED. It MUST be set to authorization_code or refresh_token.

[RFC 6749].

code

CONDITIONAL. REQUIRED only if the grant type is authorization_code. Authorization code returned in the Authentication Response.

[RFC 6749].

redirect_uri

CONDITIONAL. REQUIRED only if the grant type is authorization_code. It MUST be set as in the Request Object Table of the JWT Request parameters.

[RFC 67491].

code_verifier

CONDITIONAL. REQUIRED only if the grant type is authorization_code. Verification code of the code_challenge.

Proof Key for Code Exchange by OAuth Public Clients.

refresh_token

CONDITIONAL. REQUIRED only if the grant type is refresh_token. The Refresh Token previously issued to the Wallet Instance.

[RFC 6749].

scope

CONDITIONAL. OPTIONAL only if the grant type is refresh_token. The requested scope MUST NOT include any scope not originally granted by the User, and if omitted is treated as equal to the scope originally granted by the User.

[RFC 6749].

A DPoP Proof JWT is included in the HTTP request using the DPoP header parameter containing a DPoP JWT.

The JOSE header of a DPoP JWT MUST contain at least the following parameters:

JOSE header

Description

Reference

typ

It MUST be equal to dpop+jwt.

[RFC 7515] and [RFC 8725. Section 3.11].

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 none or with a symmetric algorithm (MAC) identifier.

[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.

[RFC 7517] and [RFC 7515].

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 contains the following claims.

Claim

Description

Reference

access_token

REQUIRED. The DPoP-bound Access Token, in signed JWT format, allows accessing the PID/(Q)EAA Credential Endpoint for obtaining the Credential.

[RFC 6749].

refresh_token

OPTIONAL. The DPoP-bound Refresh Token, in signed JWT format, which can be used to obtain a new Access Token at the PID/(Q)EAA Provider Token Endpoint.

[RFC 6749].

token_type

REQUIRED. Type of Access Token returned. It MUST be equal to DPoP.

[RFC 6749].

expires_in

REQUIRED. Expiry time of the Access Token in seconds.

[RFC 6749].

authorization_details

REQUIRED when authorization_details parameter is used to request issuance of a Credential. OPTIONAL when scope parameter is used to request issuance of a Credential. 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. In addition to the claim defined in Table of the JWT Request parameters it MUST include the following claim:

  • credential_identifiers: Array of strings, each uniquely identifying a Credential dataset that is available for the issuance.

[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. The response MUST use the HTTP Content-Type set to 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.

Below is a non-normative example of an error response.

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
    "error": "invalid_client",
    "error_description": "Client authentication failed"
}

In the following table are listed HTTP Status Codes and related error codes that are supported for the error response:

Status Code

error code

Description

400 Bad Request [REQUIRED]

invalid_request

The PID/(Q)EAA Issuer cannot fulfill the request because of missing parameters, invalid parameters or request malformed. (RFC 6749#section-5.2).

400 Bad Request [REQUIRED]

invalid_grant

The PID/(Q)EAA Issuer cannot fulfill the request because the provided authorization code or Refresh Token is invalid, expired, revoked, or does not match the redirection URI used in the authorization request, or was issued to another client. (RFC 6749#section-5.2).

400 Bad Request [REQUIRED]

unsupported_grant_type

The PID/(Q)EAA Issuer cannot fulfill the request because the authorization grant type is not supported. (RFC 6749#section-5.2).

400 Bad Request [REQUIRED]

invalid_dpop_proof

The PID/(Q)EAA Issuer cannot fulfill the request because of invalid DPoP proof. Section 5 of [RFC 9449].

401 Unauthorized [REQUIRED]

invalid_client

The PID/(Q)EAA Issuer cannot fulfill the request because of invalid parameters Client Authentication failed (for example in case of unknown client, no parameters Client Authentication included, or unsupported authentication method). (RFC 6749#section-5.2).

500 Internal Server Error [REQUIRED]

server_error

The PID/(Q)EAA Issuer encountered an internal problem.

503 Service Unavailable [REQUIRED]

temporarily_unavailable

The PID/(Q)EAA Issuer is temporary unavailable.

504 Gateway Timeout [OPTIONAL]

-

The PID/(Q)EAA Issuer cannot fulfill the request within the defined time interval.

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 DPoP JWT MUST contain the following JOSE header parameters and claims.

JOSE header

Description

Reference

typ

It MUST be equal to at+jwt.

[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 none or with a symmetric algorithm (MAC) identifier.

[RFC 7515].

kid

Unique identifier of the jwk used by the PID/(Q)EAA Provider to sign the Access Token.

RFC 7638#section_3.

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.

[RFC 9068], [RFC 7519].

sub

It identifies the subject of the JWT. It MUST be set to the value of the sub field in the PID/(Q)EAA SD-JWT-VC.

[RFC 9068], [RFC 7519] and Section 8 of [OIDC].

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 (cnf.jwk).

[RFC 9068], [RFC 7519] and Section 8 of [OIDC].

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.

[RFC 9068], [RFC 7519. Section 4.1.6].

exp

UNIX Timestamp with the expiry time of the JWT, coded as NumericDate as indicated in RFC 7519.

[RFC 9068], [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.

[RFC 9068], [RFC 7519].

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.

[RFC 9449. Section 6.1] and [RFC 7638].

Refresh Token

A DPoP-bound Refresh Token is provided by the PID/(Q)EAA Token endpoint as a result of a successful token request. The Refresh Token is encoded in JWT format, according to [RFC 7519]. The Refresh 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 DPoP JWT MUST contain the following JOSE header parameters and claims.

JOSE header

Description

Reference

typ

It MUST be equal to rt+jwt.

[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 none or with a symmetric algorithm (MAC) identifier.

[RFC 7515].

kid

Unique identifier of the jwk used by the PID/(Q)EAA Provider to sign the Access Token.

RFC 7638#section_3.

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.

[RFC 9068], [RFC 7519].

sub

It identifies the subject of the JWT. It MUST be set to the value of the sub field in the PID/(Q)EAA SD-JWT-VC.

[RFC 9068], [RFC 7519] and Section 8 of [OIDC].

client_id

The identifier for the Wallet Instance that requested the Access Token; it MUST be equal to the to kid value identifying the public key used in the Wallet Instance, used in the the Wallet Attestation (cnf.jwk).

[RFC 9068], [RFC 7519] and Section 8 of [OIDC].

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.

[RFC 9068], [RFC 7519. Section 4.1.6].

nbf

UNIX Timestamp with the time before which the JWT MUST NOT be accepted for processing, coded as NumericDate as indicated in RFC 7519. It SHOULD be set to the exp claim of the corresponding Access Token.

[RFC 7519. Section 4.1.7].

exp

UNIX Timestamp with the expiry time of the JWT, coded as NumericDate as indicated in RFC 7519.

[RFC 9068], [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.

[RFC 9068], [RFC 7519].

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.

[RFC 9449. Section 6.1] and [RFC 7638].

Nonce endpoint

The Nonce Endpoint provides a c_nonce value useful to create a proof of possession of key material for the request to the Credential Endpoint, as defined in Section 7 of OpenID4VCI.

Nonce Request

The request for a nonce MUST be an HTTP POST without a body addressed to the PID/(Q)EAA Issuer Nonce Endpoint mapped in the Credential Issuer Metadata.

Nonce Response

Nonce Response to the Wallet Instance MUST be sent using application/json media type. In case of Nonce Request successful, the PID/(Q)EAA Provider MUST return HTTP response with a 200 (OK) status code.

As defined in Section 7.2 of OpenID4VCI, the PID/(Q)EAA Issuer MUST make the response uncacheable by adding a Cache-Control header field valued with no-store.

The Nonce Response contains the following parameter:

Claim

Description

Reference

c_nonce

REQUIRED. String containing the nonce value. This value MUST be unpredictable.

Section 7.2 of [OpenID4VCI].

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.

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

credential_identifier

REQUIRED when an Authorization Details of type openid_credential was returned from the Token Response. It MUST NOT be used otherwise. This MUST be set with one of the value obtained in the credential_identifiers claim of the Token Response. It MUST NOT be used if credential_configuration_id is present.

Section 8.2 of [OpenID4VCI].

credential_configuration_id

REQUIRED if credential_identifiers parameter is absent in the Token Response. It MUST NOT be used otherwise. String specifying a unique identifier of the Credential being described in the credential_configurations_supported map in the Credential Issuer Metadata. For example, in the case of the PID, it MUST be set to PersonIdentificationData.

Section 8.2 of [OpenID4VCI].

proof

REQUIRED. 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:

  • proof_type: JSON string denoting the proof type. It MUST be jwt.

  • jwt: the JWT used as proof of possession.

[OpenID4VCI].

transaction_id

CONDITIONAL. REQUIRED only in case of deferred flow. String identifying a deferred issuance transaction.

Section 9.1 of [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 none or to a symmetric algorithm (MAC) identifier.

[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 Nonce 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

credentials

CONDITIONAL. REQUIRED if lead_time and transaction_id are not present. It contains the following parameters:

  • credential: REQUIRED. String containing one issued PID/(Q)EAA. If the requested format identifier is dc+sd-jwt then the credential parameter MUST NOT be re-encoded. If the requested format identifier is mso_mdoc then the credential parameter MUST be a base64url-encoded representation of the issued Credential.

Section 8.3, Annex A2.4 and Annex A3.4 of [OpenID4VCI].

lead_time

CONDITIONAL. REQUIRED if credentials is not present. The amount of time (in seconds) required before making a Deferred Credential Request.

This Specification.

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 credentials parameter is not present.

Section 8.3 of [OpenID4VCI].

transaction_id

CONDITIONAL. REQUIRED if credentials is not present. String identifying a deferred issuance transaction that the Wallet includes in the subsequent Credential Request as defined in Section Deferred Endpoint. It MUST be invalidated after the User obtains the Credential.

Section 8.3 of [OpenID4VCI].

In case of the Credential Request does not contain a valid Access Token, the Credential Endpoint returns an error response such as defined in Section 3 of [RFC 6750]. If any other error occurs, the PID/(Q)EAA Provider MUST return an error response as defined in Section 8.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.

Below is a non-normative example of an error response.

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."
}

In the following table are listed HTTP Status Codes and related error codes that are supported for the error response:

Status Code

error code

Description

400 Bad Request [REQUIRED]

invalid_credential_request

The PID/(Q)EAA Issuer cannot fulfill the request because of missing parameters, invalid parameters or request malformed. Section 8.3.1 of [OpenID4VCI].

400 Bad Request [REQUIRED]

unsupported_credential_type

The PID/(Q)EAA Issuer cannot fulfill the request because the requested Credential type is not supported. Section 8.3.1 of [OpenID4VCI].

400 Bad Request [REQUIRED]

unsupported_credential_format

The PID/(Q)EAA Issuer cannot fulfill the request because the requested Credential Format is not supported. Section 8.3.1 of [OpenID4VCI].

400 Bad Request [REQUIRED]

invalid_proof

The PID/(Q)EAA Issuer cannot fulfill the request because the proof parameter in the Credential Request is invalid or absent. Section 8.3.1 of [OpenID4VCI].

400 Bad Request [REQUIRED]

invalid_nonce

The PID/(Q)EAA Issuer cannot fulfill the request because the proof parameter in the Credential Request uses an invalid nonce. Section 8.3.1 of [OpenID4VCI].

400 Bad Request [REQUIRED]

invalid_encryption_parameters

The PID/(Q)EAA Issuer cannot fulfill the request because the encryption parameters in the Credential Request are invalid or missing. Section 8.3.1 of [OpenID4VCI].

400 Bad Request [REQUIRED]

credential_request_denied

The Credential Request has not been accepted by the PID/(Q)EAA Issuer. Section 8.3.1 of [OpenID4VCI].

400 Bad Request [REQUIRED]

issuance_pending

Only in case of deferred flow. The PID/(Q)EAA Issuer cannot fulfill the request because the Credential is not yet available for the issuance. Section 9.3 of [OpenID4VCI].

400 Bad Request [REQUIRED]

invalid_transaction_id

Only in case of deferred flow. The PID/(Q)EAA Issuer cannot fulfill the request because the Credential Request contains an invalid transaction_id. Section 9.3 of [OpenID4VCI].

400 Bad Request [REQUIRED]

invalid_dpop_proof

The PID/(Q)EAA Issuer cannot fulfill the request because of invalid DPoP proof. Section 7 of [RFC 9449].

500 Internal Server Error [REQUIRED]

server_error

The PID/(Q)EAA Issuer encountered an internal problem.

503 Service Unavailable [REQUIRED]

temporarily_unavailable

The PID/(Q)EAA Issuer is temporary unavailable.

504 Gateway Timeout [OPTIONAL]

-

The PID/(Q)EAA Issuer cannot fulfill the request within the defined time interval.

Deferred Endpoint

PID/(Q)EAA Providers MAY support the Deferred Endpoint aiming to satify the cases where an immediate issuance might be not possible, 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.

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.

The following requirements apply:

  1. The Deferred Credential request MAY also happen several days after the initial Credential request.

  2. The User MUST be informed that the Credential is available and ready to be issued.

  3. The Wallet Provider MUST NOT be informed about which Credential is available to be issued or which Credential Issuer the User needs to contact.

  4. The Wallet Instance MUST be informed about the amount of time to wait before making a new Credential request.

  5. 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.

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 and an identifier of the deferred issuance transaction (transaction_id). 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
{
    "transaction_id": "8xLOxBtZp8",
    "lead_time": 864000
}

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 previously provided by the User to the PID/(Q)EAA Provider.

Deferred Request

Upon receipt of the notification (by the Wallet Instance and/or by the PID/(Q)EAA Provider), the User accesses the Wallet Instance.

The Wallet Instance MUST present to the Deferred Endpoint an Access Token that is valid for the issuance of the Digital Credential previously requested at the Credential Endpoint.

If the lead_time parameter value results as less than the expiration time set for the Access Token, the Wallet Instance SHOULD use the Access Token. Otherwise, the Wallet Instance MAY obtain a new Access Token following the Refresh Token flow (see Section Refresh Token Flow for more details). If the Refresh Token flow fails, the Wallet Instance needs to submit a new authentication request.

The Deferred Credential Request MUST be an HTTP POST request. It MUST be sent using the application/json media type. The following parameter is used in the Deferred Credential Request:

  • transaction_id: REQUIRED. String identifying a Deferred Issuance transaction.

The Credential Issuer MUST invalidate the transaction_id after the Credential for which it was meant has been obtained by the Wallet Instance. The following is a non-normative example of a Deferred Credential Request:

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


{
  "transaction_id": "8xLOxBtZp8"
}

Deferred Response

The Deferred Credential Response MUST be sent using the application/json` media type. If the Digital Credential is available, the Deferred Credential Response MUST use the credentials and notification_id parameters as defined in Section Credential Response. If the Deferred Credential Request is invalid or the Digital Credential is not available, the Deferred Credential Error Response MUST be sent to the Wallet Instance according to Section 9.3 of OpenID4VCI.

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.

To uphold privacy, the event_description in the notification SHOULD NOT contain any information that could disclose User behavior or reveal the status of the personal device (e.g., storage space full).

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 notification_id value returned in the Credential Response by the PID/(Q)EAA Provider.

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:

  • credential_accepted: when the Credential was successfully stored in the Wallet Instance.

  • credential_deleted: when the unsuccessful Credential issuance was caused by a user action.

  • credential_failure: in all other unsuccessful cases.

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.

In case of the Notification Request does not contain a valid Access Token, the Notification Endpoint returns an error response such as defined in Section 3 of [RFC 6750]. If any other error occurs, the PID/(Q)EAA Provider MUST return an error response as defined in Section 10.3 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.

Below is a non-normative example of an error response.

HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
    "error": "invalid_notification_id",
    "error_description": "The notification_id field is not valid"
}

In the following table are listed HTTP Status Codes and related error codes that are supported for the error response:

Status Code

error code

Description

400 Bad Request [REQUIRED]

invalid_notification_id

The PID/(Q)EAA Issuer cannot fulfill the request because of invalid notification_id parameter. Section 10.3 of [OpenID4VCI].

400 Bad Request [REQUIRED]

invalid_notification_request

The PID/(Q)EAA Issuer cannot fulfill the request because of missing parameters, invalid parameter or request malformed. Section 10.3 of [OpenID4VCI].

500 Internal Server Error [REQUIRED]

server_error

The PID/(Q)EAA Issuer encountered an internal problem.

503 Service Unavailable [REQUIRED]

temporarily_unavailable

The PID/(Q)EAA Issuer is temporary unavailable.

504 Gateway Timeout [OPTIONAL]

-

The PID/(Q)EAA Issuer cannot fulfill the request within the defined time interval.

Entity Configuration of PID/(Q)EAA Providers

The PID/(Q)EAA Providers, as Federation Entity, are required to adhere to the guidelines outlined in Section Configuration of the Federation. Specifically, they MUST provide a well-known endpoint that hosts their Entity Configuration. The Entity Configuration of PID/(Q)EAA Providers MUST contain the parameters defined in the Sections Entity Configuration Leaves and Intermediates and Entity Configurations Common Parameters.

The PID/(Q)EAA Providers MUST provide the following metadata types:

  • federation_entity

  • oauth_authorization_server

  • openid_credential_issuer

In cases where the (Q)EAA Providers authenticate Users using their Wallet Instance, then the metadata for openid_credential_verifier MUST be provided in addition to the metadata above. In case a national eID scheme is used by the PID/(Q)EAA Providers for the User authentication, they MAY include a metadata for openid_relying_party within their Entity Configuration. The openid_relying_party metadata MUST be compliant with the current version of SPID/CIE id OIDC Technical Specification.

The federation_entity metadata MUST contain the parameters as defined in Section Metadata of federation_entity Leaves.

The openid_credential_verifier metadata MUST contain the parameters as defined in Section Metadata for openid_credential_verifier.

Metadata for oauth_authorization_server

The oauth_authorization_server metadata MUST contain the following parameters.

Claim

Description

issuer

It MUST contain an HTTPS URL that uniquely identifies the PID/(Q)EAA Provider.

pushed_authorization_request_endpoint

The URL of the pushed authorization request endpoint is where a Wallet Instance MUST submit an authorization request to obtain a request_uri value, which can then be used at the authorization endpoint. See RFC 9126#as_metadata.

authorization_endpoint

URL of the authorization server's authorization endpoint. See RFC 8414#section-2.

token_endpoint

URL of the authorization server's token endpoint. See RFC 8414#section-2.

client_registration_types_supported

Array specifying the registration types supported. The authorization server MUST support automatic. See OID-FED Section 5.1.3.

code_challenge_methods_supported

JSON array containing a list of Proof Key for Code Exchange (PKCE) RFC 7636 code challenge methods supported by the authorization server. The authorization server MUST support S256.

acr_values_supported

See OpenID Connect Discovery 1.0 Section 3. The supported values are:

  • https://www.spid.gov.it/SpidL1

  • https://www.spid.gov.it/SpidL2

  • https://www.spid.gov.it/SpidL3

scopes_supported

JSON array containing a list of the supported scope values. See RFC 8414#section-2.

response_modes_supported

JSON array containing a list of the supported "response_mode" values, as specified in OAuth 2.0 Multiple Response Type Encoding Practices. The supported values MAY be query and form_post.jwt (see JARM).

response_types_supported

JSON array containing a list of the supported "response_type" values, as specified in RFC 8414. The supported value MUST be code.

authorization_signing_alg_values_supported

JSON array containing a list of the RFC 7515 supported signing algorithms (alg values). The values MUST be set according to Section Cryptographic Algorithms. See Section 4 of JARM.

grant_types_supported

JSON array containing a list of the supported grant type values. The authorization server MUST support authorization_code.

token_endpoint_auth_methods_supported

JSON array containing a list of supported client authentication methods. The Token Endpoint MUST support attest_jwt_client_auth as defined in OAUTH-ATTESTATION-CLIENT-AUTH.

token_endpoint_auth_signing_alg_values_supported

JSON array containing a list of the signing algorithms ("alg" values) supported by the token endpoint for the signature on the JWT used to authenticate the client at the Token Endpoint. See RFC 8414#section-2.

request_object_signing_alg_values_supported

JSON array containing a list of the signing algorithms ("alg" values) supported for Request Objects. See [openid-connect-discovery-1_0].

jwks

JSON Web Key Set containing the cryptographic keys for the authorization server. See OID-FED Section 5.2.1 and JWK.

Metadata for openid_credential_issuer

The openid_credential_issuer metadata MUST contain the following claims.

Claim

Description

credential_issuer

The PID/(Q)EAA Provider identifier. It MUST be a case sensitive URL using HTTPS scheme as defined in OpenID4VCI Sections 11.2.1 and 11.2.3.

credential_endpoint

URL of the credential endpoint. See OpenID4VCI Section 11.2.3.

nonce_endpoint

URL of the Nonce Endpoint, as defined in Section 7 of OpenID4VCI.

revocation_endpoint

URL of the revocation endpoint. See RFC 8414#section-2.

deferred_credential_endpoint

URL of the deferred credential endpoint, as defined in Section 11.2.3 of OpenID4VCI.

status_attestation_endpoint

It MUST be an HTTPs URL indicating the endpoint where the Wallet Instances can request Status Assertions. See Section Digital Credential Lifecycle for more details.

notification_endpoint

It MUST be an HTTPs URL indicating the notification endpoint. See Section 11.2.3 of [OpenID4VCI].

authorization_servers

OPTIONAL. Array of strings, where each string is an identifier of the OAuth 2.0 Authorization Server (as defined in [RFC 8414]) the PID/(Q)EAA Provider relies on for authorization. If this parameter is omitted, the entity providing the PID/(Q)EAA Provider is also acting as the Authorization Server.

display

See OpenID4VCI Section 11.2.3. Array of objects containing display language properties. The parameters that MUST be included are:

  • name: String value of a display name for the PID/(Q)EAA Provider.

  • locale: String value that identifies the language of this object represented as a language tag taken from values defined in BCP47 RFC 5646. There MUST be only one object for each language identifier.

credential_configurations_supported

JSON object that outlines the details of the Credential supported by the PID/(Q)EAA Provider. It includes a list of name/value pairs, where each name uniquely identifies a specific supported Credential. This identifier is utilized to inform the Wallet Instance which Credential can be provided by the PID/(Q)EAA Provider. The associated value within the object MUST contain metadata specific to that Credential, as defined following. See OpenID4VCI Sections 11.2.3 and A.3.2.

  • format: String identifying the format of this Credential. The PID/(Q)EAA MUST support the value string "dc+sd-jwt". See OpenID4VCI Section A.3.1.

  • scope: JSON String identifying the supported scope value. The Wallet Instance MUST use this value in the Pushed Authorization Request. Scope values MUST be the entire set or a subset of the scope values in the scopes_supported parameter of the Authorization Server. [See OpenID4VCI Section 11.2.3].

  • cryptographic_binding_methods_supported: JSON Array of case sensitive strings that identify the representation of the cryptographic key material that the issued Credential is bound to. The PID/(Q)EAA Provider MUST support the value "jwk".

  • credential_signing_alg_values_supported: JSON Array of case sensitive strings that identify the algorithms that the PID/(Q)EAA Provider MUST support to sign the issued Credential. See Section Cryptographic Algorithms for more details.

  • proof_types_supported: JSON object which provides detailed information about the key proof(s) supported by the PID/(Q)EAA Provider. It consists of a list of name/value pairs, where each name uniquely identifies a supported proof type. The PID/(Q)EAA Provider MUST support at least "jwt" as defined in OpenID4VCI Section 8.2. The value associated with each name/value pair is a JSON object containing metadata related to the key proof. The PID/(Q)EAA Provider MUST support at least the parameter proof_signing_alg_values_supported which MUST be a JSON Array of case sensitive strings that identify the supported algorithms (see Section Cryptographic Algorithms for more details about the supported algorithms).

  • display: Array of objects containing display language properties. The parameters that MUST be included are:

    • name: String value of a display name for the Credential.

    • locale: String value that identifies the language of this object represented as a language tag taken from values defined in BCP47 RFC 5646. There MUST be only one object for each language identifier.

  • vct: As defined in [SD-JWT-VC Credential Format].

  • claims: Array of JSON object each describing how a certain claim related to the Credential MUST be displayed to the User. This Array lists the claims in the order they MUST be displayed by the Wallet. To provide detailed information about the claim, the innermost value MUST contain at least the following parameters. See OpenID4VCI Section A.3.2.

    • path: It contains the pointer that specifies the path to a specific claim within the Credential as defined in Appendix C of OpenID4VCI.

    • display: Array of objects containing display language properties. The parameters that MUST be included are:

      • name: String value of a display name for the claim.

      • locale: String value that identifies the language of this object represented as a language tag taken from values defined in BCP47 RFC 5646. There MUST be only one object for each language identifier.

jwks

JSON Web Key Set document, passed by value, containing the protocol specific keys for the Credential Issuer. See OID-FED Section 5.2.1 and JWK.

trust_frameworks_supported

JSON array containing all supported trust frameworks. See OIDC-IDA Section 8. The supported values are:

  • it_cie: CIE trust framework supported.

  • it_spid: SPID trust framework supported.

  • it_wallet: Italian EUDI Wallet trust framework supported.

  • eudi_wallet: Member State EUDI Wallet trust framework supported.

evidence_supported

JSON array containing all types of identity evidence supported by the Credential Issuer. See OIDC-IDA Section 8. The supported value is vouch.

status_assertion_endpoint

URL of the Status Assertion Endpoint. See OAUTH-STATUS-ASSERTION Section 11.1.

credential_hash_alg_supported

The supported algorithm used by the Wallet Instance to hash the Digital Credential for which the Status Assertion is requested. It is RECOMMENDED to use sha-256. See OAUTH-STATUS-ASSERTION Section 11.1.

Example of a (Q)EAA Provider Entity Configuration

Below is a non-normative example of an Entity Configuration of a (Q)EAA Provider containing a metadata for

  • federation_entity

  • oauth_authorization_server

  • openid_credential_issuer

  • openid_credential_verifier

{
    "iat": 1718207217,
    "exp": 1749743216,
    "iss": "https://eaa-provider.example.org",
    "sub": "https://eaa-provider.example.org",
    "authority_hints": [
        "https://trust-anchor.example.org"
    ],
    "jwks": {
        "keys": [
            {
                "kid": "FANFS3YnC9tjiCaivhWLVUJ3AxwGGz_98uRFaqMEEs",
                "kty": "EC",
                "crv": "P-256",
                "x": "jE2RpcQbFQxKpMqehahgZv6smmXD0i/LTP2QRzMADk4",
                "y": "qkMx5iqt5PhPu5tfctS6HsP+FmLgrxfrzUV2GwMQuh8"
            }
        ]
    },
    "metadata": {
        "federation_entity": {
            "homepage_uri": "https://eaa-provider.example.org/",
            "organization_name": "Organization Name",
            "contacts": [
                "informazioni@example.it",
                "protocollo@pec.example.it"
            ],
            "tos_uri": "https://eaa-provider.example.org/public/info_policy.html",
            "policy_uri": "https://eaa-provider.example.org/public/privacy_policy.html",
            "logo_uri": "https://eaa-provider.example.org/public/logo.svg"
        },
        "oauth_authorization_server": {
            "issuer": "https://eaa-provider.example.org",
            "pushed_authorization_request_endpoint": "https://eaa-provider.example.org/as/par",
            "authorization_endpoint": "https://eaa-provider.example.org/authorize",
            "token_endpoint": "https://eaa-provider.example.org/token",
            "client_registration_types_supported": [
                "automatic"
            ],
            "code_challenge_methods_supported": [
                "S256"
            ],
            "acr_values_supported": [
                "https://www.spid.gov.it/SpidL2",
                "https://www.spid.gov.it/SpidL3"
            ],
            "scopes_supported": [
                "EuropeanDisabilityCard",
                "MDL"
            ],
            "response_modes_supported": [
                "form_post.jwt",
                "query"
            ],
            "response_types_supported": [
                "code"
            ],
            "authorization_signing_alg_values_supported": [
                "ES256",
                "ES384",
                "ES512"
            ],
            "grant_types_supported": [
                "authorization_code"
            ],
            "token_endpoint_auth_methods_supported": [
                "attest_jwt_client_auth"
            ],
            "token_endpoint_auth_signing_alg_values_supported": [
                "ES256",
                "ES384",
                "ES512"
            ],
            "request_object_signing_alg_values_supported": [
                "ES256",
                "ES384",
                "ES512"
            ],
            "jwks": {
                "keys": [
                    {
                        "kid": "f10aca0992694b3581f6f699bfc8a2c6cc687725",
                        "kty": "EC",
                        "crv": "P-256",
                        "x": "jE2RpcQbFQxKpMqehahgZv6smmXD0i/LTP2QRzMADk4",
                        "y": "qkMx5iqt5PhPu5tfctS6HsP+FmLgrxfrzUV2GwMQuh8"
                    }
                ]
            }
        },
        "openid_credential_issuer": {
            "credential_issuer": "https://eaa-provider.example.org",
            "credential_endpoint": "https://eaa-provider.example.org/credential",
            "nonce_endpoint": "https://eaa-provider.example.org/nonce-endpoint",
            "deferred_credential_endpoint": "https://eaa-provider.example.org/deferred-credential",
            "revocation_endpoint": "https://eaa-provider.example.org/revoke",
            "status_attestation_endpoint": "https://eaa-provider.example.org/status",
            "notification_endpoint": "https://eaa-provider.example.org/notification",
            "display": [
                {
                    "name": "EAA Provider",
                    "locale": "it-IT"
                },
                {
                    "name": "EAA Provider",
                    "locale": "en-US"
                }
            ],
            "credential_configurations_supported": {
                "EuropeanDisabilityCard": {
                    "format": "dc+sd-jwt",
                    "scope": "EuropeanDisabilityCard",
                    "cryptographic_binding_methods_supported": [
                        "jwk"
                    ],
                    "credential_signing_alg_values_supported": [
                        "ES256",
                        "ES384",
                        "ES512"
                    ],
                    "proof_types_supported": {
                        "jwt": {
                            "proof_signing_alg_values_supported": [
                                "ES256",
                                "ES384",
                                "ES512"
                            ]
                        }
                    },
                    "display": [
                        {
                            "name": "Carta della disabilità europea",
                            "locale": "it-IT"
                        },
                        {
                            "name": "European Disability Card",
                            "locale": "en-US"
                        }
                    ],
                    "vct": "https://eaa-provider.example.org/v1.0/disabilitycard",
                    "claims": [
                        {
                            "path": ["document_number"],
                            "display": [
                                {
                                    "name": "Numero Documento",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Document Number",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["given_name"],
                            "display": [
                                {
                                    "name": "Nome",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Name",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["family_name"],
                            "display": [
                                {
                                    "name": "Cognome",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Family Name",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["birth_date"],
                            "display": [
                                {
                                    "name": "Data di Nascita (YYYY-MM-GG)",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Date of Birth (YYYY-MM-GG)",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["personal_administrative_number"],
                            "display": [
                                {
                                    "name": "Codice Fiscale",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Tax Identification Number",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["expiry_date"],
                            "display": [
                                {
                                    "name": "Data di Scadenza (YYYY-MM-GG)",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Expiration Date (YYYY-MM-GG)",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["constant_attendance_allowance"],
                            "display": [
                                {
                                    "name": "Diritto accompagnatore",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Constant attendance allowance",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["portrait"],
                            "display": [
                                {
                                    "name": "Foto codificata in base64",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Portrait base64 encoded",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["link_qr_code"],
                            "display": [
                                {
                                    "name": "Link QR Code",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Link QR Code",
                                    "locale": "en-US"
                                }
                            ]
                        }
                    ]
                },
                "MDL": {
                    "format": "dc+sd-jwt",
                    "scope": "MDL",
                    "cryptographic_binding_methods_supported": [
                        "jwk"
                    ],
                    "credential_signing_alg_values_supported": [
                        "ES256",
                        "ES384",
                        "ES512"
                    ],
                    "proof_types_supported": {
                        "jwt": {
                            "proof_signing_alg_values_supported": [
                                "ES256",
                                "ES384",
                                "ES512"
                            ]
                        }
                    },
                    "display": [
                        {
                            "name": "Patente di guida",
                            "locale": "it-IT"
                        },
                        {
                            "name": "Mobile Driver's License",
                            "locale": "en-US"
                        }
                    ],
                    "vct": "https://eaa-provider.example.org/v1.0/mdl",
                    "claims": [
                        {
                            "path": ["given_name"],
                            "display": [
                                {
                                    "name": "Nome",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "First Name",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["family_name"],
                            "display": [
                                {
                                    "name": "Cognome",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Family Name",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["birth_date"],
                            "display": [
                                {
                                    "name": "Data di nascita (YYYY-MM-GG)",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Date of Birth (YYYY-MM-GG)",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["place_of_birth"],
                            "display": [
                                {
                                    "name": "Luogo di Nascita",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Place of Birth",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["issue_date"],
                            "display": [
                                {
                                    "name": "Data di rilascio (YYYY-MM-GG)",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Issue Date (YYYY-MM-GG)",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {   
                            "path": ["expiry_date"],
                            "display": [
                                {
                                    "name": "Data di scadenza (YYYY-MM-GG)",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Expiry Date (YYYY-MM-GG)",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["issuing_country"], 
                            "display": [
                                {
                                    "name": "Paese di rilascio",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Issuing Country",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["issuing_authority"],
                            "display": [
                                {
                                    "name": "Autorità di rilascio",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Issuing Authority",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["document_number"],
                            "display": [
                                {
                                    "name": "Numero di documento",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Document Number",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["portrait"],
                            "display": [
                                {
                                    "name": "Foto codificata in base64",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Portrait base64 encoded",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["driving_privileges"],
                            "display": [
                                {
                                    "name": "Elenco delle categorie di abilitazione separate da spazio",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Driving Privileges separated by space",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["restrictions_conditions"],
                            "display": [
                                {
                                    "name": "Annotazioni/Restrizioni valide per tutte le categorie separate da spazio",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Restriction/Condition for all driving privileges separated by space ",
                                    "locale": "en-US"
                                }
                            ]
                        },
                        {
                            "path": ["driving_privileges_details"],
                            "display": [
                                {
                                    "name": "Dettagli delle categorie di abilitazione",
                                    "locale": "it-IT"
                                },
                                {
                                    "name": "Driving privilege details",
                                    "locale": "en-US"
                                }
                            ]
                        }
                    ]
                }
            },
            "jwks": {
                "keys": [
                    {
                        "kid": "f10aca0992694b3581f6f699bfc8a2c6cc687725",
                        "kty": "EC",
                        "crv": "P-256",
                        "x": "jE2RpcQbFQxKpMqehahgZv6smmXD0i/LTP2QRzMADk4",
                        "y": "qkMx5iqt5PhPu5tfctS6HsP+FmLgrxfrzUV2GwMQuh8"
                    }
                ]
            },
            "trust_frameworks_supported": [
                "it_cie",
                "it_spid",
                "it_wallet",
                "eudi_wallet"
            ],
            "evidence_supported": [
                "vouch"
            ]
        },
        "openid_credential_verifier": {
            "application_type": "web",
            "client_id": "https://eaa-provider.example.org",
            "client_name": "Organization Name",
            "contacts": [
                "informazioni@example.it",
                "protocollo@pec.example.it"
            ],
            "request_uris": [
                "https://eaa-provider.example.org/request_uri"
            ],
            "response_uris": [
                "https://eaa-provider.example.org/response_uri"
            ],
            "default_acr_values": [
                "https://www.spid.gov.it/SpidL2",
                "https://www.spid.gov.it/SpidL3"
            ],
            "request_object_signing_alg_values_supported": [
                "ES256",
                "ES384",
                "ES512"
            ],
            "authorization_signed_response_alg": [
                "ES256",
                "ES384",
                "ES512"
            ],
            "authorization_encrypted_response_alg": [
                "RSA-OAEP-256"
            ],
            "authorization_encrypted_response_enc": [
                "A128CBC-HS256",
                "A192CBC-HS384",
                "A256CBC-HS512",
                "A128GCM",
                "A192GCM",
                "A256GCM"
            ],
            "vp_formats": {
                "dc+sd-jwt": {
                    "sd-jwt_alg_values": [
                        "ES256",
                        "ES384",
                        "ES512"
                    ]
                }
            },
            "jwks": {
                "keys": [
                    {
                        "kid": "f10aca0992694b3581f6f699bfc8a2c6cc687725",
                        "kty": "EC",
                        "crv": "P-256",
                        "x": "jE2RpcQbFQxKpMqehahgZv6smmXD0i/LTP2QRzMADk4",
                        "y": "qkMx5iqt5PhPu5tfctS6HsP+FmLgrxfrzUV2GwMQuh8"
                    }
                ]
            }
        }
    }
}