Skip to main content
European CommissionEBSI European Blockchain

Verifiable Presentation Exchange Guidelines

Last updated on

Context

This document defines Verifiable Presentation (VP) Exchanges in compliance with OpenID for Verifiable Presentations (version: openid-4-verifiable-presentations-1_0-13). The primary difference between the VP exchange flow described here and that in OpenID for Verifiable Presentations is that here the flow is initiated by the Wallet. This removes the need for the Wallet to expose any external endpoints.

The VP Token Request is delivered to the Wallet as a redirect Location URI in response to the Wallet sending an Authorize Request to the Verifier. The VP is a JWT signed with the Holder's private key corresponding to the Holder's DID document's authentication key, thereby proving that the private key is controlled by the Holder.

The Authorisation Request and Response, Token Request and Response, and Credential Request and Response are semantically the same with the Verifiable Credential issuance in-time flow. The "direct_post" must be executed against the given redirect_uri.

VP Token Request

The call below is from the AS to the wallet, and it initiates the vp_token exchange. The redirect schema is registered with the Authorisation Request's client_metadata.authorization_endpoint. The request is passed as a signed request object with the following fields.

ParameterRequirementDescription
response_typeREQUIREDvp_token
client_idREQUIREDClient id of the verifier.
redirect_uriREQUIREDAn HTTPS endpoint where Wallet must post VP Token Response.
scopeREQUIREDopenid
response_modeREQUIREDdirect_post
presentation_definitionOPTIONALA string containing presentation definition. Either presentation_definition or presentation_definition_uri must be present.
presentation_definition_uriOPTIONALA URI where Wallet will fetch the presentation definition. Either presentation_definition or presentation_definition_uri must be present.
stateRECOMMENDEDAn opaque value used by the client to maintain state between the request and callback. The authorization server may include this value. The parameter SHOULD be used for preventing cross-site request forgery
nonceREQUIREDUnique to this request, used to mitigate replay attacks.
VP Token Request - Non-normative example
HTTP 302 Location: openid://
?client_id=https%3A%2F%2Fapi-conformance.ebsi.eu%2Fconformance%2Fv4%2Fauth-mock
&response_type=vp_token
&scope=openid
&redirect_uri=https%3A%2F%2Fapi-conformance.ebsi.eu%2Fconformance%2Fv4%2Fauth-mock%2Fdirect_post
&request=eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImM0S3JlcEpYem1CTVctcW8ybnREQ3drVGdMbTJDYl81ZWFiemtsalRoXzAifQ.eyJpc3MiOiJodHRwczovL2FwaS1jb25mb3JtYW5jZS5lYnNpLmV1L2NvbmZvcm1hbmNlL3YzL2F1dGgtbW9jayIsImF1ZCI6Imh0dHBzOi8vbXktaXNzdWVyLmV1L3N1ZmZpeC94eXoiLCJleHAiOjE1ODk2OTkxNjIsInJlc3BvbnNlX3R5cGUiOiJ2cF90b2tlbiIsInJlc3BvbnNlX21vZGUiOiJkaXJlY3RfcG9zdCIsImNsaWVudF9pZCI6Imh0dHBzOi8vYXBpLWNvbmZvcm1hbmNlLmVic2kuZXUvY29uZm9ybWFuY2UvdjMvYXV0aC1tb2NrIiwicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9hcGktY29uZm9ybWFuY2UuZWJzaS5ldS9jb25mb3JtYW5jZS92My9hdXRoLW1vY2svZGlyZWN0X3Bvc3QiLCJzY29wZSI6Im9wZW5pZCIsIm5vbmNlIjoiRmdrZUVyZjkxa2ZsIiwicHJlc2VudGF0aW9uX2RlZmluaXRpb25fdXJpIjoiaHR0cHM6Ly9hcGktY29uZm9ybWFuY2UuZWJzaS5ldS9jb25mb3JtYW5jZS92My9hdXRoLW1vY2svZGVmaW5pdGlvbnMveHl6In0.i4VIO7jx9M9XnYDSzsNBf6Nd2QQSw5KiczSeh4SVUuzvbSw7f8D72Bld1VDde-CAGgGGRpW_vMoVCZm-Vt9wSg

