Copyright © 2026 World Wide Web Consortium . W3C ® liability , trademark and permissive document license rules apply.
Verifiable credentials provide a mechanism to express credentials on the Web in a way that is cryptographically secure, privacy respecting, and machine-verifiable. This specification provides data model and HTTP protocols to issue, verify, present, and manage data used in such an ecosystem.
This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C standards and drafts index .
This specification is in active development. Deployment in production systems is discouraged unless you are participating in the weekly meetings that coordinate activity around this specification.
This document was published by the Verifiable Credentials Working Group as an Editor's Draft.
Publication as an Editor's Draft does not imply endorsement by W3C and its Members.
This is a draft document and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to cite this document as other than a work in progress.
This document was produced by a group operating under the W3C Patent Policy . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent that the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy .
This document is governed by the 18 August 2025 W3C Process Document .
This section is non-normative.
The Verifiable Credentials specification [ VC-DATA-MODEL-2.0 ] provides a data model and serialization to express digital credentials in a way that is cryptographically secure, privacy respecting, and machine-verifiable. This specification provides a set of HTTP Application Programming Interfaces (HTTP APIs) and protocols for issuing, verifying, presenting, and managing Verifiable Credentials.
When managing verifiable credentials , there are two general types of APIs that are contemplated. The first type of APIs are designed to be used within a single security domain. The second type of APIs can be used to communicate across different security domains. This specification defines both types of APIs.
The APIs that are designed to be used within a single security domain are used by systems that are operating on behalf of a single role such as an issuer , verifier , or holder . One benefit of these APIs for the Verifiable Credentials ecosystem is that they define a useful, common, and vetted modular architecture for managing Verifiable Credentials. For example, this approach helps software architects integrate with common components and speak a common language when implementing systems that issue verifiable credentials . Knowing that a particular architecture has been vetted is also beneficial for architects that do not specialize in verifiable credentials . Documented architectures and APIs increase market competition and reduce vendor lock-in and switching costs.
The APIs that are designed to operate across multiple security domains are used by systems that are communicating between two different roles in a verifiable credential interaction, such as an API that is used to communicate presentations between a holder and a verifier . In order to achieve protocol interoperability in verifiable credentials interactions, it is vital that these APIs be standardized. The additional benefits of documenting these APIs are the same for documenting the single-security-domain APIs: common, vetted architecture and APIs, increased market competition, and reduced vendor lock-in and switching costs.
This specification contains the following sections that software architects and implementers might find useful:
This section is non-normative.
The Verifiable Credentials API is optimized towards the following design goals:
| Goal | Description |
|---|---|
| Modularity | Implementers need only implement the APIs that are required for their use case enabling modularity between Issuing, Verifying, and Presenting. |
| Simplicity | The number of APIs and optionality are kept to a minimum to ensure that they are easy to implement and audit from a security standpoint. |
| Composability | The APIs are designed to be composable such that complex flows are possible using a small number of simple API primitives. |
| Extensibility | Extensions to API endpoints are expected and catered to in the API design enabling experimentation and the addition of value-added services on top of the base API platform. |
A RESTful API approach was used as a basis for the specification. Some endpoints use what is referred to as the 'controller' resource naming style. JSON Schema: A Media Type for Describing JSON Documents is used to define the acceptable inputs to the APIs.
This section is non-normative.
The Verifiable Credentials Data Model defines three fundamental roles, the issuer , the verifier , and the holder .
Actors fulfilling each of these roles may use a number of software or service components to realize the API for exchanging Verifiable Credentials.
Each role associates with a role-specific Coordinator, Service, and Admin as well as their own dedicated Storage Service. In addition, the issuer may also manage a Status Service for revocable credentials issued by the issuer .
Any given implementation may choose to combine any or all of these components into a single functional application. The boundaries and interfaces between these components are defined in this specification to ensure interoperability and substitutability across the Verifiable Credential conformant ecosystem.
Based on this architectural thinking, we may want to frame this API as a roadmap of related specifications, integrated in an extensible way for maximum substitutability. Several technologies, such as EDVs and WebKMSs would likely benefit from the crypto suite Approach taken for verifiable credential proofs. Defining a generic mechanism that can be realized by any functionally conformant technology enables flexibility while laying the groundwork with current existing functionality. In this way, we may be able to acknowledge that elements like Key Services, Storage, and Status are necessary parts of this API while deferring the definition of how those elements work to specification already in development as well as those yet to be written.
In addition to aggregating components into a single app, implementers may choose to operationalize any given role over any number active instances of deployed software. For example, a browser-based holder coordinator should be considered as an amalgam of a web browser, various code running in that browser, one or more web servers (in the case of cross-origin AJAX or remote embedded content), and the code running on that server. Each of those elements runs as different software packages in different configurations, each executing just part of the overall functionality of the component. For the sake of this API, each component satisfies all of its required functionality as a whole, regardless of deployment architecture.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY , MUST , MUST NOT , OPTIONAL , RECOMMENDED , REQUIRED , SHOULD , and SHOULD NOT in this document are to be interpreted as described in BCP 14 [ RFC2119 ] [ RFC8174 ] when, and only when, they appear in all capitals, as shown here.
A conforming issuer service implementation MUST provide the interface described in Section 3.2.1 Issue Credential . Other interfaces described in Section 3.2 Issuing MAY also be provided.
A conforming verifier service implementation MUST provide the interface described in Section 3.3.1 Verify Credential and Section 3.3.2 Verify Presentation . Other interfaces described in Section 3.3 Verifying MAY also be provided.
A conforming holder service implementation MUST provide the interface described in Section 3.6.4 Get Exchange Protocols and Section 3.6.6 Participate in an Exchange . Conformance to protocols, query languages, and data formats described in Section 3.7 Initiating Interactions , Section 3.4 Requesting a Presentation , Section 3.5.2 Create Presentation , Section 3.5 Presenting , and Section 3.6 Workflows and Exchanges MAY also be provided.
A
conforming
status
service
implementation
MUST
provide
the
interface
described
in
Section
C.3
B.3
Update
Status
.
A conforming workflow service implementation MUST provide all interfaces Section 3.6 Workflows and Exchanges .
A conforming service client implementation MUST provide the means to communicate with all REQUIRED interfaces provided by the corresponding service implementation. That is, a status client implementation provides means to communicate with all mandatory interfaces exposed by a status service implementation .
All implementations MAY provide functionality beyond this specification.
This section is non-normative.
Terminology used throughout this document is defined in the Terminology section of the Verifiable Credentials Data Model v2.0 specification.
A coordinator executes the business rules and policies set by the associated role. Often this is a custom or proprietary coordinator developed specifically for a single party acting in that role; it is the integration glue that connects the controlling party to the verifiable credential ecosystem.
Coordinators might provide a visual user interface, depending on the implementation. Pure command-line or continuously running services might also be able to realize this component.
With the exception of the status service , all role-to-role communication is between coordinators acting on behalf of its particular actor to fulfill its role.
An issuer coordinator executes the rules about who gets what credentials, including how the parties creating or receiving those credentials are authenticated and authorized. Typically the issuer coordinator integrates the issuer 's back-end system with the issuer service . This integration uses whatever technologies are appropriate; the interfaces between the issuer coordinator and back-end services are out of scope for this specification. The issuer coordinator drives the issuer service .
A verifier coordinator communicates with a verifier service to first check authenticity and timeliness of a given verifiable credential or verifiable presentation , then applies the verifier 's business rules before ultimately accepting or rejecting that verifiable credential or verifiable presentation . Such business rules might include evaluating the issuer of a particular claim or simply checking a configured allow-list. The verifier coordinator exposes an API for submitting verifiable credentials to the verifier per the verifier 's policies. For example, the verifier coordinator might only accept verifiable credentials from current users of the verifier 's other services. These rules typically require bespoke integration with the verifier 's existing back-end.
A holder coordinator executes the business rules for approving the flow of credentials under the control of the holder , from issuers to verifiers . In some deployments this means exposing a user interface that gives individual holders a visual way to authorize or approve verifiable credential storage or transfer. Some functionality of the holder coordinator is commonly referred to as a digital wallet . In this API, the holder coordinator initiates all flows. They request verifiable credentials from issuers . They decide if, and when, to share those verifiable credentials with verifiers . Within this API, there is no way for either the issuer or the verifier to initiate the transfer of a verifiable credential . In many scenarios, the holder coordinator is expected to be under the control of an individual human, ensuring a person is directly involved in the communication of verifiable credentials , even if only at the step of authorizing the transfer. However, some verifiable credentials are about organizations, not individuals. How individuals using holder coordinator s related to organizations, and in particular, how organizational credentials are securely shared with, and presented by, (legal) agents of those organizations is not in scope for this specification.
A service provides lower-level API functionality, driven by its associated coordinator , and is designed to enable infrastructure providers to offer verifiable credential capability through service delivery architectures such as Software-as-a-Service. All services expose HTTP endpoints to their authorized coordinators , which are themselves operating on behalf of an associated role. Although deployed services might provide their own HTML interfaces, such interfaces are out of scope for this specification. Only the HTTP endpoints of services are defined herein.
An issuer service takes requests to issue verifiable credentials from authorized issuer coordinators and return conforming verifiable credentials . This service has access to cryptographic material, such as private keys or key services which utilize private keys, in order to create the proofs for verifiable credentials . The API between the issuer service and its associated cryptographic key management service is out of scope for this specification.
A verifier service takes requests to verify verifiable credentials and verifiable presentations and returns the result of checking their proofs and status (if present). The service only checks the authenticity and timeliness of the verifiable credential , leaving the verifier coordinator to finish applying any necessary business rules.
A holder service takes requests to create Verifiable Presentations from an optional set of verifiable credentials and returns well-formed, signed Verifiable Presentations containing those VCs. These verifiable presentation s are used with issuers to demonstrate control over DIDs prior to verifiable credential issuance and with verifiers to present specific VCs.
A status service provides a privacy-preserving means of publishing and checking the status of any Verifiable Credentials issued by the issuer . Implementers of verifier services are encouraged to understand the privacy implications of checking status by referring to the respective status specification used by the verifiable credential. For specific mechanisms by which to manage verifiable credential statuses, it's recommended to refer to well-known external specifications, such as the [ VC-BITSTRING-STATUS-LIST ].
A storage service is used by each actor in the system to store their own verifiable credentials and corresponding data, as needed. Several known implementations use secure data storage such as encrypted data vaults for storing the holder 's verifiable credentials and use cryptographic authorizations to grant access to those verifiable credentials to verifier coordinator s, as directed by the holder . In-browser retrieval of such stored credentials can enable web-based verifier coordinator s to integrate data from the holder without sharing that data with the verifier —the data is only ever present in the browser. Authorizing third-party remote access to holder storage is likely in-scope for this API, although we expect this to be defined using extensible mechanisms to support a variety of storage and authorization approaches.
The issuer and verifier storage solutions may or may not use secure data storage. Since all such storage interaction is moderated by the bespoke issuer and Storage Coordinators, any necessary integrations can simply be part of that bespoke customization. We expect different implementations to compete on the ease of integration into various back-end storage platforms.
A workflow service provides a way for coordinators to automate specific interactions for specific users. Each role ( holder , issuer , and verifier ) can run their own workflow service to create and manage exchanges that realize particular workflows. Administrators configure the workflow system to support particular flows. Then, when the business rules justify it, coordinators create exchanges at their workflow service and give access to those exchanges to any authorized party.
An administration service is an acknowledgement that each of the other components need a way to be configured and managed, without prescribing the interfaces or means of that configuration. Some components might use JSON files to drive a command line interface. Others might expose HTML pages. It is expected that different implementations will compete on the power, ease, and flexibility of their administration and therefore, configuration is largely out of scope for this specification. There are some places where some configuration mechanisms are provided, such as in Section 3.6.1 Create Workflow , where there was broad agreement to standardize some configuration parameters. As the market matures, other areas of configuration standardization might occur in future versions of this specification.
The APIs defined in this specification presume that they are attached to a specific instance with an associated configuration that has been put in place by a system administrator. When a client calls an endpoint on a particular instance , the instance uses the configuration and options provided by the client to execute the action.
For
example,
the
/credentials/issue
endpoint
can
be
provided
at
the
end
of
a
longer
URL
such
as
/instances/12345/credentials/issue
.
In
this
case,
it
is
the
instance
that
is
configured
to
know
which
cryptographic
key
to
use
for
issuance,
whether
or
not
a
status
list
is
involved,
the
type
of
credential
to
issue,
the
credential
format,
and
what
additional
options
are
possible
on
the
endpoint.
Software clients that call a particular instance might not have the capability to configure an instance , or be aware of the setup that the administrator did on the instance other than the requisite details to make appropriate use of it. Administration endpoints for configuring instances could be provided by implementations but are not necessarily exposed as HTTP APIs; configuration can also be done through configuration files or graphical interfaces.
A coordinator instance can have access to multiple service instances in order to support different use cases or a use case with complex flows. Runtime discovery of service instance configuration is not defined by this specification as services are expected to be known by the coordinator at the time of deployment.
Each coordinator or service instance is associated with a specific configuration that drives its behavior. This section contains how some of those configurations might be performed.
There
are
no
restrictions
put
on
the
base
URL
for
any
particular
instance
.
The
URL
paths
used
throughout
this
specification
are
shown
as
absolute
paths
and
their
base
URL
MAY
be
the
host
name
of
the
server
(e.g.,
website.example
),
a
subdomain
(e.g.,
api.website.example
,
or
a
path
within
that
domain
(e.g.,
website.example/api
).
This API can be deployed in a variety of networking environments which might contain hostile actors. As a result, conforming service implementations require conforming service client implementations to utilize secure authorization technologies when performing certain types of requests. Each HTTP endpoint defined in this document specifies whether or not authorization is required when performing a request. With the exception of the class of forbidden authorization protocols discussed later in this section, this API is agnostic regarding authorization mechanism.
This API is meant to be generic and useful in many scenarios that require the issuance, possession, presentation, and/or verification of Verifiable Credentials. To this end, implementers are advised to consider the following classifications of use cases:
The rest of this section gives examples of the authorization technologies that have been contemplated for use by conforming implementations. Other equivalent authorization technologies can be used. Implementers are cautioned against using non-standard or legacy authorization technologies.
Requests to this API MUST NOT utilize any authorization protocol that includes long-lived static credentials such as usernames and passwords or similar values in those requests. An example of such a forbidden protocol is HTTP Basic Authentication [ RFC7617 ].
If Authorization Capabilities (ZCAPs) are used for authorization, the administrator is expected to delegate a ZCAP with the appropriate format as defined in [ ZCAP ] and as needed for the use case. This includes appropriate values for the controller, invocation target, and allowed actions, among other important properties.
{
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:cdc77118-6bfa-11ec-aceb-10bf48838a41",
"parentCapability": "urn:zcap:root:https%3A%2F%2Fvcalm-instances.example.com%2Fissuers%2Fb77c9b57-c321-4d14-902c-8f442a37707d%2Fworkflows%2Fa6513552-8e5a-4efa-b36e-1fb2a8e06822%2Fexchanges",
"controller": "did:key:z6MknBxrctS4KsfiBsEaXsfnrnfNYTvDjVpLYYUAN6PX2EfG",
"invocationTarget": "https://vcalm-instances.example.com/workflows/a6513552-8e5a-4efa-b36e-1fb2a8e06822/exchanges",
"expires": "2027-06-30T16:45:73Z",
"allowedAction": [
"write",
"read"
],
"proof": {
"type": "Ed25519Signature2020",
"created": "2026-06-30T16:45:73Z",
"verificationMethod": "did:key:z6MkfWKcvBiKCfNgz5UUGseNt37t4dguEvFgJ9XvX2UV6zB9#z6MkfWKcvBiKCfNgz5UUGseNt37t4dguEvFgJ9XvX2UV6zB9",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Fvcalm-instances.example.com%2Fissuers%2Fb77c9b57-c321-4d14-902c-8f442a37707d%2Fworkflows%2Fa6513552-8e5a-4efa-b36e-1fb2a8e06822%2Fexchanges"
],
"proofValue": "z3t9BCQyF21MDVYmLKc9zbLreqx4wBtQnUsd5aqyoWS5FfhapRz7QjPNLcgKAornUVmJR4ZjbGpuxRFnffxX1ZjtF"
}
}
The
read
action
enables
operations
that
do
not
create
or
update
resources
in
the
system
to
be
performed
on
the
provided
path,
or
on
any
path
containing
the
provided
path
as
a
prefix,
as
permitted
by
invocationTarget
and
allowedAction
in
the
ZCAP.
The
write
action
enables
operations
that
create
and/or
update
resources
in
the
system
to
be
performed
on
the
provided
path,
or
on
any
path
that
contains
the
provided
path
as
a
prefix,
as
permitted
by
invocationTarget
and
allowedAction
in
the
ZCAP.
To
enforce
the
principle
of
least
privilege,
implementers
are
expected
to
apply
the
following
best
practices:
invocationTarget
property
and
the
client
that
is
authorized
to
access
those
resources
via
the
controller
property.
This
enables
the
ZCAP
to
be
pinned
to
a
particular
client
and
server
(along
with
its
resources).
Example
invocationTarget
value:
https://vcalm-instances.example.com/workflows/a6513552-8e5a-4efa-b36e-1fb2a8e06822
.
Example
controller
value:
did:key:z6MknBxrctS4KsfiBsEaXsfnrnfNYTvDjVpLYYUAN6PX2EfG
.
invocationTarget
and
allowedAction
values
to
include
in
ZCAPs
distributed
to
clients,
based
on
the
HTTP
method
(e.g.,
GET
->
read
,
POST
->
write
)
and
the
expected
caller
of
the
API
endpoint
of
interest.
Examples of valid delegated capability subsets are shown below:
{
...
"controller": "did:key:z6MknBxrctS4KsfiBsEaXsfnrnfNYTvDjVpLYYUAN6PX2EfG",
"invocationTarget": "https://vcalm-instances.example.com/workflows/a6513552-8e5a-4efa-b36e-1fb2a8e06822",
"allowedAction": [
"write",
"read"
],
...
}
{
...
"controller": "did:key:z6MknBxrctS4KsfiBsEaXsfnrnfNYTvDjVpLYYUAN6PX2EfG",
"invocationTarget": "https://vcalm-instances.example.com/workflows/a6513552-8e5a-4efa-b36e-1fb2a8e06822/exchanges",
"allowedAction": [
"write",
"read"
],
...
}
{
...
"controller": "did:key:z6MknBxrctS4KsfiBsEaXsfnrnfNYTvDjVpLYYUAN6PX2EfG",
"invocationTarget": "https://vcalm-instances.example.com/issuers/b77c9b57-c321-4d14-902c-8f442a37707d/credentials/issue",
"allowedAction": [
"write"
],
...
}
If the OAuth 2.0 Authorization Framework [ RFC6749 ] is used for authorization, the access tokens used by clients are expected to be OAuth 2.0 Bearer Tokens [ RFC6750 ] or any other valid OAuth 2.0 token type. Any valid OAuth 2.0 grant type can be used to request the access tokens.
| VCALM OAuth 2.0 Scope Syntax |
|---|
|
scope
=
operation
":"
path-absolute
(defined
in
[
RFC3986
])
operation = "read" / "write" |
The
read
operation
enables
actions
that
do
not
create
or
update
resources
in
the
system
to
be
performed
on
the
provided
path,
or
on
any
path
containing
the
provided
path
as
a
prefix.
The
write
operation
enables
actions
that
create
and/or
update
resources
in
the
system
to
be
performed
on
the
provided
path,
or
on
any
path
that
contains
the
provided
path
as
a
prefix.
To
enforce
the
principle
of
least
privilege,
implementers
are
expected
to
apply
the
following
best
practices:
aud
(audience)
claim
that
identifies
a
specific
instance
for
which
the
access
token
applies,
allowing
the
token
to
be
pinned
to
a
particular
instance.
For
multi-tenant
deployments,
this
is
expected
to
include
the
component
instance
of
interest.
Example
aud
value:
https://vcalm-instances.example.com/workflows/a6513552-8e5a-4efa-b36e-1fb2a8e06822
.
aud
)
in
the
scopes
configured
for
the
OAuth
2.0
issuer
(see
examples
below).
GET
->
read
,
POST
->
write
)
and
the
expected
caller
of
the
API
endpoint
of
interest.
Examples of valid OAuth 2.0 scopes are shown below:
read:/
would
allow
a
client
to
retrieve
resources
via
any
API
on
a
particular
instance
(an
access
token
with
this
scope
is
expected
to
be
distributed
to
an
administrator
and
the
full
instance
ID
would
be
included
in
the
decoded
JWT's
aud
claim).
write:/
would
allow
a
client
to
create
and
modify
resources
via
any
API
on
a
particular
instance
(an
access
token
with
this
scope
is
expected
to
be
distributed
to
an
administrator
and
the
full
instance
ID
would
be
included
in
the
decoded
JWT's
aud
claim).
write:/exchanges
would
allow
a
client
to
create
an
exchange
on
a
particular
workflow
instance
(an
access
token
with
this
scope
is
expected
to
be
distributed
to
a
coordinator
and
the
full
workflow
instance
ID
would
be
included
in
the
decoded
JWT's
aud
claim).
read:/exchanges
would
allow
a
client
to
retrieve
the
state
of
an
exchange
originating
from
a
particular
workflow
instance
(an
access
token
with
this
scope
is
expected
to
be
distributed
to
a
coordinator
and
the
full
workflow
instance
ID
would
be
included
in
the
decoded
JWT's
aud
claim).
write:/credentials/issue
would
allow
a
client
to
access
the
API
endpoint
for
credential
issuance
on
a
particular
issuer
instance
(an
access
token
with
this
scope
is
expected
to
be
distributed
to
an
issuer
coordinator
or
a
workflow
service
and
the
full
issuer
instance
ID
would
be
included
in
the
decoded
JWT's
aud
claim).
Broad
OAuth
2.0
scopes
such
as
read:/
and
write:/
can
lead
to
security
vulnerabilities
in
multi-tenant
environments,
such
as
when
multiple
issuer
coordinators
might
use
different
issuer
instances
hosted
on
the
same
issuer
service
.
Implementers
are
advised
to
ensure
that
access
tokens
expressed
as
JSON
Web
Tokens
include
an
aud
(audience)
claim
that
identifies
a
specific
instance
for
which
the
access
token
applies,
allowing
the
token
to
be
pinned
to
a
particular
instance.
It
is
advised
that
OAuth
2.0
scopes
be
kept
as
narrow
as
possible
without
making
them
overly
burdensome
to
security
administrators.
Some
of
the
endpoints
defined
in
the
following
sections
accept
an
options
object.
All
properties
of
the
options
object
are
OPTIONAL
when
configuring
each
instance,
as
these
properties
are
intended
to
meet
per-deployment
needs
that
might
vary.
Thus,
any
given
instance
configuration
MAY
prohibit
client
use
of
some
options
properties
in
order
to
prevent
clients
from
passing
certain
data
to
that
instance.
Likewise,
an
instance
configuration
MAY
require
that
clients
include
some
options
properties.
Implementations
MAY
extend
an
options
object
with
additional
properties.
As extension properties are implementation specific, they ought not be mandatory. This is to maintain interoperability by avoiding clients needing to be modified to use a specific implementation.
When
adding
an
extension
options
property,
consider
whether
providing
optionality
to
clients
is
necessary.
If
not,
using
instance
configuration
to
vary
API
functionality
might
be
a
preferable
approach.
Implementations MUST throw an error if an endpoint receives data, options, or option values that it does not understand or know how to process.
All
entity
bodies
in
requests
and
responses
sent
to
or
received
from
the
API
endpoints
defined
by
this
specification
MUST
be
serialized
as
JSON
and
include
the
Content-Type
header
with
a
media
type
value
of
application/json
.
This section is non-normative.
The
OpenAPI
descriptions
in
this
specification
represent
verifiable
credential
and
verifiable
presentation
request
and
response
bodies
using
a
minimal
property
table:
@context
and
type
.
This
keeps
the
API
description
focused
on
what
VCALM
defines
—
HTTP
endpoints,
request
and
response
structure,
options
,
workflows,
exchanges,
and
related
coordinator
and
service
behavior
—
rather
than
repeating
the
full
graph
of
a
verifiable
credential
or
verifiable
presentation
in
every
endpoint
table.
The semantic content of credentials and presentations exchanged through these APIs is defined by the Verifiable Credentials ecosystem specifications that apply to a given deployment. VCALM interop testing is intended to exercise API behavior; data model conformance is out of scope for this specification and is covered by separate test suites.
OpenAPI
uses
separate
schema
names
for
the
same
sparse
property
table
where
the
API
distinguishes
roles:
Credential
and
Presentation
for
input
documents
(for
example,
credential
in
an
issue
request),
and
VerifiableCredential
and
VerifiablePresentation
where
a
secured
artifact
is
expected
(for
example,
verifiableCredential
in
a
response).
The
schemas
share
the
same
underlying
document
shape;
the
names
signal
API
usage
rather
than
different
normative
data
model
requirements.
Where
this
specification
needs
to
express
support
for
alternate
serializations
at
the
API
boundary,
it
does
so
explicitly
through
EnvelopedVerifiableCredential
,
EnvelopedVerifiablePresentation
,
and
negotiation
properties
such
as
acceptedEnvelopes
and
acceptedCryptosuites
in
verifiable
presentation
requests
.
See
Section
3.4
Requesting
a
Presentation
.
Implementers are encouraged to pay attention to the payload sizes of the Verifiable Credentials that their implementations process.
Presentations can bundle a large volume of credentials, which can result in a higher request size than anticipated by implementers. This raises the risk of interoperability issues.
A default maximum size of 10MB per verifiable credential is RECOMMENDED as an interoperability baseline, with the possibility of configuring a larger size if required. This also accommodates the 16MB size limit of most document-based database storage solutions.
By default, large binary values are expected to be linked to and a hash included (unless there is a privacy reason for not doing so).
This section contains the HTTP API endpoint definitions and implementation guidance that is to be followed when creating conforming implementations .
This section gives an overview of all endpoints in the VC-API by the component the endpoint is expected be callable from. If a component does not have a listing below it means the VC-API does not currently specify any endpoints for that component.
Below are all endpoints expected to be exposed by the issuer coordinator , along with the component that is expected to call the endpoint.
Below are all endpoints expected to be exposed by the issuer service , along with the component that is expected to call the endpoint.
Below are all endpoints expected to be exposed by the verifier coordinator , along with the component that is expected to call the endpoint.
Below are all endpoints expected to be exposed by the verifier service , along with the component that is expected to call the endpoint.
Below are all endpoints expected to be exposed by the holder coordinator , along with the component that is expected to call the endpoint.
Below are all endpoints expected to be exposed by the holder service , along with the component that is expected to call the endpoint.
Below are all endpoints expected to be exposed by the status service , along with the component that is expected to call the endpoint.
Below are all endpoints expected to be exposed by the Workflow Service, along with the component that is expected to call the endpoint.
The following APIs are defined for issuing a Verifiable Credential:
This endpoint is used to issue a verifiable credential .
To
issue
credentials
with
a
media
type
other
than
application/vc
—
such
as
application/mdoc
,
application/vc+sd-jwt
,
application/vcb;barcode-format=qr_code
,
or
application/vcb;barcode-format=pdf417
—
an
EnvelopedVerifiableCredential
can
be
returned
in
the
response.
If
a
use
case
requires
an
issuer
instance
to
attach
multiple
proofs
to
the
provided
credential
,
the
instance
MUST
attach
all
of
these
proofs
in
response
to
a
single
call
to
the
/credentials/issue
endpoint.
If
a
provided
credential
already
contains
one
or
more
proofs,
the
behavior
is
determined
by
the
configuration
of
the
issuer
instance.
An
issuing
instance
SHOULD
be
configured
to
handle
existing
proofs
in
one
of
the
following
ways:
previousProof
property
to
establish
the
chain
relationship.
credential
values
that
contain
existing
proof
values
are
provided,
when
the
instance
is
configured
to
only
accept
credentials
without
existing
proofs.
The specific approach used depends on the configuration of the issuer instance and the intended use case for the verifiable credential.
An
issuer
service
or
a
holder
service
might
store
an
issued
verifiable
credential
for
an
extended
period
of
time.
When
this
is
done,
it
can
be
useful
to
delete
such
a
verifiable
credential
;
for
instance,
an
issuer
might
need
to
do
so
because
of
regulatory
requirements
such
as
the
right
to
be
forgotten
.
See
Section
B.3
Deletion
#deletion
for
additional
considerations
related
to
the
removal
of
verifiable
credentials
from
systems.
The following APIs are defined for verifying a Verifiable Credential:
This endpoint is used to verify a verifiable credential .
To
verify
credentials
with
a
media
type
other
than
application/vc
,
such
as
application/mdoc
,
application/vc+sd-jwt
,
application/vcb;barcode-format=qr_code
,
or
application/vcb;barcode-format=pdf417
—
an
EnvelopedVerifiableCredential
can
be
provided
in
the
request.
This endpoint is used to verify a verifiable presentation and, by default, all verifiable credentials contained within it.
The verification process includes:
Business rule validation (such as verifying that credential subjects match the presentation holder, or authorization policies about who can present which credentials) is outside the scope of this verification endpoint and should be performed by the calling application.
The
instance
should
create
a
challenge
for
use
during
verification,
and
track
the
number
of
times
the
challenge
has
been
passed
to
verification
endpoints
as
options.challenge
.
When working with verifiable credentials , and decentralized identifier -based authentication, one party often needs to request data from another. This section describes the general format of those requests and provides a concrete verifiable presentation request format as well.
A verifiable presentation request is a request a verifier makes to a holder for a presentation . To make a request for one or more credentials wrapped in a verifiable presentation , a verifier constructs a JSON request describing one or more credentials that it wishes to receive from the holder . The general format for a request looks like the following:
{
// one or more requests for verifiable credentials
"query": [{
"type": "QueryByExample",
// query details specific to QueryByExample...
}],
// The target security domain, such as a website domain, to include in
// the verifiable presentation
"domain": "domain.example",
// The random challenge string to include in the verifiable presentation
"challenge": "f63cb0d2-760e-11f0-a2b1-67febb854a5f"
}
The
query
property
serves
as
the
main
extension
point
mechanism
for
requests
for
data
in
the
presentation.
While
this
document
defines
a
common
query
mechanism
(see
Section
3.4.2
Query
By
Example
),
all
query
objects
are
of
the
following
form:
type
property
with
an
associated
string
value.
The "query by example" credential query format is designed to enable developers to easily request the claims that they need from one or more verifiable credentials , to enable a particular business process. The query can also specify other information, such as one or more issuers that are trusted by the verifier .
The
credentialQuery
property
in
a
QueryByExample
query
is
a
single
object.
Logical
"AND"
and
"OR"
operations
for
combining
multiple
queries
are
handled
through
the
group
property
at
the
query
level,
as
described
in
Section
3.4.5
Logical
Operations
in
Queries
.
Multiple
queries
with
the
same
group
value
are
processed
as
"AND"
operations,
while
queries
with
different
or
missing
group
values
are
processed
as
"OR"
operations.
{
"query": [{
"type": "QueryByExample",
"credentialQuery": {
// (Optional) Reason for requesting this credential that
// may be shown to a user by their software
"reason": "We need to know if you are an alumni of this school.",
// (Optional) An example of the credential being requested
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2"
],
"type": "ExampleAlumniCredential",
// (Optional) Select credential based on credential subject type
"credentialSubject": {
"type": "Alumni"
}
},
// (Optional) Specify credentials from particular acceptedIssuers or
// delegates of the authority
"acceptedIssuers": [
{
"id": "did:web:authority.example"
},
"did:web:different-issuer.example"
]
}
}],
"challenge": "3182bdea-63d9-11ea-b6de-3b7c1404d57f",
"domain": "reunion.example"
}
The
credentialQuery
object
supports
the
following
properties:
| Property | Description |
|---|---|
| reason | An OPTIONAL string that provides a human-readable explanation for why the credential is being requested. This MAY be displayed to the holder by their software. |
| example |
An
OPTIONAL
object
that
provides
an
example
of
the
credential
being
requested,
including
its
@context
,
type
,
and
optionally
credentialSubject
fields
to
indicate
which
claims
are
needed.
|
| acceptedIssuers |
An
OPTIONAL
array
of
items,
or
lists
that
contain
items,
that
identify
entities
that
the
verifier
recognizes
and
accepts
as
issuers
of
the
verifiable
credential
.
Each
item
MUST
be
either
1)
a
[
URL
]
that
identifies
an
issuer
in
the
issuer
property
of
the
received
verifiable
credential
,
or
2)
an
object
that
contains
an
id
property
whose
value
is
a
[
URL
]
that
identifies
an
issuer
in
the
issuer
property
of
the
received
verifiable
credential
,
or
3)
an
object
that
contains
a
recognizedIn
property
that
is
associated
with
an
object
with
a
type
property
that
is
set
to
RecognizedEntityCredential
and
an
id
property
with
a
[
URL
]
value
that
points
to
such
a
credential
as
defined
in
the
Recognized
Entities
v1.0
specification;
the
list
contains
recognized
issuers
that
are
acceptable
to
the
verifier
.
Valid
example
values
include:
|
| acceptedCryptosuites |
An
OPTIONAL
array
specifying
which
cryptographic
proof
suites
the
verifier
will
accept.
Each
element
SHOULD
be
an
object
with
a
cryptosuite
property
referencing
a
Data
Integrity
cryptosuite
name
or
Ed25519Signature2020
for
legacy
(for
backwards
compatibility,
string
values
MAY
also
be
used
and
are
to
be
interpreted
as
the
cryptosuite
name).
This
enables
the
holder
to
select
an
appropriate
proof
format.
This
property
MAY
be
used
independently
of
acceptedEnvelopes
,
which
is
only
applicable
to
enveloped
credentials.
Valid
example
values
include:
|
| acceptedEnvelopes |
An
OPTIONAL
array
specifying
which
envelope
formats
the
verifier
will
accept.
Each
element
SHOULD
be
an
object
with
a
mediaType
property
referencing
the
media
type
for
the
envelope
(for
backwards
compatibility,
string
values
MAY
also
be
used
and
are
to
be
interpreted
as
the
media
type).
This
enables
the
holder
to
provide
credentials
in
formats
other
than
the
default
Data
Integrity
format.
This
property
MAY
be
used
independently
of
acceptedCryptosuites
,
which
is
only
applicable
to
JSON-LD
credentials
signed
with
an
acceptable
cryptosuite.
Valid
example
values
include:
|
A
JSON
Schema
for
a
QueryByExample
is
provided
in
a
separate
file
for
integration
into
software
systems.
The following example demonstrates a QueryByExample that specifies accepted cryptosuites and envelope formats, enabling the holder to choose an appropriate proof mechanism:
{
"query": [{
"type": "QueryByExample",
"credentialQuery": {
"reason": "Please present your PermanentResidentCard to complete the verification process.",
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/citizenship/v3"
],
"type": ["PermanentResidentCard"],
"credentialSubject": {
"birthCountry": ""
}
},
"acceptedCryptosuites": [
{"cryptosuite": "eddsa-rdfc-2022"},
{"cryptosuite": "ecdsa-rdfc-2019"},
{"cryptosuite": "bbs-2023"},
{"cryptosuite": "ecdsa-sd-2023"}
],
"acceptedEnvelopes": [
{"mediaType": "application/jwt"},
{"mediaType": "application/vc+sd-jwt"}
]
}
}],
"challenge": "9876fedc-ba98-7654-3210-fedcba987654",
"domain": "immigration.example"
}
In
the
example
above,
the
verifier
indicates
it
will
accept
credentials
secured
with
any
of
the
listed
cryptosuites.
By
including
bbs-2023
and
ecdsa-sd-2023
,
the
verifier
signals
that
selective
disclosure
proofs
are
acceptable,
allowing
the
holder
to
reveal
only
the
birthCountry
field
rather
than
the
entire
credential.
The
acceptedEnvelopes
property
indicates
that
JWT-based
envelope
formats
are
also
acceptable.
Any
field
included
in
a
Query
By
Example
is
a
required
field.
This
means
that
when
using
a
Query
By
Example
to
enable
selective
disclosure,
a
requester
needs
to
be
mindful
not
to
include
fields
in
their
query
that
are
not
needed
for
their
use
case.
Query
By
Example
provides
no
way
to
indicate
an
"optional"
field;
consequently,
it
is
up
to
the
wallet
that
is
responding
to
the
query
to
ensure
that
its
response
does
not
reveal
any
information
beyond
what
is
being
requested.
Note:
Some
securing
mechanisms
for
verifiable
credentials
do
not
permit
selective
disclosure;
in
these
cases,
unrequested
information
might
have
to
be
sent
in
order
to
send
the
requested
information.
Digital
wallets
are
expected
to
inform
users
about
what
information
will
be
shared.
To
request
a
field
without
any
statement
about
an
expected
value,
a
requester
can
include
the
field
in
the
request
and
leave
the
value
as
an
empty
string.
For
instance,
if
a
requester
needs
a
first
name,
they
could
include
the
optional
"
credentialSubject
"
object
with
a
single
field,
"firstName":
""
.
This
would
allow
a
wallet
to
respond
with
only
the
firstName
of
the
requested
credential
with
no
expectation
of
any
other
field
being
included.
_This
does
not
prevent
a
wallet
from
oversharing
by
including
additional
fields
in
its
response
to
the
query._
To
signal
that
selective
disclosure
cryptosuites
are
acceptable,
verifiers
SHOULD
include
cryptosuites
such
as
bbs-2023
or
ecdsa-sd-2023
in
the
acceptedCryptosuites
array.
This section defines how a verifier can request that a holder perform Decentralized Identifier-based Authentication [ DID-CORE ]. In its simplest form, the authentication protocol is comprised of a challenge by the verifier and a response by a holder :
{
"query": [{
"type": "DIDAuthentication",
"acceptedMethods": [{"method": "example"}]
}],
"challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
"domain": "example.com"
}
The DID Authentication request above specifies that the verifier would like the holder to demonstrate control over a DID by generating a digital signature over the provided challenge. The holder might respond by providing the following response:
{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": "VerifiablePresentation",
"holder": "did:example:12345",
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-rdfc-2022",
"verificationMethod": "did:example:12345#key-1",
"challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
"domain": "example.com",
"created": "2024-02-25T14:58:42Z",
"proofPurpose": "authentication",
"proofValue": "z3FXQjecWufY46...UAUL5n2Brbx"
}
}
The DID Authentication query format enables a verifier to request that a holder authenticate in specific ways. A DID Authentication query MUST be of the following form:
| Property | Description |
|---|---|
| type |
A
REQUIRED
string
value
that
MUST
be
set
to
DIDAuthentication
.
|
| acceptedMethods |
An
optional
array
of
objects
expressing
that
the
verifier
would
accept
any
DID
Method
listed.
Each
object
in
the
array
MUST
contain
a
property
called
method
with
a
value
that
is
a
DID
Method
name,
and
MAY
contain
other
properties
that
are
specific
to
the
DID
Method.
Valid
example
values
include:
|
| acceptedCryptosuites |
An
optional
array
of
objects
that
conveys
the
cryptography
suites
among
which
the
holder
MUST
choose
when
generating
a
cryptographic
proof
to
be
submitted
to
this
verifier
.
Each
object
in
the
array
MUST
contain
a
property
called
cryptosuite
with
a
value
that
is
a
Data
Integrity
cryptosuite
name
(or
Ed25519Signature2020
for
legacy),
and
MAY
contain
other
properties
that
are
specific
to
the
cryptosuite.
Valid
example
values
include:
|
The following example demonstrates that the verifier would like the holder to use the DID Web method and a data integrity ECDSA cryptography suite to authenticate over the established communication channel, such as the Credential Handler API (CHAPI):
{
"query": [{
"type": "DIDAuthentication",
"acceptedMethods": [{"method": "key"}],
"acceptedCryptosuites": [{"cryptosuite": "ecdsa-rdfc-2019"}]
}],
"challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
"domain": "example.com"
}
In the next example, the verifier would like the holder to use either the DID Key or DID Web method, with the standard EdDSA data integrity cryptography suite; optionally include a cryptographic proof that they are capable of performing a data integrity BBS proof; and authenticate over a different communication channel, in this case using a Verifiable Credential API HTTP endpoint.
{
"query": [{
"type": "DIDAuthentication",
"acceptedMethods": [{"method": "key"}, {"method": "web"}],
"acceptedCryptosuites": [{"cryptosuite": "ecdsa-rdfc-2019"}]
}, {
"type": "DIDAuthentication",
"required": false,
"acceptedMethods": [{"method": "key"}, {"method": "web"}],
"acceptedCryptosuites": [{"cryptosuite": "bbs-2023"}]
}],
"challenge": "zLEwtBYgQVNR4tyeo",
"domain": "didauth.example"
}
The DID Authentication response format enables a holder to provide the information requested by the verifier . A DID Authentication response MUST be a verifiable presentation of the following form:
| Property | Description |
|---|---|
| type |
A
REQUIRED
string
value
that
MUST
be
set
to
VerifiablePresentation
.
|
| holder | A REQUIRED string value that MUST be set to a specific DID that is of the type that was requested in the DID Authentication query. |
| proof |
A
REQUIRED
value
that
MUST
be
one
or
more
specific
digital
proof
types
that
were
requested
in
the
DID
Authentication
query.
Each
proof
object
MUST
include
the
domain
and
challenge
values
that
were
provided
in
the
DID
Authentication
query.
Holder
implementations
MUST
ensure
that
the
domain
specified
by
the
verifier
matches
the
domain
used
for
the
current
channel
of
communication.
|
It
is
vital
that
a
holder
implementation
check
the
domain
provided
by
the
verifier
against
the
domain
used
for
the
current
channel
of
communication.
If
a
holder
fails
to
do
so,
a
dishonest
verifier
could
then
replay
the
message
to
a
domain
that
is
not
their
own.
For
example,
a
dishonest
verifier
operating
from
the
evil.example
domain
could
retrieve
a
challenge
from
your
bank,
specify
a
domain
value
of
yourbank.example
,
and
then
replay
your
response
to
your
bank
to
get
access
to
your
financial
accounts.
This
attack
is
mitigated
as
long
as
implementations
ensure
that
the
appropriate
domain
is
used
when
generating
the
verifiable
presentation
.
The example below demonstrates a simple DID Authentication response.
{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": "VerifiablePresentation",
"holder": "did:example:12345",
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-rdfc-2022",
"verificationMethod": "did:example:12345#key-1",
"challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
"domain": "example.com",
"created": "2024-02-25T14:58:42Z",
"proofPurpose": "authentication",
"proofValue": "z3FXQjecWufY46...UAUL5n2Brbx"
}
}
In Verifiable Presentation Requests, the structuring and retrieval of information rely on the use of logical operations. "AND" and "OR" operations play crucial roles in defining the path to desired data.
At
the
top-most
level
of
the
request
structure,
different
types
of
queries
are
expected
to
be
processed
as
"AND"
operations
if
each
one's
group
property
is
set
to
the
same
value.
In
this
example,
there
are
two
queries
with
the
group
flag
set
to
certification
.
This
results
in
an
"AND"
operation,
indicating
that
both
of
these
conditions
need
to
be
met
in
order
to
fulfill
the
request.
{
"query": [{
"type": "QueryByExample",
"group": "certification",
// query details ...
},
// "AND"
{
"type": "DigitalCredentialQueryLanguage",
"group": "certification",
// query details ...
}]
}
Within
a
specific
query
type,
an
"OR"
operation
can
be
applied,
by
either
not
specifying
the
group
or
providing
group
values
that
are
different
from
one
another.
{
"query": [{
"type": "QueryByExample",
"group": "college-degree",
// query details ...
},
// "OR"
{
"type": "DigitalCredentialQueryLanguage",
"group": "job-experience",
// query details ...
}]
}
The following APIs are defined for presenting a Verifiable Credential:
The
URL
path
value
exchange-id
is
meaningful
to
the
server
but
is
opaque
to
the
client.
While
some
server
implementations
might
use
values
that
happen
to
be
human-readable,
clients
are
strongly
advised
to
not
assign
semantics
to
any
human-readable
values.
An
EnvelopedVerifiablePresentation
can
be
returned
in
the
response
in
order
to
create
presentations
with
a
media
type
other
than
application/vp
,
such
as
application/vp+jwt
.
A workflow defines a particular set of steps for exchanging verifiable credentials between two parties across a trust boundary. Each step can involve the issuance, verification, transmission, and/or presentation of verifiable credentials. Workflows are designed to support both linear sequences of steps and more complex patterns including branching logic and repeated steps, enabling sophisticated interactions between the parties involved. Examples of VCALM workflows include, but are not limited to, the following:
Workflow
instances
are
expected
to
be
created
by
administrators,
for
use
with,
for
example,
coordinator
websites.
A
workflow
instance
is
created
by
performing
an
HTTP
POST
to
the
workflow
service's
/workflows
endpoint.
The
HTTP
request
body
includes
the
configuration
for
the
workflow
instance.
This
includes,
but
is
not
limited
to,
information
about
the
steps
that
define
the
workflow
and
any
credential
templates
that
will
be
used
to
issue
verifiable
credentials.
The
steps
that
define
the
workflow
might
also
be
templates,
enabling
additional
flexibility.
If
a
workflow
involves
the
issuance
of
verifiable
credentials,
or
the
verification
of
presentations
or
credentials,
then
the
workflow
instance
configuration
can
include
authorization
capabilities
to
use
one
or
more
issuer
and/or
verification
services.
Once a workflow instance exists, authorization to create and query particular workflow interactions, called exchanges, can be given to coordinators.
An exchange represents a particular interaction based on a given workflow. The interaction will take place between an exchange client and the workflow service. Exchanges are expected to be transitory, only existing as long as the interaction takes to complete. The workflow service stores state information about each exchange, such as whether the exchange is pending, active, or complete, as well as the current step in the workflow, any workflow-specific variables and data, and any verifiable presentations and credentials received while the exchange executes. Implementers are free to use whatever variables they desire for their implementation in addition to the reserved variables defined in Section 3.6.3 Create Exchange . While there is no technical limitation on the number of steps in a workflow, implementers might want to enforce a default maximum number of steps to prevent bugs.
An
issuer,
verifier,
or
holder
coordinator
is
responsible
for
creating
exchanges.
The
coordinator
creates
an
exchange
by
performing
an
HTTP
POST
to
the
/exchanges
subpath
of
a
chosen
workflow,
on
the
workflow
service.
The
HTTP
request
body
includes
an
expiration
date
and
time
for
the
exchange
and
any
variables
to
be
used
to
populate
the
workflow's
templates
for
the
particular
exchange.
The
request
body
can
also
include
configuration
options
to
enable
the
exchange
to
be
executed
using
additional
protocols
beyond
this
API.
Once
the
exchange
is
created,
an
exchange
URL
that
identifies
the
exchange
and
enables
interaction
with
it
is
returned
to
the
coordinator.
The exchange URL is given to the exchange client so that it can initiate the exchange. Note that while the exchange URL is given to the coordinator to then provide it to the exchange client, the actual exchange is performed between the exchange client and the workflow service; the coordinator is not involved after providing the exchange URL to the exchange client. To be clear: a coordinator can still use its own exchange client for any use case that requires it to execute the exchange itself.
Initiating the exchange does not require any authorization beyond the exchange URL. Depending on the workflow service implementation, exchange URLs can also be capability URLs (i.e., the URL is an unguessable secret such that only whomever is given the URL can initiate the exchange). If the workflow that the exchange is based on requires any additional authorization beyond the possession of the exchange URL, this is to be obtained during the exchange, not at its initiation.
The exchange URL can also be used by the coordinator to query the current state of the exchange as it progresses and to obtain information associated with the exchange that the workflow service has stored. Querying the exchange in this way requires additional authorization that the coordinator is expected to have and that the exchange client is not.
How the exchange URL is transmitted from a coordinator to an exchange client is out of scope for this specification. Known mechanisms for sharing the exchange URL with the client include the Credential Handler API (aka CHAPI), a QR code, or a universal link.
Exchanges are designed to be executable using other protocols in addition to this API exchange protocol; for example, an exchange could potentially be executable with any of the [ OPENID4VCI ], [ OPENID4VP ], [ DIDCOMM ], and exchange protocols. The protocols supported depend on the complexity of the workflow the exchange is based on, and the options provided by the coordinator when the exchange was created.
The
exchange
client
is
expected
to
initiate
the
exchange
using
a
protocol
that
is
compatible
with
how
the
client
received
the
exchange
URL.
For
example,
the
exchange
URL
could
have
been
provided
over
CHAPI
with
a
protocol
identifier
indicating
that
this
API
protocol
ought
to
be
used.
Alternatively,
the
exchange
URL
could
be
included
as
the
credential_issuer
in
an
[
OPENID4VCI
]
credential
offer,
or
as
the
client_id
of
an
[
OPENID4VP
]
authorization
request,
indicating
that
[
OPENID4VCI
]
or
[
OPENID4VP
],
respectively,
ought
to
be
used.
This
section
focuses
on
how
an
exchange
client
uses
this
API
to
interact
with
the
exchange;
see
Section
3.7.4
Interaction
Protocols
Response
to
see
how
to
combine
exchanges
with
other
protocols
such
as
[
OPENID4VCI
],
[
OPENID4VP
],
and
[
DIDCOMM
].
Exchanges that are executed using this API protocol involve messages sent as request and response bodies over HTTP. Each message consists of a simple JSON object that includes zero or more of the following properties and values:
verifiablePresentation
:
A
Verifiable
Presentation
or
an
array
of
Verifiable
Presentations.
This
is
used
by
either
party
in
an
exchange
to
provide
information
to
the
other
party,
either
because
the
latter
requested
it
or
because
the
former
is
simply
offering
it.
verifiablePresentationRequest
:
A
Verifiable
Presentation
Request.
This
is
used
by
either
party
in
an
exchange
to
request
information
from
the
other
party.
redirectUrl
:
A
URL
that
can
be
used
to
continue
an
interaction
at
another
location.
One
use
case
for
this
is
to
send
the
user
of
an
exchange
client
back
to
a
coordinator
website
after
an
exchange
has
completed.
referenceId
:
An
optional
identifier
to
correlate
exchange
messages.
A
server
MAY
include
this
value;
if
present,
the
client
SHOULD
include
it
in
its
next
message.
The
value
SHOULD
be
a
urn:uuid
value.
Custom properties and values might also be included, but are expected to trigger errors in implementations that do not recognize them.
To
initiate
an
exchange
using
this
API
protocol,
an
exchange
client
performs
an
HTTP
POST
sending
a
JSON
object
as
the
request
body.
In
the
simplest
case,
when
the
client
has
no
constraints
of
its
own
on
the
exchange
—
i.e.,
it
has
nothing
to
request
from
the
other
party
—
the
JSON
object
is
empty
(
{}
).
The
workflow
service
responds
with
its
own
JSON
object
in
the
response
body.
If
that
response
object
is
empty,
the
exchange
is
complete
and
nothing
is
requested
from
nor
offered
to
the
exchange
client.
If
the
object
includes
verifiablePresentationRequest
,
then
the
exchange
is
not
yet
complete
and
some
additional
information
is
requested,
as
specified
by
the
contents
of
the
associated
verifiable
presentation
request.
If
the
object
includes
verifiablePresentation
,
then
some
information
is
offered,
such
as
verifiable
credentials
issued
to
the
holder
operating
the
exchange
client
or
verifiable
credentials
with
information
about
the
exchange
server's
operator
based
on
the
exchange
client's
request.
If
the
object
includes
redirectUrl
,
the
exchange
is
complete
and
the
workflow
service
recommends
that
the
client
proceed
to
another
place
to
continue
the
interaction
in
another
form.
Many
verifiable
credential
use
cases
can
be
implemented
using
these
basic
primitives.
Either
party
to
an
exchange
is
capable
of
requesting
verifiable
presentations
and
of
providing
one
or
more
verifiable
credentials
that
might
be
necessary
to
establish
trust
and/or
gain
authorization
capabilities,
and
either
party
is
capable
of
presenting
credentials
that
they
hold
or
that
they
have
issued.
Specific
workflows
can
be
configured
to
expect
specific
presentations
and
credentials
and
to
reject
deviations
from
the
expected
flow
of
information.
When
a
workflow
service
determines
that
a
particular
message
is
not
acceptable,
it
raises
an
error
by
responding
with
a
4xx
HTTP
status
message
and
a
JSON
object
that
expresses
information
about
the
error.
The exchange design approach is layered: it aims to provide a minimal communication message layer and a set of primitives that enable most use cases to be implemented via specific verifiable presentation requests and verifiable credentials at a layer above. See the appendices that follow for examples of workflows and exchanges that use specific verifiable presentation requests and verifiable credentials.
Minimum viable examples of both step and credential templates, as well as a couple more complex workflow templates, can be found in the appendix Workflow Step and Template Examples .
A given interaction with an exchange is expected to be short-lived but other mechanisms can be used to enable longer or multi-stage interactions. Examples of other interaction mechanisms include SMS, email, web notifications, or phone calls. This approach simplifies digital wallet implementation and allows existing mechanisms to be reused without reinvention within this API. The Web or native platforms are expected to enable additional interactions via applications (such as Web browsers) or other platform features. For example, in asynchronous issuance, a holder requests a credential but waits for processing. In such cases, system components (such as an issuer coordinator) make use of mechanisms outside this API to notify the holder when their credential is ready for collection.
The following APIs are defined for using workflows and exchanges for credential use cases that require crossing trust boundaries:
In
the
workflows
and
exchanges
APIs,
a
"local"
ID
refers
to
an
ID
that
is
local
to
a
service
instance.
In
other
words,
an
exchangeId
or
workflowId
refers
to
a
fully
qualified
URL,
while
a
localExchangeId
or
localWorkflowId
refers
to
a
specific
element
in
the
URL
path.
Workflows
can
contain
information
about
steps,
credential
templates,
and
authorization.
In
some
cases,
a
workflow
will
also
reference
the
reserved
results
variable
at
different
points
in
its
configuration
(typically
in
credential
templates).
This
variable
holds
data
that
the
workflow
service
receives
from
clients
throughout
the
course
of
an
exchange.
Here
is
a
basic
workflow
configuration
that
contains
a
DID
Authentication
step
and
a
credential
delivery
step:
A
step
that
includes
an
issueRequests
array
containing
one
or
more
issue
request
objects.
Each
issue
request
object
identifies
a
credential
template
to
use,
either
by
its
identifier
(
credentialTemplateId
)
or
by
its
index
(
credentialTemplateIndex
)
in
the
workflow's
credentialTemplates
array.
An
issue
request
object
MAY
also
include
a
variables
property
to
provide
values
to
be
used
when
evaluating
the
credential
template.
By
default,
the
result
of
each
issue
request
is
included
in
the
verifiable
presentation
that
is
sent
to
the
exchange
client
in
the
same
step.
An
issue
request
object
MAY
include
an
optional
result
property
whose
value
MUST
be
either
the
name
of
a
top-level
variable
in
the
exchange's
variables
object
or
a
JSON
pointer
to
any
variable
within
the
exchange's
variables
object,
identifying
where
the
result
of
the
issue
request
is
to
be
stored.
This
enables
greater
composition,
as
subsequent
steps
can
reference
the
stored
result,
or
the
exchange
can
end
and
a
party
with
access
to
the
exchange
state
can
obtain
the
result
for
use
in
another
exchange
or
via
some
other
mechanism.
{
"id": "9fd3bc6d-4a04-4b3d-a983-3482d0586626",
"initialStep": "didAuthRequest",
"steps": {
"didAuthRequest": {
"createChallenge": true,
"verifiablePresentationRequest": {
"query": {
"type": "DIDAuthentication",
"acceptedMethods": [
{
"method": "key"
},
{
"method": "web"
}
],
"acceptedCryptosuites": [
{
"cryptosuite": "eddsa-rdfc-2022"
},
{
"cryptosuite": "ed25519-2020"
}
]
},
"domain": "https://issuer.example.com"
},
"nextStep": "credentialDelivery"
},
"credentialDelivery": {
"issueRequests": [
{
"credentialTemplateId": "caffb919-053a-4bfa-beba-80567904f842",
"variables": "sampleAchievementCredential"
}
]
}
},
"credentialTemplates": [
{
"id": "caffb919-053a-4bfa-beba-80567904f842",
"type": "jsonata",
"template": "{
\"credential\": {
\"@context\": [
\"https://www.w3.org/ns/credentials/v2\",
\"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json\",
\"https://purl.imsglobal.org/spec/ob/v3p0/extensions.json\"
],
\"id\": sampleAchievementCredential.id,
\"type\": [\"VerifiableCredential\", \"AchievementCredential\"],
\"issuer\": {
\"type\": [\"Profile\"],
\"name\": \"Example Issuer\",
\"image\": {
\"type\": \"Image\",
\"id\": \"https://issuer.example.com/logo.png\"
}
},
\"awardedDate\": sampleAchievementCredential.awardedDate,
\"validFrom\": sampleAchievementCredential.validFrom,
\"name\": \"Sample Achievement\",
\"credentialSubject\": {
\"id\": results.didAuthRequest.verifiablePresentation.holder,
\"type\": \"AchievementSubject\",
\"name\": sampleAchievementCredential.credentialSubject.name,
\"achievement\": {
\"id\": sampleAchievementCredential.credentialSubject.achievement.id,
\"type\": [\"Achievement\"],
\"achievementType\": sampleAchievementCredential.credentialSubject.achievement.achievementType,
\"name\": sampleAchievementCredential.credentialSubject.achievement.name,
\"description\": sampleAchievementCredential.credentialSubject.achievement.description,
\"alignment\": sampleAchievementCredential.credentialSubject.achievement.alignment
}
}
}
}"
}
],
"controller": "did:web:issuer.example.com"
}
A
step
MAY
include
a
verifiablePresentation
to
explicitly
express
one
or
more
verifiable
presentation
s
to
be
used
in
that
step.
This
presentation
could
be
composed
via
other
variables
in
an
exchange
and
could
be
augmented
with
any
additional
verifiable
credentials
that
might
be
issued
during
the
step
(per
issueRequests
).
This
supports
use
cases
where
specific
verifiable
presentation
versions
are
required,
specific
sub-types
of
verifiable
presentations
are
required,
or
specific
verifiable
presentation
contents
are
required,
including
previously
out-of-band
issued
verifiable
credentials
that
are
to
be
delivered
in
the
workflow
step.
A
step
MAY
include
a
redirectUrl
to
specify
a
URL
to
send
to
the
client
that
can
be
used
to
continue
an
interaction
at
another
location.
One
use
case
for
this
is
to
send
the
user
of
an
exchange
client
back
to
a
coordinator
website
after
an
exchange
has
completed.
Another
use
case
is
to
return
an
interaction
URL
that
allows
a
server
to
implement
custom
business
rules
during
a
continuing
interaction
without
requiring
the
client
to
navigate
to
a
web
browser.
For
example,
a
first
exchange
could
request
information
from
a
user
and
then
return
an
interaction
URL
via
redirectUrl
.
The
client
(e.g.,
a
digital
wallet)
can
determine
that
it
is
an
interaction
URL
(e.g.,
the
URL
uses
?iuv=1
)
and
fetch
it,
causing
the
interaction
server
to
run
custom
business
logic
and
then
return
a
protocol
object
with
another
exchange
to
continue
the
interaction.
Some
workflows
will
need
to
reference
custom
variables
in
one
or
more
of
their
steps.
In
this
case,
the
coordinator
will
need
to
provide
the
appropriate
value(s)
for
the
variable(s)
when
it
creates
an
exchange.
Here
is
an
example
of
a
workflow
configuration
with
a
templated
DID
Authentication
step
(Notice
the
verifiablePresentationRequest
and
callbackUrl
variables
referenced
in
the
didAuthRequest
step):
{
"id": "9fd3bc6d-4a04-4b3d-a983-3482d0586626",
"initialStep": "didAuthRequest",
"steps": {
"didAuthRequest": {
"stepTemplate": {
"type": "jsonata",
"template": "{
"createChallenge": true,
"verifiablePresentationRequest": verifiablePresentationRequest,
"callback": {
"url": callbackUrl
},
"nextStep": "credentialDelivery"
}"
}
},
"credentialDelivery": {
"issueRequests": [
{
"credentialTemplateId": "caffb919-053a-4bfa-beba-80567904f842",
"variables": "sampleAchievementCredential"
}
]
}
},
"credentialTemplates": [
{
"id": "caffb919-053a-4bfa-beba-80567904f842",
"type": "jsonata",
"template": "{
\"credential\": {
\"@context\": [
\"https://www.w3.org/ns/credentials/v2\",
\"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json\",
\"https://purl.imsglobal.org/spec/ob/v3p0/extensions.json\"
],
\"id\": sampleAchievementCredential.id,
\"type\": [\"VerifiableCredential\", \"AchievementCredential\"],
\"issuer\": {
\"type\": [\"Profile\"],
\"name\": \"Example Issuer\",
\"image\": {
\"type\": \"Image\",
\"id\": \"https://issuer.example.com/logo.png\"
}
},
\"awardedDate\": sampleAchievementCredential.awardedDate,
\"validFrom\": sampleAchievementCredential.validFrom,
\"name\": \"Sample Achievement\",
\"credentialSubject\": {
\"id\": results.didAuthRequest.verifiablePresentation.holder,
\"type\": \"AchievementSubject\",
\"name\": sampleAchievementCredential.credentialSubject.name,
\"achievement\": {
\"id\": sampleAchievementCredential.credentialSubject.achievement.id,
\"type\": [\"Achievement\"],
\"achievementType\": sampleAchievementCredential.credentialSubject.achievement.achievementType,
\"name\": sampleAchievementCredential.credentialSubject.achievement.name,
\"description\": sampleAchievementCredential.credentialSubject.achievement.description,
\"alignment\": sampleAchievementCredential.credentialSubject.achievement.alignment
}
}
}
}"
}
],
"controller": "did:web:issuer.example.com"
}
For
the
openId
options,
specifically
the
values
createAuthorizationRequest
and
authorizationRequest
,
the
example
below
is
provided
to
help
developers
understand
what
an
[
OPENID4VP
]
Authorization
Request
looks
like:
{
"response_type": "vp_token",
"presentation_definition": {
"id": "f1bd224a-0fed-469a-b64a-dad7cf63fd98",
"input_descriptors": [
{
"id": "77d50c71-95ef-442c-a372-f32e17634fab",
"constraints": {
"fields": [
{
"path": [
"$['@context']"
],
"filter": {
"type": "array",
"contains": {
"type": "string",
"const": "https://www.w3.org/ns/credentials/v2"
}
}
},
{
"path": [
"$['type']"
],
"filter": {
"type": "array",
"contains": {
"type": "string",
"const": "VerifiableCredential"
}
}
},
{
"path": [
"$['credentialSubject']['name']"
],
"filter": {
"type": "string"
}
}
]
},
"purpose": "We require a name credential to display your name when you post messages."
}
]
},
"response_mode": "direct_post",
"client_metadata": {
"vp_formats_supported": {
"ldp_vc": {
"proof_type_values": [
"DataIntegrityProof",
"Ed25519Signature2020"
],
"cryptosuite_values": [
"ecdsa-rdfc-2019",
"eddsa-rdfc-2022"
]
}
},
"vp_formats": {
"jwt_vp": {
"alg": [
"EdDSA",
"Ed25519",
"ES256",
"ES384"
]
},
"jwt_vp_json": {
"alg": [
"EdDSA",
"Ed25519",
"ES256",
"ES384"
]
},
"di_vp": {
"proof_type": [
"ecdsa-rdfc-2019",
"eddsa-rdfc-2022",
"Ed25519Signature2020"
]
},
"ldp_vp": {
"proof_type": [
"ecdsa-rdfc-2019",
"eddsa-rdfc-2022",
"Ed25519Signature2020"
]
}
}
},
"client_id": "https://some.example/workflows/z1A7ojitBF3pGpVzW17MgU7zm/exchanges/z1ACKwiBiXmuGjpKAdKMpBZXB/openid/client/authorization/response",
"client_id_scheme": "redirect_uri",
"response_uri": "https://some.example/workflows/z1A7ojitBF3pGpVzW17MgU7zm/exchanges/z1ACKwiBiXmuGjpKAdKMpBZXB/openid/client/authorization/response",
"nonce": "z1ACKwiBiXmuGjpKAdKMpBZXB"
}
There
is
an
expires
property
associated
with
exchanges,
denoting
the
expiration
date
and
time
of
the
exchange.
It
is
created
using
the
/workflows/{localWorkflowId}/exchanges
endpoint.
This
impacts
the
lifetime
of
challenges
associated
with
such
an
exchange:
if
a
challenge
is
bound
to
an
exchange,
that
challenge
ceases
to
be
valid
at
the
date
referenced
by
the
expires
property
of
the
exchange.
This endpoint provides a mechanism for a client to query an exchange for all of the protocols that it supports. A single exchange can support many protocols that are capable of achieving the goals of the exchange, such as the issuance of a verifiable credential into a digital wallet.
This
endpoint
also
enables
the
website
operator
to
delegate
the
authority
to
execute
the
exchange
to
a
third
party,
such
as
a
service
provider,
by
delegating
that
trust
through
the
HTTPS
domain.
For
example,
the
website
brand.example
can
delegate
the
operation
of
the
exchange
to
a
partner
saas.example
by
using
the
saas.example
domain
in
the
list
of
protocols.
This
enables
the
client
to
depend
on
their
trust
in
brand.example
to
delegate
the
operation
of
the
exchange
to
a
third
party
in
the
same
way
that
a
website
links
to
resources
from
other
domains
to
render
a
web
page.
This
endpoint
MUST
return
the
current
verifiable
presentation
request
to
be
returned
by
an
exchange
when
accessed
with
an
Accept
header
value
of
application/json
.
Processing
this
request
SHOULD
NOT
advance
the
exchange
to
a
new
step
nor
perform
any
state-changing
side
effects,
such
as
credential
issuance.
If
there
is
no
verifiable
presentation
request
available
for
the
exchange
in
the
current
step,
the
value
of
the
verifiablePresentationRequest
property
returned
by
this
endpoint
MUST
be
an
empty
JSON
object.
This
might
be
a
useful
endpoint
for
integration
with
Digital
Credentials
.
To
make
a
[
digital-credentials
]
request
backed
by
the
VCALM
protocol,
the
coordinator
MUST
provide
the
interaction
URL
as
the
request
data.
Subsequently,
the
browser
MUST
fetch
the
interaction
URL
,
retrieve
the
supported
protocols,
and
perform
an
HTTP
GET
on
the
vcapi
URL
concatenated
with
/request
.
This feature allows the browser to route their requests through the coordinator's origin (thereby anchoring the entire operation in said origin), to the delegate they have approved as a service provider. This convenience exists whether the request is made on the same device or forwarded for a cross-device request.
Finally, this endpoint operates without the need for signed requests, as it MAY rely on TLS and existing CA infrastructure, without a need for new certificates nor a need to incorporate those into the exchange protocol in an additive way. However, if we find that the [ digital-credentials ] or other supported protocols require signed requests or encrypted responses, then the request MAY be returned as a signed object referencing a public key that SHOULD be used to encrypt the response. Upon receipt of the (potentially encrypted) response, the coordinator could decrypt and deliver the response to the appropriate exchange or delegate decryption support to the exchange service altogether. The official decision on which interface VCALM prescribes for performing this functionality is in flux as the [ digital-credentials ] rules continue to evolve.
A
server
MAY
include
a
referenceId
property
in
an
exchange
message.
If
the
client
receives
a
referenceId
,
it
SHOULD
include
the
same
referenceId
in
its
next
message
to
the
server.
This
aids
in
debugging
and
ensures
that
potentially
delayed
or
misordered
messages
are
linked
to
the
correct
request.
The
value
of
referenceId
SHOULD
be
a
urn:uuid
value.
The APIs in this specification enables unmediated (automated, machine-to-machine) or mediated (person in the loop) exchanges to be executed. These exchanges are initiated by a holder coordinator and responded to by any Coordinator that implements exchanges. The flows consist of the following steps:
The holder coordinator MAY call the Coordinator's exchange discovery endpoint to determine if the holder coordinator supports the Coordinator's protocol requirements on a particular endpoint, before actually initiating the exchange.
A diagram of the steps outlined above is presented below:
The general exchange above can be performed in a way that is fully automated, mediated by a person, or in a hybrid fashion where portions are automated but interaction by a person is required at certain stages. The second step above is used to provide guidance on whether the next step is automated or requires an individual to intervene.
The following diagram illustrates an exchange where the holder coordinator initiates with a Verifiable Presentation Request, requiring credentials from the receiving Coordinator before proceeding:
The following diagram illustrates an exchange where the holder coordinator sends a counter-request after receiving the server's initial request:
The
following
example
demonstrates
an
exchange
client
initiating
an
exchange
with
a
verifiablePresentationRequest
that
specifies
which
cryptographic
proof
formats
and
envelope
types
it
will
accept.
If
the
credentialQuery
property
is
not
present,
the
exchange
client
will
accept
any
credential(s)
from
the
workflow
service
that
match
the
specified
formats.
{
"verifiablePresentationRequest": {
"query": [{
"type": "QueryByExample",
"credentialQuery": {
"acceptedCryptosuites": [
{"cryptosuite": "eddsa-rdfc-2022"},
{"cryptosuite": "ecdsa-rdfc-2019"},
{"cryptosuite": "bbs-2023"}
],
"acceptedEnvelopes": [
{"mediaType": "application/jwt"}
]
}
}]
}
}
The following example demonstrates an exchange client requesting credentials from the workflow service before fulfilling any subsequent request. In this scenario, the exchange client requires proof that the server operator is a registered business before sharing personal information.
{
"verifiablePresentationRequest": {
"query": [{
"type": "QueryByExample",
"credentialQuery": {
"reason": "Please present your BusinessRegistrationCredential to complete the verification process.",
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2"
],
"type": ["BusinessRegistrationCredential"]
},
"acceptedCryptosuites": [
{"cryptosuite": "eddsa-rdfc-2022"}
]
}
}]
}
}
It is useful for an implementation to communicate how to start interacting with it to another implementation. This bootstrapping process is called initiating an interaction , and communicates what protocols each implementation supports as well as how to start a particular interaction with the implementation.
While several interaction specifications reside in this document, the general approach is agnostic as to use case, application, and protocol. This approach can be used to pair two or more applications that desire to bootstrap into a particular protocol over any transmission medium — such as a web browser, QR Code (optical medium), or NFC (wireless medium) — where the protocol does not need to involve this API.
The
sequence
diagram
below
outlines
an
issuer
generating
an
interaction
URL
,
using
a
QR
Code
to
share
it
with
a
holder
,
and
proceeding
with
the
vcapi
protocol:
The
sequence
diagram
below
outlines
a
verifier
generating
an
interaction
URL
,
using
a
QR
Code
to
share
it
with
a
holder
,
and
proceeding
with
the
vcapi
protocol:
The
sequence
diagram
below
outlines
a
holder
generating
an
interaction
URL
,
using
a
QR
Code
to
share
it
with
a
verifier
,
and
proceeding
with
the
inviteRequest
protocol:
The
format
of
the
interaction
URL
MUST
conform
to
the
syntax
for
the
URL
Standard
and
contain
an
iuv
query
parameter
encoding
the
interaction
URL
version
number,
which
MUST
be
1
when
using
this
version
of
this
API.
The
interaction
URL
SHOULD
be
an
HTTPS
URL
that
contains
an
interaction-specific
identifier.
The
URL
SHOULD
be
opaque
and
require
no
URL
syntax
processing
before
it
is
fetched
by
the
receiving
system.
An
example
of
such
a
URL
is
shown
below:
https://app.example/interactions/z8n38Dp7a?iuv=1
Protocols that encode lengthy protocol-specific information into URLs suffer from limitations placed by software libraries on the maximum allowable length of a URL. At the time of writing, the suggested URL length limit is roughly 2,000 characters. Implementers SHOULD NOT put information that can be expressed in the response to a GET request for an interaction URL , defined in Section 3.7.4 Interaction Protocols Response , into the query parameters of the interaction URL .
A
coordinator
has
the
freedom
to
put
the
interaction
URL
at
any
location
on
its
Web
origin,
because
it
is
expected
to
be
considered
opaque
by
consuming
software
(except
for
the
iuv
query
parameter).
However,
it
is
important
that
the
interaction
URL
be
hosted
on
a
coordinator
and
NOT
hosted
at
the
workflow
service.
This
enables
the
coordinator's
Web
origin
(DNS
domain
name)
to
be
used
as
a
consistent
trust
signal
by
consumers
and
the
application
of
business
rules
that
might
modulate
actions.
An interaction QR Code MUST be an interaction URL expressed as a QR code according to ISO18004:2024: QR Code Bar Code Symbology Specification . To ensure broad interoperability, the length of the interaction URL SHOULD be as short as possible, SHOULD NOT exceed 400 alphanumeric characters, and MUST NOT exceed 4,296 alphanumeric characters. An example of an interaction QR code can be found below:
https://app.example/interactions/z8n38Dp7a?iuv=1
It
can
be
useful
to
invoke
an
application
that
is
capable
of
processing
an
interaction
URL
.
This
section
defines
an
interaction:
protocol
scheme
format
(for
native
apps)
and
a
web+interaction:
protocol
scheme
format
(for
web
apps)
for
this
purpose.
The
format
of
the
protocol
scheme
MUST
conform
to
the
following
syntax:
| The Interaction Protocol Scheme |
|---|
scheme = ("interaction:" / "web+interaction:") interaction-url
interaction-url
=
URL
|
The
interaction-url
is
any
URL
that
conforms
to
the
URL
Standard
and
where
retrieving
the
resource
at
the
URL
results
in
an
interaction
protocols
response
.
interaction:https://app.example/interactions/z8n38Dp7a?iuv=1
web+interaction:https://app.example/interactions/z8n38Dp7a?iuv=1
Performing a retrieval of the interaction URL results in instructions on how to start an interaction with the remote system.
When
the
interaction
URL
is
fetched
using
an
Accept
header
value
of
application/json
,
a
single
JSON
object
containing
a
protocols
map
MUST
be
returned
where
each
key
is
a
protocol
identifier
and
each
value
is
a
URL
that
can
be
used
to
initiate
the
interaction.
For
example,
performing
an
HTTP
GET
on
the
https://app.example/interactions/z8n38Dp7a?iuv=1
interaction
URL
might
result
in
either
of
the
following
responses:
{
"protocols": {
"inviteRequest": "https://saas.example/workflows/123/exchanges/987/invite-request/response",
"vcapi": "https://saas.example/workflows/123/exchanges/987",
"oid4vp-1.0": "openid4vp://?client_id=https%3A%2F%2Fapp.example%2Fworkflows%2F123%2Fexchanges%2F987%2Fopenid%2Fclient%2Fauthorization%2Fresponse&request_uri=https%3A%2F%2Fapp.example%2Fworkflows%2F123%2Fexchanges%2F987%2Fopenid%2Fclient%2Fauthorization%2Frequest'"
}
}
{
"protocols": {
"inviteRequest": "https://saas.example/interactions/123/invite-request/response"
}
}
The
protocol
response
enables
protocol
execution
to
be
delegated
to
third-party
service
providers
through
the
HTTPS
domain
trust
model,
similar
to
the
delegation
mechanism
described
in
the
Get
Exchange
Protocols
section.
For
example,
the
website
app.example
can
delegate
the
operation
of
the
exchange
to
a
partner
saas.example
by
including
the
saas.example
domain
in
the
list
of
protocols.
When
the
interaction
URL
is
fetched
using
any
unrecognized
Accept
header
value,
a
text/html
document
MUST
be
returned
with
directions
instructing
a
human
being
to
use
specific
software
that
understands
how
to
process
interaction
URLs
.
Below is a table of interaction protocols that are supported today. There is broad interest in extracting this table into a separate document as a dependency of this specification. The reasoning behind this interest is that the idea of a generic, extensible, reference of credential management protocols has a natural appeal across various communities and use cases. In the event that this migration occurs, implementers are expected to use that reference instead of this table for protocol usage. In the event that there is a conflict between the table below and information in the new reference, implementers ought to note versioning differences of this specification and proceed with caution.
| Property | Usage |
|---|---|
interact
|
The
interact
interaction
protocol
is
used
to
redirect
a
wallet
to
a
different
interaction
URL,
where
the
exchange
will
continue.
This
protocol
can
be
used
by
exchanges
as
a
delegation
mechanism.
The
value
of
this
entry
should
be
an
interaction
URL.
More
details
can
be
found
in
Section
3.7.1
Interaction
URL
Format
.
|
inviteRequest
|
The
inviteRequest
interaction
protocol
is
used
by
a
local
system
to
signal
to
the
remote
system
that
it
would
like
an
invitation
to
a
remote
system.
The
value
of
this
entry
should
be
the
URL
of
a
website
where
an
individual
can
engage
in
a
use-case-specific
interaction.
More
details
can
be
found
in
Section
3.7.5
inviteRequest
Interaction
Protocol
.
|
vcapi
|
The
vcapi
interaction
protocol
is
used
to
initiate
a
specific
exchange
as
described
in
Section
3.6.6
Participate
in
an
Exchange
.
The
value
of
this
entry
should
be
the
fully-qualified
URL
used
as
the
ID
for
the
exchange.
More
details
can
be
found
in
Section
3.7.6
vcapi
Interaction
Protocol
.
|
didcomm
|
The
didcomm
interaction
protocol
is
used
to
initiate
a
credential
issuance
or
presentation
flow
in
accordance
with
the
latest
version
of
[
DIDCOMM
].
The
value
of
this
entry
should
be
the
Out-of-Band
(OOB)
Invitation
URL
for
the
exchange.
More
details
can
be
found
in
DIDComm
Messaging
.
|
oid4vci-1.0
|
The
Implementers are advised to understand the drift that has occurred with this specification and the impact that this has made on the semantics of this property. Specifically, due to the material differences between popular draft versions and the stable 1.0 version, it is difficult for a wallet to know how to process an inbound request without coordination in advance. As a result of this, implementers are advised to use the versioned variant of this property as described in the protocol versioning note below. |
oid4vp-1.0
|
The
Implementers are advised to understand the drift that has occurred with this specification and the impact that this has made on the semantics of this property. Specifically, due to the material differences between popular draft versions and the stable 1.0 version, it is difficult for a wallet to know how to process an inbound request without coordination in advance. As a result of this, implementers are advised to use the versioned variant of this property as described in the protocol versioning note below. |
OID4VCI
|
A
deprecated
and
unversioned
variant
of
the
|
OID4VP
|
A
deprecated
and
unversioned
variant
of
the
|
For
protocols
where
version
ambiguity
could
cause
interoperability
issues,
implementers
might
consider
adding
information
to
the
protocol
properties.
One
way
to
do
this
would
be
to
use
the
pattern
"
PROTOCOL
-
MAJOR
.
MINOR
".
For
example,
instead
of
oid4vp
,
they
ought
to
use
oid4vp-draft28
or
oid4vp-1.0
.
Some
coordinator
implementations
will
implement
the
protocols
endpoint
as
a
pass
through
to
a
protocols
endpoint
for
an
exchange
instance.
For
example,
a
GET
on
https://app.example/interactions/z8n38Dp7a?iuv=1
will
result
in
a
pass-through
GET
on
https://app.example/workflows/123/exchanges/987/protocols
,
which
would
return
the
response
above.
Implementing
interaction
URLs
in
this
way
can
provide
an
easier
implementation
path.
The
inviteRequest
interaction
protocol
is
used
by
a
local
system
to
signal
to
the
remote
system
that
it
would
like
an
invitation
to
a
remote
system
via
a
specific
URL,
such
as
a
website
where
an
individual
can
engage
in
a
use-case
specific
interaction.
If
the
inviteRequest
interaction
protocol
is
selected,
the
local
system
sends
data
using
an
HTTP
POST
to
instruct
the
remote
system
where
to
send
the
individual.
A
couple
examples
of
the
POST
data
are
shown
below.
These
examples
intend
to
highlight
that
this
specification
does
not
state
any
requirements
as
to
how
the
"url"
field
is
formatted,
but
does
recommend
that
an
implementer
of
this
interaction
mechanism
make
use
of
a
unique
ID:
{
"url": "https://website.example/checkout/8372974",
"purpose": "Checkout at ShopCo",
"referenceId": "417bcaf2-14d9-11f0-99d7-9f094678517b"
}
{
"url": "https://website.example/forms/7864165",
"purpose": "Fill out online form",
"referenceId": "d4a6e5b8-1715-4654-8e47-e68b311756d1"
}
The
vcapi
interaction
protocol
is
used
to
initiate
a
specific
exchange
as
described
in
Section
3.6.6
Participate
in
an
Exchange
.
{
"verifiablePresentationRequest": {
"query": [{
"type": "QueryByExample",
"credentialQuery": {
"reason": "Please provide your student ID.",
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2",
],
"type": "StudentIdCredential",
"credentialSubject": {
"studentId": ""
},
},
"acceptedIssuers": [{
"id": "did:web:university.example"
}]
}
}],
"challenge": "5e34826e-14da-11f0-98a5-8b1c0a196728",
"domain": "university.example"
}
}
When an implementation detects an anomaly while processing a document, a ProblemDetails object can be used to report the issue to other software systems. The interfaces for these objects follow [ RFC9457 ] to encode the data. A ProblemDetails map consists of the following properties:
type
key
MUST
be
present
and
its
value
MUST
be
a
URL
identifying
the
type
of
problem.
title
key
SHOULD
provide
a
short
but
specific
human-readable
string
for
the
problem.
detail
key
SHOULD
provide
a
longer
human-readable
string
for
the
problem.
Leveraging
keys
such
as
detail
,
and
instance
is
encouraged,
to
provide
more
contextual
feedback
about
the
error,
while
being
conscious
of
security
concerns
and
hence
not
disclosing
sensitive
information.
The following problem description types are defined by this specification:
Further lists of ProblemDetails that might be reported by implementations can be found in the following specifications:
{
"type": "https://www.w3.org/TR/vc-data-model#CRYPTOGRAPHIC_SECURITY_ERROR",
"status": 400,
"title": "CRYPTOGRAPHIC_SECURITY_ERROR",
"detail": "The cryptographic security mechanism couldn't be verified. This is likely due to a malformed proof or an invalid verificationMethod."
}
The
example
type
URLs
above
will
work
in
the
future
after
VCDM
v2.0
becomes
a
global
standard.
To
ensure
the
error
links
to
the
appropriate
location,
you
can
replace
the
base
URL
of
https://www.w3.org/TR/vc-data-model
with
www.w3.org/TR/vc-data-model-2.0
for
the
time
being.
Implementers are strongly advised to sanitize all server errors in production environments, as not doing so can lead to information disclosure.
It is recommended to avoid raising errors while performing verification, and instead gather ProblemDetails objects to include in the verification results.
This
specification
defines
a
distinction
between
a
verification
error
and
a
verification
warning.
Errors
are
ProblemDetails
relating
to
cryptography,
data
model,
and
malformed
context
and
are
unrecoverable.
Warnings
are
ProblemDetails
relating
to
status
and
validity
periods
and
might
be
recoverable
or
leave
the
subsequent
action
to
the
discretion
of
the
application.
If
an
error
is
included,
the
verified
property
of
the
VerificationResponse
object
MUST
be
set
to
false
;
if
no
errors
are
included,
it
MUST
be
set
to
true
.
{
"verified": false,
"document": verifiableCredential,
"mediaType": "application/vc",
"controller": issuer,
"controllerDocument": didDocument,
"warnings": [ProblemDetails],
"errors": [ProblemDetails]
}
The
architecture
described
in
this
specification
is
designed
for
market
acceptance
through
a
combination
of
efficiency
and
respect
for
privacy
and
human
rights.
APIs
and
protocols
for
processing
verifiable
credentials
do
not
favor
delegation
by
the
issuer
role
over
delegation
by
the
subject
role.
A.2
"Phoning
Home"
Considered
Harmful
It
is
considered
a
bad
privacy
practice
for
a
verifier
to
contact
an
issuer
about
a
specific
verifiable
credential
.
This
practice
is
known
as
"phoning
home"
and
can
result
in
a
mismatch
in
privacy
expectations
between
holders
,
issuers
,
verifiers
,
and
other
parties
expressed
in
a
verifiable
credential
.
Phoning
home
enables
issuers
to
correlate
unsuspecting
parties
with
the
use
of
certain
verifiable
credentials
which
can
violate
privacy
expectations
that
each
entity
might
have
regarding
the
use
of
those
credentials.
For
example,
what
is
expected
by
the
holder
to
be
a
private
interaction
between
them
and
the
verifier
becomes
one
where
the
issuer
is
notified
of
the
interaction.
There
are
some
interactions
where
contacting
the
issuer
in
a
privacy-preserving
manner
upholds
the
privacy
expectations
of
the
holder
.
For
example,
contacting
the
issuer
to
get
revocation
status
information
in
a
privacy-respecting
manner,
such
as
through
a
status
list
that
provides
group
privacy
can
be
acceptable
as
long
as
the
issuer
is
not
able
to
single
out
which
verifiable
credential
is
being
queried
based
on
the
retrieval
of
the
status
list.
For
more
information
on
one
such
mechanism
see
the
Bitstring
Status
List
v1.0
specification.
Verifiers
are
urged
to
not
"phone
home"
in
ways
that
will
create
privacy
violations.
When
retrieving
content
that
section
is
linked
from
a
verifiable
credential
,
using
mechanisms
such
as
Oblivious
HTTP
and
aggressively
caching
results
can
improve
the
privacy
characteristics
of
the
ecosystem.
B.
Security
Considerations
B.1
Unknown
Proof
Types
non-normative.
Holder
coordinator
implementations,
such
as
digital
wallet
software,
can
receive
and
store
verifiable
credentials
that
include
proofs
that
are
not
understood
by
the
software,
however,
these
proofs
are
not
to
be
presented
by
the
implementation.
A
verifiable
credential
with
several
proofs
,
some
of
which
the
implementation
understands
and
others
that
it
does
not,
can
be
presented
by
the
implementation
provided
that
the
proof
of
choice
is
understood
by
the
implementation
and
the
others
are
removed
prior
to
presentation.
Implementations
maintain
allow
lists
of
understood
proofs
and
ensure
that
any
proofs
not
present
are
stripped
prior
to
presentation.
Implementations
can
use
the
presence
of
unknown
proofs
as
potential
adoption
signals
in
a
decentralized
ecosystem.
It
is
also
important
for
implementers
to
understand
that
in
the
three
party
model
,
the
holder
coordinator
acts
as
a
conduit
between
the
issuer
and
the
verifier
,
enabling
interoperability
between
the
two
even
if/when
the
holder
coordinator
doesn't
necessarily
implement
verification
of
certain
proofs
.
As
an
example
in
another
space:
"Web
browsers
were
able
to
download
and
store
PDF
files
prior
to
adding
their
own
PDF-reader
functionality"
—
this
kind
of
decentralized
innovation,
interoperability,
and
progressive
enhancement
is
important
in
the
three
party
model
and
more
generally
in
scalable,
decentralized
ecosystems.
It
is
also
important
to
help
reduce
centralization
by
not
forcing
people
to
adopt
specific
new
and
different
software
just
to
store
a
verifiable
credential
that
has
at
least
one
proof
on
it
that
their
current
software
does
not
(yet)
understand.
A
holder
coordinator
might
be
able
to
present
some
proofs
even
when
it
does
not
have
the
software
to
verify
them,
but
this
needs
to
be
understood
with
certainty,
not
guessed.
That
is,
when
adding
a
copy
of
a
stored
verifiable
credential
to
a
presentation,
holder
software
needs
to
remove
any
proofs
that
it
does
not
explicitly
know
it
can
safely
present.
Any
proofs
that
software
does
explicitly
know
it
can
safely
present
can
remain.
For
example,
a
digital
wallet
that
can
verify
an
ecdsa-rdfc-2019
proof
,
but
not
an
ecdsa-jcs-2019
proof
,
can
still
present
either.
Other
proofs
,
such
as
those
that
offer
selective
disclosure
and
/
or
unlinkable
disclosure
features
require
transformation
(that
is,
a
base
proof
is
transformed
to
a
derived
proof
plus
a
"reveal
document")
and,
therefore,
a
wallet
will
not
be
able
to
present
these
proofs
unless
the
wallet
has
implemented
the
procedures
for
deriving
a
proof.
It
is
vital
that
a
wallet
not
present
a
base
proof
by
accident,
as
it
might
include
information
that
is
secret
to
the
holder
.
This
specification
strongly
suggests
the
use
of
HTTPS
for
interaction
URLs
for
the
following
reasons:
The
HTTPS
URL
used
in
an
interaction
firmly
establishes
trust
in
the
interaction
based
on
the
existing
and
well
understood
same-origin
trust
model
used
by
browsers.
The
initial
URL
provided
establishes
trust
such
that
subsequent
protocols
used
in
the
interaction
can
be
simply
and
safely
delegated
or
outsourced
to
other
systems,
some
of
which
can
be
in
a
separate
domain.
Graphical
interfaces
that
need
to
gather
consent
can
use
domain
names,
which
are
understood
well
enough
by
section
details
the
general
population
to
combat
phishing
attacks.
Protocols
that
require
stronger
verification
of
any
party
can
use
protocol-specific
mechanisms,
such
as
verifiable
credentials
,
to
verify
the
holder
,
issuer
,
or
verifier
during
a
particular
protocol
exchange.
Using
protocol
schemes
that
are
not
rooted
in
the
HTTPS
trust
model
requires
separate
encryption
protocol,
key
management,
and
trust
models
to
be
used,
which
are
often
less
broadly
developed
and
deployed
and
require
much
more
development
and
analysis
to
determine
the
threat
and
privacy
model.
B.3
Deletion
The
APIs
provided
by
this
specification
enable
the
deletion
of
verifiable
credentials
and
verifiable
presentations
from
storage
services
.
The
result
of
these
deletions
and
the
side-effects
they
might
cause
are
out
of
scope
model
for
this
specification.
However,
implementers
are
advised
to
understand
the
various
ways
deletion
can
be
implemented.
There
are
at
least
two
types
of
deletion
that
are
contemplated
by
this
specification.
Partial
deletion
marks
a
record
for
deletion
but
continues
to
store
some
or
all
of
the
original
information.
This
mode
of
operation
can
be
useful
if
there
are
audit
requirements
for
all
credentials
and/or
presentations
over
a
particular
time
period,
or
if
recovering
an
original
credential
might
be
a
useful
feature
to
provide.
Complete
deletion
purges
all
information
related
to
a
given
verifiable
credential
or
verifiable
presentation
in
a
way
that
is
unrecoverable.
This
mode
of
operation
can
be
useful
when
removing
information
that
is
outdated
and
beyond
the
needs
of
any
audit
or
when
responding
to
any
sort
of
"
right
to
be
forgotten
"
request.
When
deleting
a
verifiable
credential
,
handling
of
its
status
information
needs
to
be
considered.
Some
use
cases
might
call
for
deletion
of
a
particular
verifiable
credential
to
also
set
the
revocation
and
suspension
bits
of
that
verifiable
credential
,
such
that
any
sort
of
status
check
for
the
deleted
credential
fails
and
use
of
the
credential
is
halted.
Given
the
scenarios
above,
implementers
are
advised
to
allow
the
system
actions
that
occur
after
a
delete
to
be
configurable,
such
that
system
flexibility
is
sufficient
to
address
any
verifiable
credential
use
case.
B.4
Payload
Sizes
Larger
transactions
can
trigger
DoS
incidents.
It's
recommended
to
configure
the
payload
size
accepted
by
endpoints
at
an
instance
level.
B.5
Additional
Validation
In
most
cases,
simply
verifying
the
proof
might
not
be
sufficient
to
properly
handle
the
received
data.
Verifier
services
are
expected
to
configure
additional
validation
steps
based
on
their
use
cases.
To
define
such
additional
validations,
implementers
can
refer
to
specifications
such
as
Section
2.3:
Resource
Integrity
and
Section
2.4:
Contexts
and
Vocabularies
in
the
Verifiable
Credential
Data
Integrity
1.0
specification
where
further
information
can
be
found
about
context
handling
and
integrity
verification.
Improper
validation
will
often
lead
to
security
vulnerabilities.
Additional
validation
steps
can
be
accounted
for
when
returning
a
verification
response
object,
through
the
problem
details.
B.6
Secure
Coding
Practices
Implementers
are
urged
to
use
industry
standard
secure
coding
practices
when
implementing
this
specification.
Even
deeply
experienced
software
developers
can
make
mistakes
and
the
use
of
secure
coding
checklists
and
vulnerability
scanning
software
can
catch
errors
that
would
result
in
including
security
compromises.
Following
checklists
and
guides
such
as
the
OWASP
Secure
Coding
Practices
Checklist
considerations,
privacy
considerations,
and
the
OWASP
Web
Security
Testing
Guide
can
help
reduce
the
chance
of
insecure
implementations.
market
competition
considerations.
A threat model for the VCALM specification has been created based on a use case of a first responder onboarding themselves to a new incident. This use case was chosen because it could be simplified to detail the issuance of a verifiable credential for the particular incident, predicated on the verification of an existing emergency responder credential. This enabled the data flow diagram in the threat model to detail both the verification and issuance steps, in the same workflow.
Since
the
interfaces
W3C
is
migrating
to
manage
the
lifecycle
of
verifiable
credentials
described
by
this
specification
are
generalized
a
holistic
threat
modelling
approach
and
is
in
nature,
the
security
implications
process
of
their
use
might
not
be
immediately
apparent
to
readers.
To
understand
deprecating
the
sort
of
security
concerns
one
might
need
to
consider
Security
Considerations
sections
in
a
complete
software
system,
implementers
are
urged
new
specifications.
Please
refer
to
read
about
how
this
technology
can
be
used
by
the
Appendix
Verifiable
Credentials
Data
A.
Threat
Model
v2.0
for
documentation
related
to
security
considerations.
W3C
is
migrating
to
a
holistic
threat
modelling
approach
and
is
in
the
section
on
Data
Integrity
Security
process
of
deprecating
the
Privacy
Considerations
sections
in
new
specifications.
Please
refer
to
Appendix
A.
Threat
Model
).
for
documentation
related
to
privacy
considerations.
The status service provides three primary operations for managing status lists:
The status list operations described in this specification (create list, get list, and set status) are non-normative and represent a recommended implementation approach. Status list creation and management might depend on various factors not accounted for in this specification, such as the following:
Implementers are free to design their status list management systems according to their specific needs, as long as the resulting status information can be verified according to the status mechanism specification in use such as the Bitstring Status List v1.0 specification.
To maximize privacy, verifiers are encouraged to obtain status information from holders rather than directly querying the status service. When a holder presents a verifiable credential , they are encouraged to include the corresponding status list credential or sufficient status information to enable verification without requiring the verifier to contact the issuer . This approach prevents correlation of status checks with specific verifiers or verifiable credentials .
This endpoint is used to create a new status list credential that can be used to track the status of verifiable credentials . A status list is itself a verifiable credential that contains status information for multiple credentials, enabling privacy-preserving status checks. The status list credential is returned in the response and can be made publicly accessible for verification purposes.
For consistency in verification processes, the status list credential typically uses the same securing mechanism (proof type and cryptographic suite) as the verifiable credentials it will be linked to. This allows verifiers to verify both the credentials and their associated status lists using the same verification methods.
For specific mechanisms by which to manage verifiable credential statuses, implementers are encouraged to refer to well-known external specifications, such as the [ VC-BITSTRING-STATUS-LIST ] specification, which provides a normative example of how to implement status list credentials.
This endpoint retrieves a publicly accessible status list credential. This endpoint is typically publicly accessible without authentication to enable verifiers and holders to retrieve status information.
The
endpoint
returns
the
status
list
credential
in
an
appropriate
format
based
on
the
media
type
requested
or
the
default
format
configured
for
the
service.
The
response
is
typically
either
a
VerifiableCredential
or
an
EnvelopedVerifiableCredential
,
consistent
with
the
format
used
by
the
verifiable
credentials
that
reference
this
status
list.
This
allows
verifiers
to
process
the
status
list
using
the
same
mechanisms
they
use
for
verifying
the
associated
credentials.
For
privacy-preserving
status
mechanisms,
verifiers
are
encouraged
to
obtain
status
information
from
holders
rather
than
directly
querying
this
endpoint.
When
a
holder
presents
a
verifiable
credential
that
includes
status
information
(such
as
a
credentialStatus
property),
the
holder
is
encouraged
to
also
provide
the
corresponding
status
list
credential
or
sufficient
status
information
to
enable
verification.
This
approach
prevents
the
issuer
from
correlating
status
checks
with
specific
verifiers
or
verifiable
credentials
,
thereby
preserving
privacy.
When a verifier needs to check the status of a verifiable credential , the recommended flow is as follows:
This endpoint might also be useful for holders who need to retrieve status list credentials to include in presentations, or for cases where direct issuer contact is acceptable from a privacy perspective.
This endpoint is used to update the status of an issued verifiable credential within a status list. When a credential's status needs to be changed (e.g., revoked or suspended), this endpoint updates the corresponding entry in the status list credential.
The request typically specifies the credential to update, the status list entry information (including the status list credential identifier and the index within that list), and the new status value. The status service updates the status list credential accordingly.
Below are examples of templates for what could be considered a minimum workflow that contains a single step, followed by an example of a minimum credential. Note that both of these "minimum" templates are still dependent on the authorization and variable choices made in each example.
{
"id": "https://localhost:18443/workflows/z19nXMUSyXawSMK6j65Vs4jb1",
"sequence": 0,
"controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"steps": {
"verify": {
"stepTemplate": {
"type": "jsonata",
"template": "{\"verifiablePresentationRequest\": verifiablePresentationRequest}"
}
}
},
"initialStep": "verify",
"zcaps": {...}
}
{
"id": "https://localhost:18443/workflows/z19mYrRgRuwN9PnezmhoJhBoV",
"sequence": 0,
"controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"credentialTemplates": [
{
"type": "jsonata",
"template": "{\"@context\": [\"https://www.w3.org/ns/credentials/v2\", \"https://www.w3.org/ns/credentials/examples/v2\"],\"type\": [\"VerifiableCredential\",\"ExampleNameCredential\"],\"credentialSubject\": {\"name\": name}}"
}
],
"steps": {
"issue": {
"issueRequests": [
{
"credentialTemplateIndex": 0,
"result": "issuedExampleNameCredentialResult"
}
]
}
},
"initialStep": "issue",
"zcaps": {...}
}
Below are examples of more complex workflows.
This
first
example
has
multiple
steps,
includes
verification
and
issuance,
supports
both
ZCAP
and
OAuth2
authorization,
shows
reuse
of
a
credential
template
both
with
and
without
custom
variables,
and
has
a
presentation
schema
check.
The
example
uses
Verifiable
Credentials
Data
Model
2.0
(
validFrom
,
https://www.w3.org/ns/credentials/v2
).
{
"id": "https://localhost:18443/workflows/z19mYrRgRuwN9PnezmhoJhBoV",
"sequence": 0,
"controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"meterId": "https://localhost:18443/meters/z1AG3Ud3apFhGaTBfRm7KZPRY",
"credentialTemplates": [
{
"id": "urn:credential-template-1",
"type": "jsonata",
"template": "\n {\n \"@context\": [\n \"https://www.w3.org/ns/credentials/v2\",\n 'https://www.w3.org/ns/credentials/examples/v2'\n ],\n \"id\": credentialId,\n \"type\": [\n \"VerifiableCredential\",\n \"UniversityDegreeCredential\"\n ],\n \"validFrom\": validFrom,\n \"credentialSubject\": {\n \"id\": results.verify.did,\n \"degree\": {\n \"type\": \"BachelorDegree\",\n \"name\": \"Bachelor of Science and Arts\"\n }\n }\n }\n"
}
],
"steps": {
"verify": {
"createChallenge": true,
"verifiablePresentationRequest": {
"query": [
{
"type": "DIDAuthentication",
"acceptedMethods": [
{
"method": "key"
}
]
},
{
"type": "QueryByExample",
"credentialQuery": [
{
"reason": "We require a verifiable credential to pass this test",
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2"
],
"type": "UniversityDegreeCredential"
}
}
]
}
],
"domain": "https://localhost:18443"
},
"presentationSchema": {
"type": "JsonSchema",
"jsonSchema": {
"title": "Presentation",
"type": "object",
"required": [
"@context",
"type",
"verifiableCredential"
],
"additionalProperties": false,
"properties": {
"@context": {
"type": "array"
},
"holder": {
"type": "string"
},
"type": {
"type": "array"
},
"proof": {
"oneOf": [
{
"type": "object"
},
{
"type": "array"
}
]
},
"verifiableCredential": {
"oneOf": [
{
"title": "Strict Degree Credential",
"type": "object",
"required": [
"@context",
"type",
"issuer",
"credentialSubject"
],
"additionalProperties": false,
"properties": {
"@context": {
"type": "array",
"items": [
{
"const": "https://www.w3.org/ns/credentials/v2"
},
{
"const": "https://www.w3.org/ns/credentials/examples/v2"
}
]
},
"id": {
"type": "string"
},
"issuer": {
"const": "did:key:z6Mkjc99Z627zYQTJXTXP5ohoFnjyGP74ooyRmRYabxz8ozo"
},
"type": {
"type": "array",
"items": [
{
"const": "VerifiableCredential"
},
{
"const": "UniversityDegreeCredential"
}
]
},
"validFrom": {
"type": "string"
},
"credentialSubject": {
"type": "object",
"required": [
"degree"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"degree": {
"type": "object",
"required": [
"type",
"name"
],
"additionalProperties": false,
"properties": {
"type": {
"const": "BachelorDegree"
},
"name": {
"const": "Bachelor of Science and Arts"
}
}
}
}
},
"proof": {
"oneOf": [
{
"type": "object"
},
{
"type": "array"
}
]
}
}
},
{
"type": "array",
"minItems": 1,
"items": {
"title": "Strict Degree Credential",
"type": "object",
"required": [
"@context",
"type",
"issuer",
"credentialSubject"
],
"additionalProperties": false,
"properties": {
"@context": {
"type": "array",
"items": [
{
"const": "https://www.w3.org/ns/credentials/v2"
},
{
"const": "https://www.w3.org/ns/credentials/examples/v2"
}
]
},
"id": {
"type": "string"
},
"issuer": {
"const": "did:key:z6Mkjc99Z627zYQTJXTXP5ohoFnjyGP74ooyRmRYabxz8ozo"
},
"type": {
"type": "array",
"items": [
{
"const": "VerifiableCredential"
},
{
"const": "UniversityDegreeCredential"
}
]
},
"validFrom": {
"type": "string"
},
"credentialSubject": {
"type": "object",
"required": [
"degree"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"degree": {
"type": "object",
"required": [
"type",
"name"
],
"additionalProperties": false,
"properties": {
"type": {
"const": "BachelorDegree"
},
"name": {
"const": "Bachelor of Science and Arts"
}
}
}
}
},
"proof": {
"oneOf": [
{
"type": "object"
},
{
"type": "array"
}
]
}
}
}
}
]
}
}
}
},
"nextStep": "issue"
},
"issue": {
"issueRequests": [
{
"credentialTemplateId": "urn:credential-template-1"
},
{
"credentialTemplateId": "urn:credential-template-1",
"variables": {
"credentialId": "urn:different",
"validFrom": "2024-01-01T00:00:00Z",
"results": {
"verify": {
"did": "did:example:1"
}
}
}
}
]
}
},
"initialStep": "verify",
"zcaps": {
"issue": {
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:560e68a8-6c39-454d-8a54-b16c7d1e35fe",
"controller": "did:key:z6MkrFmv97wsVfa7sseVctxAEAoyUL4fpLAGMfGUbtSoC3G3",
"parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fissuers%2Fz1A9Aay1eLcMPnBYEFkkqhZev",
"invocationTarget": "https://localhost:18443/issuers/z1A9Aay1eLcMPnBYEFkkqhZev/credentials/issue",
"expires": "2025-12-01T21:28:44Z",
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-12-01T21:23:44Z",
"verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fissuers%2Fz1A9Aay1eLcMPnBYEFkkqhZev"
],
"proofValue": "z4ubKiW87sRfEqSWRwoLhPGLTMuR7VnYuGyunPkWCbc6oCqUQDQUEz4bWw3zYBWACTywWj4NyBoUJwyH9VVBYZTKY"
}
},
"createChallenge": {
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:07537e74-25d7-49fa-9d30-28728bbb4838",
"controller": "did:key:z6MkrFmv97wsVfa7sseVctxAEAoyUL4fpLAGMfGUbtSoC3G3",
"parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa",
"invocationTarget": "https://localhost:18443/verifiers/z1A2cLHcMzzuGT7sBZiU7AtYa/challenges",
"expires": "2025-12-01T21:28:44Z",
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-12-01T21:23:44Z",
"verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa"
],
"proofValue": "zydEXjYSYFVAVkoHvET2QMqsHgVqxRQoYViU6DDPRncjdSj2VAW19dAFUPBrpYBTt1kwYHeVB9HNZhoHtQL7DJ2A"
}
},
"verifyPresentation": {
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:4f495517-f6bd-488f-b662-fa2f761ccd03",
"controller": "did:key:z6MkrFmv97wsVfa7sseVctxAEAoyUL4fpLAGMfGUbtSoC3G3",
"parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa",
"invocationTarget": "https://localhost:18443/verifiers/z1A2cLHcMzzuGT7sBZiU7AtYa/presentations/verify",
"expires": "2025-12-01T21:28:44Z",
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-12-01T21:23:44Z",
"verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa"
],
"proofValue": "z3NmKFcY2o146jTgpoLi6hD6TwRV7uC2SzEQrvTQSi4Sg33xCm3jE2QtYoa5MBGFvax8DCpjpjWdzzdhXUxijXLUG"
}
}
},
"authorization": {
"oauth2": {
"issuerConfigUrl": "https://localhost:18443/.well-known/oauth-authorization-server"
}
}
}
This
second
example
uses
the
stepTemplate
feature.
It
expects
the
verifiablePresentationRequest
to
be
provided
in
full
as
a
variable
when
creating
the
exchange,
and
contains
a
callbackUrl
to
demonstrate
the
callback
feature.
{
"id": "https://localhost:18443/workflows/z19nXMUSyXawSMK6j65Vs4jb1",
"sequence": 0,
"controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"meterId": "https://localhost:18443/meters/z1A7quFpnVP4NdDURjUv78JVj",
"steps": {
"verify": {
"stepTemplate": {
"type": "jsonata",
"template": "\n {\n \"createChallenge\": true,\n \"verifiablePresentationRequest\": verifiablePresentationRequest,\n \"callback\": {\n \"url\": callbackUrl\n }\n }"
}
}
},
"initialStep": "verify",
"zcaps": {
"createChallenge": {
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:103c3199-ae29-48c0-a848-61752093909c",
"controller": "did:key:z6MkezKzgnoN3fxvdnsNhyf8wacUTLt22gg6PpXi2DRFkdBA",
"parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp",
"invocationTarget": "https://localhost:18443/verifiers/z1AG62DcvrFkaszuQmcvZ1tjp/challenges",
"expires": "2025-12-01T21:32:04Z",
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-12-01T21:27:04Z",
"verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp"
],
"proofValue": "z21ZcYeG7wPae2kvznuqH9V6S3bb3M2Zfs1cEGf4KdYnHB12AAe1to6scLCgdjyLdLM1E3uWWUupkE6xGaNzVnJis"
}
},
"verifyPresentation": {
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:14b5563a-1f73-4c3b-9fbb-a93b11e1084d",
"controller": "did:key:z6MkezKzgnoN3fxvdnsNhyf8wacUTLt22gg6PpXi2DRFkdBA",
"parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp",
"invocationTarget": "https://localhost:18443/verifiers/z1AG62DcvrFkaszuQmcvZ1tjp/presentations/verify",
"expires": "2025-12-01T21:32:04Z",
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-12-01T21:27:04Z",
"verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp"
],
"proofValue": "z5pHj7SvNzB8GamN77kYLCjt66J98pHr5dqVgXpZJ7zHKnA6A2RMgVMvPAc3xxCADbuYsCgioGDPAQjvYzF9XF33u"
}
}
}
}
The lifecycle of a verifiable credential includes the creation of a workflow , an initial interaction to engage in an exchange , issuance, status management, local credential administration, presentation, verification, and validation. This specification defines an HTTP-based API for verifiable credential lifecycle management that can be used by issuers , holders , and verifiers . There are other specifications, such as Digital Credentials , OpenID for Verifiable Credential Issuance 1.0 , and OpenID for Verifiable Presentations 1.0 that might seem to provide similar functionality to this specification. This section explains what other specifications have been considered before the standardization of this specification, and how this specification differs from other specifications in the ecosystem.
Fundamentally, this specification is the only specification that is focused on the entire lifecycle management of verifiable credentials . It is agnostic to credential format, credential query language, and credential delivery protocol. Any credential format that is expressible as a verifiable credential or an enveloped verifiable credential can be used with this specification. Similarly, credential delivery protocols such as OpenID for Verifiable Credential Issuance 1.0 or OpenID for Verifiable Presentations 1.0 can be used in interactions and exchanges defined by this specification. Finally, this specification supports multiple credential query languages to provide for flexibility as technologies improve and market verticals specialize.
This specification defines APIs for the entirety of verifiable credential lifecycle management because not doing so creates opportunities for vendor lock-in. No other specification exists that provides interfaces that prevent vendor lock throughout the lifecycle management of verifiable credentials .
This section will be submitted to the Internet Engineering Steering Group (IESG) for review, approval, and registration with the IANA when this specification becomes a W3C Proposed Recommendation.
The Working Group thanks the following individuals for their contributions to this specification: The final list of acknowledgements will be compiled at the end of the Candidate Recommendation phase.
Portions of the work on this specification have been funded by the United States Department of Homeland Security's Silicon Valley Innovation Program under contracts 70RSAT20T00000003, 70RSAT20T00000010, 70RSAT20T00000029, 70RSAT20T00000031, 70RSAT20T00000033, and 70RSAT20T00000043. The content of this specification does not necessarily reflect the position or the policy of the U.S. Government and no official endorsement should be inferred.
Development of this specification has also been supported by the W3C Credentials Community Group , formerly chaired by a combination of these individuals throughout its incubation therein: Kim Hamilton Duffy, Heather Vescent, Wayne Chang, Mike Prorock, Harrison Tang, Will Abramson, Mahmoud Alkhraishi, and Denken Chen.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: