openid-4-vp December 2021
Terbu, et al. Standards Track [Page]
Workgroup:
connect
Internet-Draft:
openid-connect-4-verifiable-presentations-1_0-06
Published:
Intended Status:
Standards Track
Authors:
O. Terbu
walt.id
T. Lodderstedt
yes.com
K. Yasuda
Microsoft
A. Lemmon
Convergence.tech
T. Looker
Mattr

OpenID Connect for Verifiable Presentations

Abstract

This specification defines an extension of OpenID Connect to allow presentation of claims in the form of W3C Verifiable Credentials as part of the protocol flow in addition to claims provided in the id_token and/or via Userinfo responses.

Table of Contents

1. Introduction

This specification extends OpenID Connect with support for presentation of claims via W3C Verifiable Credentials. This allows existing OpenID Connect RPs to extends their reach towards claims sources asserting claims in this format. It also allows new applications built using Verifiable Credentials to utilize OpenID Connect as integration and interoperability layer towards credential holders.

This specification enables requesting and delivery of verifiable presentations in conjunction with Self-Issued OpenID Providers (see [SIOPv2]) as well as traditional OpenID Providers (see [OpenID]).

2. Use Cases

2.1. Verifier accesses Wallet via OpenID Connect

A Verifier uses OpenID Connect to obtain verifiable presentations. This is a simple and mature way to obtain identity data. From a technical perspective, this also makes integration with OAuth-protected APIs easier as OpenID Connect is based on OAuth.

2.2. Existing OpenID Connect RP integrates SSI wallets

An application currently utilizing OpenID Connect for accessing various federated identity providers can use the same protocol to also integrate with emerging SSI-based wallets. This is a convenient transition path leveraging existing expertise to protect investments made.

2.3. Existing OpenID Connect OP as custodian of End-User Credentials

An existing OpenID Connect may extends its service by maintaining credentials issued by other claims sources on behalf of its customers. Customers can mix claims of the OP and from their credentials to fulfil authentication requests.

2.4. Federated OpenID Connect OP adds device-local mode

An extisting OpenID Connect OP with a native user experience (PWA or native app) issues Verifiable Credentials and stores it on the user's device linked to a private key residing on this device under the user's control. For every authentication request, the native user experience first checks whether this request can be fulfilled using the locally stored credentials. If so, it generates a presentations signed with the user's keys in order to prevent replay of the credential.

This approach dramatically reduces latency and reduces load on the OP's servers. Moreover, the user can identity, authenticate, and authorize even in situations with unstable or without internet connectivity.

3. Terminology

Credential

A set of one or more claims made by an issuer. (see [VC_DATA])

Verifiable Credential (VC)

A verifiable credential is a tamper-evident credential that has authorship that can be cryptographically verified. Verifiable credentials can be used to build verifiable presentations, which can also be cryptographically verified. The claims in a credential can be about different subjects. (see [VC_DATA])

Presentation

Data derived from one or more verifiable credentials, issued by one or more issuers, that is shared with a specific verifier. (see [VC_DATA])

Verified Presentation (VP)

A verifiable presentation is a tamper-evident presentation encoded in such a way that authorship of the data can be trusted after a process of cryptographic verification. Certain types of verifiable presentations might contain data that is synthesized from, but do not contain, the original verifiable credentials (for example, zero-knowledge proofs). (see [VC_DATA])

W3C Verifiable Credential Objects

Both verifiable credentials and verifiable presentations

4. Overview

This specification defines mechanisms to allow RPs to request and OPs to provide Verifiable Presentations via OpenID Connect.

Verifiable Presentations are used to present claims along with cryptographic proofs of the link between presenter and subject of the verifiable credentials it contains. A verifiable presentation can contain a subset of claims asserted in a certain credential (selective disclosure) and it can assemble claims from different credentials.

There are two credential formats to VCs and VPs: JSON or JSON-LD. There are also two proof formats to VCs and VPs: JWT and Linked Data Proofs. Each of those formats has different properties and capabilites and each of them comes with different proof types. Proof formats are agnostic to the credential format chosen. However, the JSON credential format is commonly used with JSON Web Signatures (see [VC_DATA], section 6.3.1). JSON-LD is commonly used with different kinds of Linked Data Proofs and JSON Web Signatures (see [VC_DATA], section 6.3.2). Applications can use all beforementioned assertion and proof formats with this specification.

This specification introduces new token type "VP Token" used as generic container for verifiable presentation objects that is returned in authentication and token responses in addition to ID Tokens (see Section 5).

Note that when both ID Token and VP Token are returned, each has a different function. ID Token serves as an Authentication receipt that carries information regarding the Authentication Event of the End-user. VP Token serves as a proof of possession of a third party attested claims and carries claims about the user.

Verifiers request verifiable presentations using the claims parameter as defined in (@!OpenID) and syntax as defined in DIF Presentation Exchange [DIF.PresentationExchange].

5. vp_token

The response parameter vp_token is defined as follows:

5.1. Request

A VP Token is requested by adding a new top level element vp_token to the claims parameter. This element contains a presentation_definition element as defined in Section 4 of [DIF.PresentationExchange].

Please note this draft defines a profile of [DIF.PresentationExchange] as follows:

  • The format element underneath the presentation_definition that represents supported presentation formats, proof types, and algorithms is not supported. Those are determined using new RP and OP metadata (see Section 6).

The request syntax is illustrated in the following example:

{
    "id_token": {
        "email": null
    },
    "vp_token": {
        "presentation_definition": {
            "id": "vp token example",
            "input_descriptors": [
                {
                    "id": "id card credential",
                    "format": {
                        "ldp_vc": {
                            "proof_type": [
                                "Ed25519Signature2018"
                            ]
                        }
                    },
                    "constraints": {
                        "fields": [
                            {
                                "path": [
                                    "$.type"
                                ],
                                "filter": {
                                    "type": "string",
                                    "pattern": "IDCardCredential"
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}

This simple example requests the presentation of a credential of a certain type.

The following example

{
    "id_token": {
        "email": null
    },
    "vp_token": {
        "presentation_definition": {
            "id": "vp token example",
            "input_descriptors": [
                {
                    "id": "id card credential with constraints",
                    "format": {
                        "ldp_vc": {
                            "proof_type": [
                                "Ed25519Signature2018"
                            ]
                        }
                    },
                    "constraints": {
                        "limit_disclosure": "required",
                        "fields": [
                            {
                                "path": [
                                    "$.type"
                                ],
                                "filter": {
                                    "type": "string",
                                    "pattern": "IDCardCredential"
                                }
                            },
                            {
                                "path": [
                                    "$.credentialSubject.given_name"
                                ]
                            },
                            {
                                "path": [
                                    "$.credentialSubject.family_name"
                                ]
                            },
                            {
                                "path": [
                                    "$.credentialSubject.birthdate"
                                ]
                            }
                        ]
                    }
                }
            ]
        }
    }
}

shows how the RP can request selective dislosure or certain claims from a credential of a particular type.

RPs can also ask for alternative credentials being presented, which is shown in the next example:

{
    "id_token": {
        "email": null
    },
    "vp_token": {
        "presentation_definition": {
            "id": "alternative credentials",
            "submission_requirements": [
                {
                    "name": "Citizenship Information",
                    "rule": "pick",
                    "count": 1,
                    "from": "A"
                }
            ],
            "input_descriptors": [
                {
                    "id": "id card credential",
                    "group": [
                        "A"
                    ],
                    "format": {
                        "ldp_vc": {
                            "proof_type": [
                                "Ed25519Signature2018"
                            ]
                        }
                    },
                    "constraints": {
                        "fields": [
                            {
                                "path": [
                                    "$.type"
                                ],
                                "filter": {
                                    "type": "string",
                                    "pattern": "IDCardCredential"
                                }
                            }
                        ]
                    }
                },
                {
                    "id": "passport credential",
                    "format": {
                        "jwt_vc": {
                            "alg": [
                                "RS256"
                            ]
                        }
                    },
                    "group": [
                        "A"
                    ],
                    "constraints": {
                        "fields": [
                            {
                                "path": [
                                    "$.vc.type"
                                ],
                                "filter": {
                                    "type": "string",
                                    "pattern": "PassportCredential"
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}

5.2. Response

A vp_token MUST be provided in the same response as the id_token of the respective OpenID Connect transaction. Depending on the response/grant type, this can be either the authentication response or the token response.

The vp_token either contains a single verifiable presentation or an array of verifiable presentations.

Each of those verifiable presentations MAY contain a presentation_submission element as defined in [DIF.PresentationExchange]. This presentation_submission element links the input descriptor identifiers as specified in the corresponding request to the respective verifiable presentations within the vp_token along with format information. The root of the path expressions in the descriptor map is the respective verifiable presentation, pointing to the respective Verifiable Credentials.

This is shown in the following example.

{
    "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://identity.foundation/presentation-exchange/submission/v1"
    ],
    "type": [
        "VerifiablePresentation",
        "PresentationSubmission"
    ],
    "verifiableCredential": [
        {
            "@context": [
                "https://www.w3.org/2018/credentials/v1",
                "https://www.w3.org/2018/credentials/examples/v1"
            ],
            "id": "https://example.com/credentials/1872",
            "type": [
                "VerifiableCredential",
                "IDCardCredential"
            ],
            "issuer": {
                "id": "did:example:issuer"
            },
            "issuanceDate": "2010-01-01T19:23:24Z",
            "credentialSubject": {
                "given_name": "Fredrik",
                "family_name": "Strömberg",
                "birthdate": "1949-01-22"
            },
            "proof": {
                "type": "Ed25519Signature2018",
                "created": "2021-03-19T15:30:15Z",
                "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..PT8yCqVjj5ZHD0W36zsBQ47oc3El07WGPWaLUuBTOT48IgKI5HDoiFUt9idChT_Zh5s8cF_2cSRWELuD8JQdBw",
                "proofPurpose": "assertionMethod",
                "verificationMethod": "did:example:issuer#keys-1"
            }
        }
    ],
    "id": "ebc6f1c2",
    "holder": "did:example:holder",
    "presentation_submission": {
        "id": "Selective disclosure example presentation",
        "definition_id": "Selective disclosure example",
        "descriptor_map": [
            {
                "id": "ID Card with constraints",
                "format": "ldp_vc",
                "path": "$.verifiableCredential[0]"
            }
        ]
    },
    "proof": {
        "type": "Ed25519Signature2018",
        "created": "2021-03-19T15:30:15Z",
        "challenge": "n-0S6_WzA2Mj",
        "domain": "https://client.example.org/cb",
        "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..GF5Z6TamgNE8QjE3RbiDOj3n_t25_1K7NVWMUASe_OEzQV63GaKdu235MCS3hIYvepcNdQ_ZOKpGNCf0vIAoDA",
        "proofPurpose": "authentication",
        "verificationMethod": "did:example:holder#key-1"
    }
}

The OP MAY also add a _vp_token element to the corresponding ID Token, which is defined as follows:

_vp_token: JWT claim containing an element of type presentation_submission as defined in [DIF.PresentationExchange]. This presentation_submission element links the input descriptor identifiers as specified in the corresponding request to the respective verifiable presentations within the vp_token along with format information. The root of the path expressions in the descriptor map is the respective vp_token.

This element might, for example, be used if the particular format of the provided presentations does not allow for the direct inclusion of presentation_submission elements or if the OP wants to provide the RP with additional information about the format and structure in advance of the processing of the vp_token.

In case the OP returns a single verifiable presentation in the vp_token, the descriptor map would then contain a simple path expression "$".

This is an example of a vp_token containing a single verifiable presentation

{
    "@context": [
        "https://www.w3.org/2018/credentials/v1"
    ],
    "type": [
        "VerifiablePresentation"
    ],
    "verifiableCredential": [
        {
            "@context": [
                "https://www.w3.org/2018/credentials/v1",
                "https://www.w3.org/2018/credentials/examples/v1"
            ],
            "id": "https://example.com/credentials/1872",
            "type": [
                "VerifiableCredential",
                "IDCardCredential"
            ],
            "issuer": {
                "id": "did:example:issuer"
            },
            "issuanceDate": "2010-01-01T19:23:24Z",
            "credentialSubject": {
                "given_name": "Fredrik",
                "family_name": "Strömberg",
                "birthdate": "1949-01-22"
            },
            "proof": {
                "type": "Ed25519Signature2018",
                "created": "2021-03-19T15:30:15Z",
                "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..PT8yCqVjj5ZHD0W36zsBQ47oc3El07WGPWaLUuBTOT48IgKI5HDoiFUt9idChT_Zh5s8cF_2cSRWELuD8JQdBw",
                "proofPurpose": "assertionMethod",
                "verificationMethod": "did:example:issuer#keys-1"
            }
        }
    ],
    "id": "ebc6f1c2",
    "holder": "did:example:holder",
    "proof": {
        "type": "Ed25519Signature2018",
        "created": "2021-03-19T15:30:15Z",
        "challenge": "n-0S6_WzA2Mj",
        "domain": "https://client.example.org/cb",
        "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..GF5Z6TamgNE8QjE3RbiDOj3n_t25_1K7NVWMUASe_OEzQV63GaKdu235MCS3hIYvepcNdQ_ZOKpGNCf0vIAoDA",
        "proofPurpose": "authentication",
        "verificationMethod": "did:example:holder#key-1"
    }
}

with a matching _vp_token in the corresponding id_token.

{
    "iss": "https://self-issued.me/v2",
    "aud": "https://book.itsourweb.org:3000/client_api/authresp/uhn",
    "iat": 1615910538,
    "exp": 1615911138,
    "sub": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs",
    "sub_jwk": {
        "kty": "RSA",
        "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx...DKgw",
        "e": "AQAB"
    },
    "auth_time": 1615910535,
    "nonce": "960848874",
    "_vp_token": {
        "presentation_submission": {
            "id": "Selective disclosure example presentation",
            "definition_id": "Selective disclosure example",
            "descriptor_map": [
                {
                    "id": "ID Card with constraints",
                    "format": "ldp_vp",
                    "path": "$",
                    "path_nested": {
                        "format": "ldp_vc",
                        "path": "$.verifiableCredential[0]"
                    }
                }
            ]
        }
    }
}

A descriptor_map element MAY also contain a path_nested element refering to the actual credential carried in the respective verifiable presentation.

This is an example of a vp_token containing multiple verifiable presentations,

[
    {
        "@context": [
            "https://www.w3.org/2018/credentials/v1"
        ],
        "type": [
            "VerifiablePresentation"
        ],
        "verifiableCredential": [
            {
                "@context": [
                    "https://www.w3.org/2018/credentials/v1",
                    "https://www.w3.org/2018/credentials/examples/v1"
                ],
                "id": "https://example.com/credentials/1872",
                "type": [
                    "VerifiableCredential",
                    "IDCardCredential"
                ],
                "issuer": {
                    "id": "did:example:issuer"
                },
                "issuanceDate": "2010-01-01T19:23:24Z",
                "credentialSubject": {
                    "given_name": "Fredrik",
                    "family_name": "Strömberg",
                    "birthdate": "1949-01-22"
                },
                "proof": {
                    "type": "Ed25519Signature2018",
                    "created": "2021-03-19T15:30:15Z",
                    "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..PT8yCqVjj5ZHD0W36zsBQ47oc3El07WGPWaLUuBTOT48IgKI5HDoiFUt9idChT_Zh5s8cF_2cSRWELuD8JQdBw",
                    "proofPurpose": "assertionMethod",
                    "verificationMethod": "did:example:issuer#keys-1"
                }
            }
        ],
        "id": "ebc6f1c2",
        "holder": "did:example:holder",
        "proof": {
            "type": "Ed25519Signature2018",
            "created": "2021-03-19T15:30:15Z",
            "challenge": "n-0S6_WzA2Mj",
            "domain": "https://client.example.org/cb",
            "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..GF5Z6TamgNE8QjE3RbiDOj3n_t25_1K7NVWMUASe_OEzQV63GaKdu235MCS3hIYvepcNdQ_ZOKpGNCf0vIAoDA",
            "proofPurpose": "authentication",
            "verificationMethod": "did:example:holder#key-1"
        }
    },
    {
        "presentation":
        "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImRpZDpleGFtcGxlOmFiZmUxM2Y3MTIxMjA0
        MzFjMjc2ZTEyZWNhYiNrZXlzLTEifQ.eyJzdWIiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxY
        zI3NmUxMmVjMjEiLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsImlzc
        yI6Imh0dHBzOi8vZXhhbXBsZS5jb20va2V5cy9mb28uandrIiwibmJmIjoxNTQxNDkzNzI0LCJpYXQiO
        jE1NDE0OTM3MjQsImV4cCI6MTU3MzAyOTcyMywibm9uY2UiOiI2NjAhNjM0NUZTZXIiLCJ2YyI6eyJAY
        29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd
        3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZ
        UNyZWRlbnRpYWwiLCJVbml2ZXJzaXR5RGVncmVlQ3JlZGVudGlhbCJdLCJjcmVkZW50aWFsU3ViamVjd
        CI6eyJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IjxzcGFuIGxhbmc9J2ZyL
        UNBJz5CYWNjYWxhdXLDqWF0IGVuIG11c2lxdWVzIG51bcOpcmlxdWVzPC9zcGFuPiJ9fX19.KLJo5GAy
        BND3LDTn9H7FQokEsUEi8jKwXhGvoN3JtRa51xrNDgXDb0cq1UTYB-rK4Ft9YVmR1NI_ZOF8oGc_7wAp
        8PHbF2HaWodQIoOBxxT-4WNqAxft7ET6lkH-4S6Ux3rSGAmczMohEEf8eCeN-jC8WekdPl6zKZQj0YPB
        1rx6X0-xlFBs7cl6Wt8rfBP_tZ9YgVWrQmUWypSioc0MUyiphmyEbLZagTyPlUyflGlEdqrZAv6eSe6R
        txJy6M1-lD7a5HTzanYTWBPAUHDZGyGKXdJw-W_x0IWChBzI8t3kpG253fg6V3tPgHeKXE94fz_QpYfg
        --7kLsyBAfQGbg"
    }
]

with a matching _vp_token in the corresponding id_token.

{
    "iss": "https://self-issued.me/v2",
    "aud": "https://book.itsourweb.org:3000/client_api/authresp/uhn",
    "iat": 1615910538,
    "exp": 1615911138,
    "sub": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs",
    "sub_jwk": {
        "kty": "RSA",
        "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx...DKgw",
        "e": "AQAB"
    },
    "auth_time": 1615910535,
    "nonce": "960848874",
    "_vp_token": {
        "presentation_submission": {
            "id": "Selective disclosure example presentation",
            "definition_id": "Selective disclosure example",
            "descriptor_map": [
                {
                    "id": "ID Card with constraints",
                    "format": "ldp_vp",
                    "path": "$[0]",
                    "path_nested": {
                        "format": "ldp_vc",
                        "path": "$[0].verifiableCredential[0]"
                    }
                },
                {
                    "id": "Ontario Health Insurance Plan",
                    "format": "jwt_vp",
                    "path": "$[1].presentation",
                    "path_nested": {
                        "format": "jwt_vc",
                        "path": "$[1].presentation.vp.verifiableCredential[0]"
                    }
                }
            ]
        }
    }
}

Note: Authentication event information is conveyed via the id token while it's up to the RP to determine what (additional) claims are allocated to id_token and vp_token, respectively, via the claims parameter.

6. Metadata

This specification introduces additional metadata to enable RP and OP to determine the verifiable presentation formats, proof types and algorithms to be used in a protocol exchange.

6.1. RP Metadata

This specification defines new client metadata parameters according to [OpenID.Registration].

RPs indicate the suported formats using the new parameter vp_formats.

  • vp_formats: REQUIRED. An object defining the formats, proof types and algorithms a RP supports. Valid values include jwt_vp and ldp_vp. When this parameter is used, the format property inside a presentation_definition object as defined in [DIF.PresentationExchange] MUST NOT be present inside the claims parameter in the request. The OP MUST ignore format property inside a presentation_definition object even if the RP includes it.

Note that version 2.0.0 of [DIF.PresentationExchange] allows the RP to specify format of each requested credential using the formats property inside the input_descriptor object, in addition to communicating the supported presentation formats using the vp_formats parameter in the RP metadata.

Here is an example for a RP registering with a Standard OP via dynamic client registration:

{
   "client_id": "s6BhdRkqt3",
   "redirect_uris": [
      "https://client.example.org/callback",
      "https://client.example.org/callback2"
   ],
   "client_name": "My Example",
   "token_endpoint_auth_method": "client_secret_basic",
   "application_type": "web",
   "response_types": "code",
   "grant_types": "authorization_code",
   "vp_formats": {
      "jwt_vp": {
         "alg": [
            "EdDSA",
            "ES256K"
         ]
      },
      "ldp_vp": {
         "proof_type": [
            "Ed25519Signature2018"
         ]
      }
   }
}

Here is an example for a RP registering with a SIOP (see [SIOPv2]) with the registration request parameter:

{
   "client_id": "s6BhdRkqt3",
   "redirect_uris": [
      "https://client.example.org/callback"
   ],
   "client_name": "My Example (SIOP)",
   "application_type": "web",
   "response_types": "id_token",
   "vp_formats": {
      "jwt_vp": {
         "alg": [
            "EdDSA",
            "ES256K"
         ]
      },
      "ldp_vp": {
         "proof_type": [
            "Ed25519Signature2018"
         ]
      }
   }
}

6.2. RP Metadata Error Response

This extension defines the following error codes that MUST be returned when the OP does not support client metadata parameters:

  • vp_formats_not_supported: The OP does not support any of the VP formats supported by the RP such as those included in the vp_formats registration parameter.

Error response must be made in the same manner as defined in [OpenID].

6.3. OP Metadata

This specification defines new server metadata parameters according to [OpenID-Discovery].

The OP publishes the formats it supports using the vp_formats metadata parameter as defined above in its "openid-configuration".

7. Security Considerations

7.1. Preventing Replay Attacks

To prevent replay attacks, verifiable presentation container objects MUST be linked to client_id and if provided nonce from the Authentication Request. The client_id is used to detect presentation of credentials to a different than the intended party. The nonce value binds the presentation to a certain authentication transaction and allows the verifier to detect injection of a presentation in the OpenID Connect flow, which is especially important in flows where the presentation is passed through the front channel.

RPs MUST send a nonce parameter complying with the security considerations given in [OpenID], section 15.5.2., with every Authentication Request as a basis for replay detection.

Note: These values MAY be represented in different ways in a verifiable presentation (directly as claims or indirectly be incorporation in proof calculation) according to the selected proof format denated by the format claim in the verifiable presentation container.

Here is a non-normative example for format=jwt_vp (only relevant part):

{
  "iss": "did:example:ebfeb1f712ebc6f1c276e12ec21",
  "jti": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5",
  "aud": "s6BhdRkqt3",
  "nonce": "343s$FSFDa-",
  "nbf": 1541493724,
  "iat": 1541493724,
  "exp": 1573029723,
  "vp": {
    "@context": [
      "<https://www.w3.org/2018/credentials/v1",>
      "<https://www.w3.org/2018/credentials/examples/v1">
    ],
    "type": ["VerifiablePresentation"],

    "verifiableCredential": [""]
  }
}

In the example above, nonce is included as the nonce and client_id as the aud value in the proof of the verifiable presentation.

Here is a non-normative example for format=ldp_vp (only relevant part):

{
  "@context": [ ... ],
  "type": "VerifiablePresentation",
  "verifiableCredential": [ ... ],
  "proof": {
    "type": "RsaSignature2018",
    "created": "2018-09-14T21:19:10Z",
    "proofPurpose": "authentication",
    "verificationMethod": "did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1",
    "challenge": "343s$FSFDa-",
    "domain": "s6BhdRkqt3",
    "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5
      XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqs
      LfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh
      4vGHSrQyHUGlcTwLtjPAnKb78"
  }
}

In the example above, nonce is included as the challenge and client_id as the domain value in the proof of the verifiable presentation.

7.2. Validation of Verifiable Presentations

A verifier MUST validate the integrity, authenticity, and holder binding of any verifiable presentation provided by an OP according to the rules of the respective presentation format.

This requirement holds true even if those verifiable presentations are embedded within a signed OpenID Connect assertion, such as an ID Token or a Userinfo response. This is required because verifiable presentations might be signed by the same holder but with different key material and/or the OpenID Connect assertions may be signed by a 3rd party (e.g. a traditional OP). In both cases, just checking the signature of the respective OpenID Connect assertion does not, for example, check the holder binding.

Note: Some of the available mechanisms are outlined in section 4.3.2 of [DIF.PresentationExchange].

It is NOT RECOMMENDED for the Subject to delegate the presentation of the credential to a third party.

8. Examples

This section illustrates examples when W3C Verifiable Credentials objects are requested using claims parameter and returned in a VP Token.

8.1. Self-Issued OpenID Provider (SIOP)

This section illustrates the protocol flow for the case of communication through the front channel with SIOP.

8.1.1. Authentication request

The following is a non-normative example of how an RP would use the claims parameter to request claims in the vp_token:

  HTTP/1.1 302 Found
  Location: openid://?
    response_type=id_token
    &client_id=https%3A%2F%2Fclient.example.org%2Fcb
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid
    &claims=...
    &state=af0ifjsldkj
    &nonce=n-0S6_WzA2Mj
    &registration_uri=https%3A%2F%2F
      client.example.org%2Frf.txt%22%7D

8.1.1.1. claims parameter
{
    "id_token": {
        "email": null
    },
    "vp_token": {
        "presentation_definition": {
            "id": "vp token example",
            "input_descriptors": [
                {
                    "id": "id card credential with constraints",
                    "format": {
                        "ldp_vc": {
                            "proof_type": [
                                "Ed25519Signature2018"
                            ]
                        }
                    },
                    "constraints": {
                        "limit_disclosure": "required",
                        "fields": [
                            {
                                "path": [
                                    "$.type"
                                ],
                                "filter": {
                                    "type": "string",
                                    "pattern": "IDCardCredential"
                                }
                            },
                            {
                                "path": [
                                    "$.credentialSubject.given_name"
                                ]
                            },
                            {
                                "path": [
                                    "$.credentialSubject.family_name"
                                ]
                            },
                            {
                                "path": [
                                    "$.credentialSubject.birthdate"
                                ]
                            }
                        ]
                    }
                }
            ]
        }
    }
}

8.1.2. Authentication Response (including vp_token)

The successful authentication response contains a vp_token parameter along with id_token and state.

  HTTP/1.1 302 Found
  Location: https://client.example.org/cb#
    id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso
    &vp_token=...
    &state=af0ifjsldkj

8.1.2.1. id_token

This is the example ID Token:

{
   "iss":"https://self-issued.me/v2",
   "aud":"https://client.example.org/cb",
   "iat":1615910538,
   "exp":1615911138,
   "sub":"NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs",
   "auth_time":1615910535,
   "nonce":"n-0S6_WzA2Mj",
   "sub_jwk": {
     "kty":"RSA",
     "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
     4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
     tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
     QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
     SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
     w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
     "e":"AQAB"
    }
    "_vp_token": {
        "presentation_submission": {
            "id": "Selective disclosure example presentation",
            "definition_id": "Selective disclosure example",
            "descriptor_map": [
                {
                    "id": "ID Card with constraints",
                    "format": "ldp_vp",
                    "path": "$",
                    "path_nested": {
                        "format": "ldp_vc",
                        "path": "$.verifiableCredential[0]"
                    }
                }
            ]
        }
    }
}
8.1.2.2. vp_token content

This is the example vp_token containing a verifiable presentation (and credential) in LD Proof format.

Note: in accordance with Section 7 the verifiable presentation's challenge claim is set to the value of the nonce request parameter value and the domain claim contains the RP's client_id.

{
    "@context": [
        "https://www.w3.org/2018/credentials/v1"
    ],
    "type": [
        "VerifiablePresentation"
    ],
    "verifiableCredential": [
        {
            "@context": [
                "https://www.w3.org/2018/credentials/v1",
                "https://www.w3.org/2018/credentials/examples/v1"
            ],
            "id": "https://example.com/credentials/1872",
            "type": [
                "VerifiableCredential",
                "IDCardCredential"
            ],
            "issuer": {
                "id": "did:example:issuer"
            },
            "issuanceDate": "2010-01-01T19:23:24Z",
            "credentialSubject": {
                "given_name": "Fredrik",
                "family_name": "Str&#246;mberg",
                "birthdate": "1949-01-22"
            },
            "proof": {
                "type": "Ed25519Signature2018",
                "created": "2021-03-19T15:30:15Z",
                "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..PT8yCqVjj5ZHD0W36zsBQ47oc3El07WGPWaLUuBTOT48IgKI5HDoiFUt9idChT_Zh5s8cF_2cSRWELuD8JQdBw",
                "proofPurpose": "assertionMethod",
                "verificationMethod": "did:example:issuer#keys-1"
            }
        }
    ],
    "id": "ebc6f1c2",
    "holder": "did:example:holder",
    "proof": {
        "type": "Ed25519Signature2018",
        "created": "2021-03-19T15:30:15Z",
        "challenge": "n-0S6_WzA2Mj",
        "domain": "https://client.example.org/cb",
        "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..GF5Z6TamgNE8QjE3RbiDOj3n_t25_1K7NVWMUASe_OEzQV63GaKdu235MCS3hIYvepcNdQ_ZOKpGNCf0vIAoDA",
        "proofPurpose": "authentication",
        "verificationMethod": "did:example:holder#key-1"
    }
}

8.2. Authorization Code Flow with vp_token

This section illustrates the protocol flow for the case of communication using frontchannel and backchannel (utilizing the authorization code flow).

8.2.1. Authentication Request

  GET /authorize?
    response_type=code
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid
    &claims=...
    &state=af0ifjsldkj
    &nonce=n-0S6_WzA2Mj HTTP/1.1
  Host: server.example.com
8.2.1.1. Claims parameter
{
    "id_token": {
        "email": null
    },
    "vp_token": {
        "presentation_definition": {
            "id": "vp token example",
            "input_descriptors": [
                {
                    "id": "id card credential with constraints",
                    "format": {
                        "ldp_vc": {
                            "proof_type": [
                                "Ed25519Signature2018"
                            ]
                        }
                    },
                    "constraints": {
                        "limit_disclosure": "required",
                        "fields": [
                            {
                                "path": [
                                    "$.type"
                                ],
                                "filter": {
                                    "type": "string",
                                    "pattern": "IDCardCredential"
                                }
                            },
                            {
                                "path": [
                                    "$.credentialSubject.given_name"
                                ]
                            },
                            {
                                "path": [
                                    "$.credentialSubject.family_name"
                                ]
                            },
                            {
                                "path": [
                                    "$.credentialSubject.birthdate"
                                ]
                            }
                        ]
                    }
                }
            ]
        }
    }
}

8.2.2. Authentication Response

HTTP/1.1 302 Found
  Location: https://client.example.org/cb?
    code=SplxlOBeZQQYbYS6WxSbIA
    &state=af0ifjsldkj

8.2.3. Token Request

  POST /token HTTP/1.1
  Host: server.example.com
  Content-Type: application/x-www-form-urlencoded
  Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

  grant_type=authorization_code
  &code=SplxlOBeZQQYbYS6WxSbIA
  &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb

8.2.4. Token Response (including vp_token)

This is the example token response containing a vp_token containg a verifiable presentation (and credential) in LD Proof format.

Note: in accordance with Section 7 the verifiable presentation's challenge claim is set to the value of the nonce request parameter value and the domain claim contains the RP's client_id.

{
   "access_token": "SlAV32hkKG",
   "token_type": "Bearer",
   "refresh_token": "8xLOxBtZp8",
   "expires_in": 3600,
   "id_token": "eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso",
   "vp_token": {
      "@context": [
         "https://www.w3.org/2018/credentials/v1"
      ],
      "type": [
         "VerifiablePresentation"
      ],
      "verifiableCredential": [
         {
            "@context": [
               "https://www.w3.org/2018/credentials/v1",
               "https://www.w3.org/2018/credentials/examples/v1"
            ],
            "id": "https://example.com/credentials/1872",
            "type": [
               "VerifiableCredential",
               "IDCardCredential"
            ],
            "issuer": {
               "id": "did:example:issuer"
            },
            "issuanceDate": "2010-01-01T19:23:24Z",
            "credentialSubject": {
               "given_name": "Fredrik",
               "family_name": "Str&#246;mberg",
               "birthdate": "1949-01-22"
            },
            "proof": {
               "type": "Ed25519Signature2018",
               "created": "2021-03-19T15:30:15Z",
               "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..PT8yCqVjj5ZHD0W36zsBQ47oc3El07WGPWaLUuBTOT48IgKI5HDoiFUt9idChT_Zh5s8cF_2cSRWELuD8JQdBw",
               "proofPurpose": "assertionMethod",
               "verificationMethod": "did:example:issuer#keys-1"
            }
         }
      ],
      "id": "ebc6f1c2",
      "holder": "did:example:holder",
      "proof": {
         "type": "Ed25519Signature2018",
         "created": "2021-03-19T15:30:15Z",
         "challenge": "n-0S6_WzA2Mj",
         "domain": "s6BhdRkqt3",
         "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..GF5Z6TamgNE8QjE3RbiDOj3n_t25_1K7NVWMUASe_OEzQV63GaKdu235MCS3hIYvepcNdQ_ZOKpGNCf0vIAoDA",
         "proofPurpose": "authentication",
         "verificationMethod": "did:example:holder#key-1"
      }
   }
}
8.2.4.1. id_token
{
    "iss": "http://server.example.com",
    "sub": "248289761001",
    "aud": "s6BhdRkqt3",
    "iat": 1615910538,
    "exp": 1615911138,
    "auth_time": 1615910535,
    "nonce": "960848874",
    "_vp_token": {
        "presentation_submission": {
            "id": "Selective disclosure example presentation",
            "definition_id": "Selective disclosure example",
            "descriptor_map": [
                {
                    "id": "ID Card with constraints",
                    "format": "ldp_vp",
                    "path": "$",
                    "path_nested": {
                        "format": "ldp_vc",
                        "path": "$.verifiableCredential[0]"
                    }
                }
            ]
        }
    }
}

9. Normative References

[DIF.PresentationExchange]
Buchner, D., Zunde, B., Riedel, M., and K. H. Duffy, "Presentation Exchange 2.0.0", , <https://identity.foundation/presentation-exchange>.
[OpenID.Registration]
Sakimura, N., Bradley, J., and M. Jones, "OpenID Connect Dynamic Client Registration 1.0 incorporating errata set 1", , <https://openid.net/specs/openid-connect-registration-1_0.html>.
[OpenID-Discovery]
Sakimura, N., Bradley, J., de Medeiros, B., and E. Jay, "OpenID Connect Discovery 1.0 incorporating errata set 1", , <https://openid.net/specs/openid-connect-discovery-1_0.html>.
[OpenID]
Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, "OpenID Connect Core 1.0 incorporating errata set 1", , <http://openid.net/specs/openid-connect-core-1_0.html>.

10. Informative References

[SIOPv2]
Microsoft, Jones, M. B., and T. Looker, "Self-Issued OpenID Provider V2", , <https://openid.bitbucket.io/connect/openid-connect-self-issued-v2-1_0.html>.
[VC_DATA]
Sporny, M., Noble, G., Longley, D., Burnett, D. C., Zundel, B., and D. Chadwick, "Verifiable Credentials Data Model 1.0", , <https://www.w3.org/TR/vc-data-model>.

Appendix A. IANA Considerations

TBD

Appendix B. Acknowledgements

We would like to thank Ronald Koenig, Daniel Fett, Fabian Hauck, and Alen Horvat for their valuable feedback and contributions that helped to evolve this specification.

Appendix C. Notices

Copyright (c) 2021 The OpenID Foundation.

The OpenID Foundation (OIDF) grants to any Contributor, developer, implementer, or other interested party a non-exclusive, royalty free, worldwide copyright license to reproduce, prepare derivative works from, distribute, perform and display, this Implementers Draft or Final Specification solely for the purposes of (i) developing specifications, and (ii) implementing Implementers Drafts and Final Specifications based on such documents, provided that attribution be made to the OIDF as the source of the material, but that such attribution does not indicate an endorsement by the OIDF.

The technology described in this specification was made available from contributions from various sources, including members of the OpenID Foundation and others. Although the OpenID Foundation has taken steps to help ensure that the technology is available for distribution, it takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this specification or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any independent effort to identify any such rights. The OpenID Foundation and the contributors to this specification make no (and hereby expressly disclaim any) warranties (express, implied, or otherwise), including implied warranties of merchantability, non-infringement, fitness for a particular purpose, or title, related to this specification, and the entire risk as to implementing this specification is assumed by the implementer. The OpenID Intellectual Property Rights policy requires contributors to offer a patent promise not to assert certain patent claims against other contributors and against implementers. The OpenID Foundation invites any interested party to bring to its attention any copyrights, patents, patent applications, or other proprietary rights that may cover technology that may be required to practice this specification.

Appendix D. Document History

[[ To be removed from the final specification ]]

-06

-05

-04

-03

-02

-01

-00

Authors' Addresses

Oliver Terbu
walt.id
Torsten Lodderstedt
yes.com
Kristina Yasuda
Microsoft
Adam Lemmon
Convergence.tech
Tobias Looker
Mattr