JWT Header:
{
typ: 'JWT',
alg: 'ES256',
kid: 'c4KrepJXzmBMW-qo2ntDCwkTgLm2Cb_5eabzkljTh_0'
}
JWT Payload:
{
iss: 'https://api-conformance.ebsi.eu/conformance/v3/auth-mock',
aud: 'https://my-issuer.eu/suffix/xyz',
exp: 1589699162,
response_type: 'vp_token',
response_mode: 'direct_post',
client_id: 'https://api-conformance.ebsi.eu/conformance/v3/auth-mock',
redirect_uri: 'https://api-conformance.ebsi.eu/conformance/v3/auth-mock/direct_post',
scope: 'openid',
nonce: 'FgkeErf91kfl',
presentation_definition_uri: 'https://api-conformance.ebsi.eu/conformance/v3/auth-mock/definitions/xyz'
}

VP Token Response

VP Token Response is delivered to AS by posting to URI defined in direct_post. The payload is formatted as application/x-www-form-urlencoded data. Presentation submission parameters define how requested VP should be interpreted. The contents is defined here but flattened to key-value pairs.

The state parameter is mandatory for the VP Token Response when it is present in the VP Token Request sent by the "Authorization Server." In such cases, the Client must ensure that the values of the state parameter are identical in both.

