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.
Parameter | Requirement | Description |
---|---|---|
response_type | REQUIRED | vp_token |
client_id | REQUIRED | Client id of the verifier. |
redirect_uri | REQUIRED | An HTTPS endpoint where Wallet must post VP Token Response. |
scope | REQUIRED | openid |
response_mode | REQUIRED | direct_post |
presentation_definition | OPTIONAL | A string containing presentation definition. Either presentation_definition or presentation_definition_uri must be present. |
presentation_definition_uri | OPTIONAL | A URI where Wallet will fetch the presentation definition. Either presentation_definition or presentation_definition_uri must be present. |
state | RECOMMENDED | An 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 |
nonce | REQUIRED | Unique 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
{
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' }
}
}
]
}
}
]
}
{
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.