Copyright © 2022 the Contributors to the Verifiable Presentation Request Specification v0.1 Specification, published by the W3C Credentials Community Group under the W3C Community Contributor License Agreement (CLA). A human-readable summary is available.
This specification describes a declarative JSON-based query language used by applications to perform requests from wallets and agents. The results of the requests are always wrapped in a Verifiable Presentation.
This specification was published by the W3C Credentials Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.
This draft highlights some of the pending issues that are still to be discussed in the community group. No decision has been taken on the outcome of these issues including whether they are valid. Pull requests with proposed specification text for outstanding issues are strongly encouraged.
If you wish to make comments regarding this document, please send them to public-credentials@w3.org (subscribe, archives).
This section is non-normative.
When working with Verifiable Credentials, Decentralized Identifier (DID) based Authentication, and Authorization Capabilities, a client application often needs to request credential-related objects from a wallet or agent. This document presents a specification that describes the format of those requests.
Note: This specification is unstable at present, and only reflects an effort to get initial interop working, for incubation and implementation experience. Additionally, the intention is to align this spec and the query format to fit into/work with other protocols/messaging formats such as DIDComm.
To make a request for one or more objects wrapped in a Verifiable Presentation, a client constructs a JSON request describing one or more queries that it wishes to perform from the receiver.
{ query: [{ type: 'APopularQueryType', // query details ... }, { type: 'AnotherQueryType', // query details ... }], // Challenge that will be digitally signed in the authentication proof // that will be attached to the VerifiablePresentation response challenge, // Required recipients: [ // an optional key agreement key for encrypting the response if // this is supported ], interact: { // an optional set of mechanisms that can be used to respond to the query "service": [{ // a service that can be used to respond to the query where the service // might be an HTTP endpoint, bluetooth location, or P2P protocol }] } }
The query type serves as the main extension point mechanism for requests for data in the presentation. This document defines several common query types.
{ "query": [ { "type": "QueryByExample", "credentialQuery": [ { // One or more example query entries "required": false, // (Optional) Defaults to 'true' if omitted // (Optional) Reason for requesting this credential that // may be shown to a user by their wallet software "reason": "We need you to prove your eligibility to work.", "example": { "@context": ["https://www.w3.org/2018/credentials/v1", "https://w3id.org/citizenship/v1"], "type": "PermanentResidentCard", // (Optional) You can request a specific subject id "credentialSubject": { "id": "...", "name": "..." }, // (Optional) Specify only credentials of a particular schema "credentialSchema": { "id": "urn:foo:1234", "type": "SomeType" }, // (Optional) Specify credentials from a particular issuer only "trustedIssuer": [ { "required": true, "issuer": "urn:some:required:issuer" } ], // (Optional) "issuerQuery": [ // ] } }, { // Another example query "type": "AnotherQueryType" // ... } ] } ], "challenge": "3182bdea-63d9-11ea-b6de-3b7c1404d57f", // the domain that will be digitally signed in the authentication // proof that will be attached to the VerifiablePresentation // response, identifying the recipient "domain": "jobs.example.com" }
{ query: [{ type: 'DIDAuth' }], challenge: '99612b24-63d9-11ea-b99f-4f66f3e4f81a', domain: 'example.com' }
Response:
{ "@context": ["https://www.w3.org/2018/credentials/v1"], "type": "VerifiablePresentation", "holder": "did:example:12345", "proof": { "proofPurpose": "authentication", "type": "Ed25519Signature2018", "challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a", "domain": "example.com", "created": "2020-06-06T21:05:13Z", "verificationMethod": "did:example:12345#z6Mkkg...", "jws": "..." } }
The interaction type serves as the main extension point mechanism for ways of responding to a query.
A mediated presentation service requires the use of an out-of-band interface, for example, a person using a Web browser.
... "interact": { "service": [{ "type": "MediatedBrowserPresentationService2021", "serviceEndpoint": "https://degree.example/fill-out-forms?session=123456" }] } ...
An unmediated presentation service requires no out-of-band interfaces, enabling fully-automated presentation processing.
... "interact": { "service": [{ "type": "UnmediatedHttpPresentationService2021", "serviceEndpoint": "https://degree.example/active-flows/123456" }] } ...
This request query format is intended to be used in a variety of protocols and usage scenarios.
This section is non-normative.
The Credential Handler API (CHAPI) specification enables in-browser Javascript applications to communicate with wallet providers for the purpose of issuing Verifiable Credentials and requesting Verifiable Presentations. Interested implementers are encouraged to look at the Credential Handler Polyfill repository for further discussion and examples.
CHAPI is an extension of the Credential Management API, and includes the following:
navigator.credentials.get(request)
navigator.credentials.store(request)
A VerifiablePresentation is used to both store or present VerifiableCredentials. When storing a VerifiableCredential, the VerifiablePresentation does not need to be signed.
This section is non-normative.
CHAPI provides a single derived class, the WebCredential
that forms
the basis for any sort of credential data that is provided over the Web, i.e.,
via a "Credential Handler" that a origin has registered in the user's browser
when the user visited that origin's website.
const webCredential = new WebCredential('VerifiablePresentation', { '@context': 'https://www.w3.org/2018/credentials/v1', ...presentation });
This section is non-normative.
Using CHAPI, a web application can get()
and store()
credentials without knowing anything about the user's wallet. This is
intentional; for privacy reasons, the client app must not be able to query any
information (without user consent) about which wallets or credential handlers a
user may have installed (otherwise, fingerprinting and other attacks would be
possible).
A web app (a Relying Party or verifier) can request a credential using
credentials.get()
during a user gesture event, for example when
the user pushes a button on a page that requires identity attributes or
authentication.
const credentialQuery = { web: { VerifiablePresentation: { query: { type: 'QueryByExample', credentialQuery: { // an optional reason for requesting this credential that // may be shown to a user by their wallet software reason: 'We need you to prove your eligibility to work.', example: { '@context': [ 'https://www.w3.org/2018/credentials/v1', 'https://w3id.org/citizenship/v1' ], type: 'PermanentResidentCard' } } }, // a 128-bit randomly generated value encoded as a string (use a UUID); // it will be digitally signed in the authentication proof // that will be attached to the VerifiablePresentation response challenge: '3182bdea-63d9-11ea-b6de-3b7c1404d57f', // the domain that must be digitally signed in the authentication // proof that will be attached to the VerifiablePresentation // response, identifying the recipient domain: 'jobs.example.com' } } }; const webCredential = await navigator.credentials.get(credentialQuery); if(!webCredential) { console.log('no presentation received'); } // Response: null // if the user cancels // or a WebCredential with these attributes/values: { "type": "web", "dataType": "VerifiablePresentation", "data": { // Verifiable Presentation goes here, containing the credentials // that the user agreed to share, or `null` if the user canceled } } const {data: presentation} = webCredential; // send `presentation` to server for forwarding to verifier API
A web app (for example, a credential issuer such as a university or institution) can ask to store a credential during a user gesture event, for example when the user pushes a button to receive a credential.
const result = await navigator.credentials.store(webCredential); if(!result) { console.log('store credential operation canceled'); } // Response: null // if the user cancels // or a WebCredential with these attributes/values: { "type": "web", "dataType": "VerifiablePresentation", "data": { // Verifiable Presentation goes here, containing the credentials // that the user agreed to store } }
This section is non-normative.
TBD
This section is non-normative.
TBD. (The intention of this spec is to align the query format with existing protocols and messaging formats such as DIDComm.)
This section is non-normative.
There are a number of security and privacy considerations that implementers will want to take into consideration when implementing this specification.
This section is non-normative.
TBD
This section is non-normative.
The Working Group would like to thank the following individuals for reviewing and providing feedback on the specification (in alphabetical order):
TBD...