VP Token Response - Non-normative example
HTTP POST into: https://api-conformance.ebsi.eu/conformance/v3/auth-mock/direct_post
vp_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDplYnNpOnpkUGoxR1BYamZFUlh4WFBFMVlUWWRKIzdqM1RwYU5kUE5UT3pPdG91T09rbmxPTFFrM0pQLXlrVGZyYVd0WTNHTUUifQ.eyJpc3MiOiJkaWQ6ZWJzaTp6ZFBqMUdQWGpmRVJYeFhQRTFZVFlkSiIsImF1ZCI6Imh0dHBzOi8vYXBpLWNvbmZvcm1hbmNlLmVic2kuZXUvY29uZm9ybWFuY2UvdjMvYXV0aC1tb2NrIiwic3ViIjoiZGlkOmVic2k6emRQajFHUFhqZkVSWHhYUEUxWVRZZEoiLCJpYXQiOjE1ODk2OTkyNjAsIm5iZiI6MTU4OTY5OTI2MCwiZXhwIjoxNTg5Njk5MjYwLCJub25jZSI6IkZna2VFcmY5MWtmbCIsImp0aSI6InVybjp1dWlkOjA3MDYwNjFhLWUyY2EtNDYxNC05ZGU3LTljMTQ1MTkzNWYwMiIsInZwIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIl0sImlkIjoidXJuOnV1aWQ6MDcwNjA2MWEtZTJjYS00NjE0LTlkZTctOWMxNDUxOTM1ZjAyIiwidHlwZSI6WyJWZXJpZmlhYmxlUHJlc2VudGF0aW9uIl0sImhvbGRlciI6ImRpZDplYnNpOnpkUGoxR1BYamZFUlh4WFBFMVlUWWRKIiwidmVyaWZpYWJsZUNyZWRlbnRpYWwiOlsiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKRlV6STFOaUlzSW10cFpDSTZJbVJwWkRwbFluTnBPbnAyU0ZkWU16VTVRVE5EZG1aS2JrTlpZVUZwUVdSbEkwWXdjalZQZVhSZmJHRm9kblo2TmsxWGJGbHpNMjFqV1U1TFdtbHBVV1JWWm5GMk9IUnphRWhPT1hjaWZRLmV5SnBjM01pT2lKa2FXUTZaV0p6YVRwNmRraFhXRE0xT1VFelEzWm1TbTVEV1dGQmFVRmtaU0lzSW5OMVlpSTZJbVJwWkRwbFluTnBPbnBrVUdveFIxQllhbVpGVWxoNFdGQkZNVmxVV1dSS0lpd2lhV0YwSWpveE5UZzVOams1TWpZd0xDSnVZbVlpT2pFMU9EazJPVGt5TmpBc0ltVjRjQ0k2TVRVNE9UWTVPVEkyTUN3aWFuUnBJam9pZFhKdU9uVjFhV1JpTmpreE5tTXhNQzA0WWpZMExUUTBNamd0T0dKbU5TMWpaR1kwT0RNNE16TXhNR01pTENKMll5STZleUpBWTI5dWRHVjRkQ0k2V3lKb2RIUndjem92TDNkM2R5NTNNeTV2Y21jdk1qQXhPQzlqY21Wa1pXNTBhV0ZzY3k5Mk1TSmRMQ0pwWkNJNkluVnlianAxZFdsa09tSTJPVEUyWXpFd0xUaGlOalF0TkRReU9DMDRZbVkxTFdOa1pqUTRNemd6TXpFd1l5SXNJblI1Y0dVaU9sc2lWbVZ5YVdacFlXSnNaVU55WldSbGJuUnBZV3dpTENKV1pYSnBabWxoWW14bFFYUjBaWE4wWVhScGIyNGlMQ0pEVkZkaGJHeGxkRk5oYldWSmJsUnBiV1VpWFN3aWFYTnpkV0Z1WTJWRVlYUmxJam9pTWpBeU1DMHdOUzB4TjFRd056b3dOem8wTUZvaUxDSjJZV3hwWkVaeWIyMGlPaUl5TURJd0xUQTFMVEUzVkRBM09qQTNPalF3V2lJc0luWmhiR2xrVlc1MGFXd2lPaUl5TURJd0xUQTFMVEUzVkRBM09qQTNPalF3V2lJc0ltVjRjR2x5WVhScGIyNUVZWFJsSWpvaU1qQXlNQzB3TlMweE4xUXdOem93TnpvME1Gb2lMQ0pwYzNOMVpXUWlPaUl5TURJd0xUQTFMVEUzVkRBM09qQTNPalF3V2lJc0ltTnlaV1JsYm5ScFlXeFRkV0pxWldOMElqcDdJbWxrSWpvaVpHbGtPbVZpYzJrNmVtUlFhakZIVUZocVprVlNXSGhZVUVVeFdWUlpaRW9pZlN3aVkzSmxaR1Z1ZEdsaGJGTmphR1Z0WVNJNmV5SnBaQ0k2SW1oMGRIQnpPaTh2WVhCcExYQnBiRzkwTG1WaWMya3VaWFV2ZEhKMWMzUmxaQzF6WTJobGJXRnpMWEpsWjJsemRISjVMM1l5TDNOamFHVnRZWE12TUhneU16QXpPV1UyTXpVMlpXRTJZamN3TTJObE5qY3laVGRqWm1Gak1HSTBNamMyTldJeE5UQm1Oak5rWmpjNFpUSmlaREU0WVdVM09EVTNPRGRtTm1FeUlpd2lkSGx3WlNJNklrWjFiR3hLYzI5dVUyTm9aVzFoVm1Gc2FXUmhkRzl5TWpBeU1TSjlmWDAuOURya3kzcGpCTXFRT3JZSzRzSVRfLXFfM0g5WVlrSG9IRHA1V0hQc055VTVsNExPSFJPajlCOHRLbVZuVnc0aGEzMlVEd0xTd2Q4YzZFbHpUSzNfLVEiXX19.fGUeTLm5mplufL1VpCNbxKGmUzBeMS-NnSkaHNf6_08pFg6iEKfJmD2Wt2eDvj4qijXwnnbLFYV4zBt3PHfpWA
&presentation_submission=%7B%22id%22%3A%22a30e3b91-fb77-4d22-95fa-871689c322e2%22%2C%22definition_id%22%3A%2232f54163-7166-48f1-93d8-ff217bdb0653%22%2C%22descriptor_map%22%3A%5B%7B%22id%22%3A%22same-device-in-time-credential%22%2C%22path%22%3A%22%24%22%2C%22format%22%3A%22jwt_vp%22%2C%22path_nested%22%3A%7B%22format%22%3A%22jwt_vc%22%2C%22path%22%3A%22%24verifiableCredential%5B0%5D%22%7D%7D%5D%7D

JWT Header:
{
typ: 'JWT',
alg: 'ES256',
kid: 'did:ebsi:zdPj1GPXjfERXxXPE1YTYdJ#7j3TpaNdPNTOzOtouOOknlOLQk3JP-ykTfraWtY3GME'
}
JWT Payload:
{
iss: 'did:ebsi:zdPj1GPXjfERXxXPE1YTYdJ',
aud: 'https://api-conformance.ebsi.eu/conformance/v3/auth-mock',
sub: 'did:ebsi:zdPj1GPXjfERXxXPE1YTYdJ',
iat: 1589699260,
nbf: 1589699260,
exp: 1589699260,
nonce: 'FgkeErf91kfl',
jti: 'urn:uuid:0706061a-e2ca-4614-9de7-9c1451935f02',
vp: {
'@context': [ 'https://www.w3.org/2018/credentials/v1' ],
id: 'urn:uuid:0706061a-e2ca-4614-9de7-9c1451935f02',
type: [ 'VerifiablePresentation' ],
holder: 'did:ebsi:zdPj1GPXjfERXxXPE1YTYdJ',
verifiableCredential: [
'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDplYnNpOnp2SFdYMzU5QTNDdmZKbkNZYUFpQWRlI0YwcjVPeXRfbGFodnZ6Nk1XbFlzM21jWU5LWmlpUWRVZnF2OHRzaEhOOXcifQ.eyJpc3MiOiJkaWQ6ZWJzaTp6dkhXWDM1OUEzQ3ZmSm5DWWFBaUFkZSIsInN1YiI6ImRpZDplYnNpOnpkUGoxR1BYamZFUlh4WFBFMVlUWWRKIiwiaWF0IjoxNTg5Njk5MjYwLCJuYmYiOjE1ODk2OTkyNjAsImV4cCI6MTU4OTY5OTI2MCwianRpIjoidXJuOnV1aWRiNjkxNmMxMC04YjY0LTQ0MjgtOGJmNS1jZGY0ODM4MzMxMGMiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmI2OTE2YzEwLThiNjQtNDQyOC04YmY1LWNkZjQ4MzgzMzEwYyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJWZXJpZmlhYmxlQXR0ZXN0YXRpb24iLCJDVFdhbGxldFNhbWVJblRpbWUiXSwiaXNzdWFuY2VEYXRlIjoiMjAyMC0wNS0xN1QwNzowNzo0MFoiLCJ2YWxpZEZyb20iOiIyMDIwLTA1LTE3VDA3OjA3OjQwWiIsInZhbGlkVW50aWwiOiIyMDIwLTA1LTE3VDA3OjA3OjQwWiIsImV4cGlyYXRpb25EYXRlIjoiMjAyMC0wNS0xN1QwNzowNzo0MFoiLCJpc3N1ZWQiOiIyMDIwLTA1LTE3VDA3OjA3OjQwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmVic2k6emRQajFHUFhqZkVSWHhYUEUxWVRZZEoifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHBzOi8vYXBpLXBpbG90LmVic2kuZXUvdHJ1c3RlZC1zY2hlbWFzLXJlZ2lzdHJ5L3YyL3NjaGVtYXMvMHgyMzAzOWU2MzU2ZWE2YjcwM2NlNjcyZTdjZmFjMGI0Mjc2NWIxNTBmNjNkZjc4ZTJiZDE4YWU3ODU3ODdmNmEyIiwidHlwZSI6IkZ1bGxKc29uU2NoZW1hVmFsaWRhdG9yMjAyMSJ9fX0.9Drky3pjBMqQOrYK4sIT_-q_3H9YYkHoHDp5WHPsNyU5l4LOHROj9B8tKmVnVw4ha32UDwLSwd8c6ElzTK3_-Q'
]
}
}

Presentation Definition and Presentation Submission

Presentation Definition
{
id: '32f54163-7166-48f1-93d8-ff217bdb0653',
format: { jwt_vc: { alg: [ 'ES256' ] }, jwt_vp: { alg: [ 'ES256' ] } },
input_descriptors: [
{
id: 'same-device-in-time-credential',
constraints: {
fields: [
{
path: [ '$.type' ],
filter: {
type: 'array',
contains: { const: 'CTWalletSameInTime' }
}
}
]
}
}
]
}
Presentation Submission
{
id: 'a30e3b91-fb77-4d22-95fa-871689c322e2',
definition_id: '32f54163-7166-48f1-93d8-ff217bdb0653',
descriptor_map: [
{
id: 'same-device-in-time-credential',
path: '$',
format: 'jwt_vp',
path_nested: { format: 'jwt_vc', path: '$verifiableCredential[0]' }
}
]
}

Service to Service Token Flow

A Verifiable Presentation token can used by a service to request an access token from AS. Before invoking the token endpoint, the service must request a presentation definition from AS with the desired scopes. AS maps these scopes to VP definitions. The service invokes the token endpoint with a corresponding presentation_submission encoded as in VP Token Response above.