Copyright © 2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
This document specifies an API to enable user agents to mediate presentation and issuance of digital credentials such as a driver's license, government-issued identification card, and/or other types of digital credential. The API builds on Credential Management Level 1 as a means by which to request or issue a digital credential from a user agent or underlying platform.
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 at https://www.w3.org/TR/.
This is an unofficial proposal.
This document was published by the Federated Identity 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 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 which 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 03 November 2023 W3C Process Document.
This document defines an API enabling a website to request presentation and issuance of a digital credential.
The API design is agnostic to both credential presentation exchange protocols, credential issuance protocols and credential formats. However, to promote interoperability this document includes a 13. Registry of protocols.
The API is designed to support the following goals:
Digital credentials of many types can be presented and issued using this API. Examples of these types include:
The goal of the definitions in this section is to reuse or establish terminology that is common across a variety of digital credential formats and protocols. Discussions surrounding these definitions are active and the definitions are likely to change over the next several months.
This specification is currently focused on digital credentials pertaining to people.
The following items are within the scope of this specification:
The following items are out of scope:
WebIDLpartial dictionary CredentialRequestOptions {
DigitalCredentialRequestOptions digital;
};
The digital member
allows for options to configure the request for a digital credential.
WebIDLdictionary DigitalCredentialRequestOptions {
sequence<DigitalCredentialGetRequest> requests;
};
The requests
specify an exchange protocol and request data, which the user agent MAY match against a
holder's software, such as a digital wallet.
The DigitalCredentialGetRequest dictionary represents a presentation request. It is used to specify an exchange protocol and some request data, which the user agent MAY match against software used by a holder,
such as a digital wallet.
WebIDLdictionary DigitalCredentialGetRequest {
required DOMString protocol;
required object data;
};
The protocol member
denotes the exchange protocol.
The protocol member's value can be one
of the well-defined protocol identifiers defined in
13.
Registry of protocols or a custom protocol identifier.
The data member is
the request data to be handled by the holder's
credential provider, such as a digital identity wallet.
WebIDLpartial dictionary CredentialCreationOptions {
DigitalCredentialCreationOptions digital;
};
The digital member
allows for options to configure the issuance of a digital credential.
WebIDLdictionary DigitalCredentialCreationOptions {
sequence<DigitalCredentialCreateRequest> requests;
};
The requests
specify an issuance protocol and request data, which the user agent MAY forward to a
holder.
The DigitalCredentialCreateRequest dictionary represents an issuance request. It is used to specify an issuance protocol and some request data, to communicate the issuance request between the issuer and the
holder.
WebIDLdictionary DigitalCredentialCreateRequest {
required DOMString protocol;
required object data;
};
The protocol
member denotes the issuance protocol.
The protocol member's value is be one
of the well-defined keys defined in 13.
Registry of protocols or any other
custom one.
The data member
is the request data to be handled by the holder's
credential provider, such as a digital identity wallet.
The DigitalCredential interface represents a conceptual
digital credential.
User mediation is always
"required". Requesting a DigitalCredential credential does not support
"conditional",
"optional", or
"silent" user mediation. If
get() is called with anything other than
"required", a TypeError will be
thrown.
WebIDL[Exposed=Window, SecureContext]
interface DigitalCredential : Credential {
readonly attribute DOMString protocol;
[SameObject] readonly attribute object data;
static boolean userAgentAllowsProtocol(DOMString protocol);
};
DigitalCredential instances are origin bound.
The protocol member is the
exchange protocol that was used to request the
digital credential, or the issuance protocol
that was used to issue the digital credential.
The data member is the
credential's response data. It contains the subset of JSON-parseable
object types.
The CM spec's Extensions points outlines the following things to do to integrate. Adding as a todo list:
This document provides a generic, high-level API that’s meant to be extended with specific types of credentials that serve specific authentication needs. Doing so is, hopefully, straightforward.
Define appropriate:
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors). [[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) is appropriate for credentials that remain effective forever and can therefore simply be copied out of the credential store
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors). [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) is appropriate for credentials that need to be re-generated from a credential source.
[[Store]](credential, sameOriginWithAncestors) methods on ExampleCredential's interface object.
Long-running operations, like those in PublicKeyCredential's [[Create]](origin, options, sameOriginWithAncestors) and [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) operations are encouraged to use options.signal to allow developers to abort the operation. See DOM §3.3 Using AbortController and AbortSignal objects in APIs for detailed instructions.
ExampleCredential's [[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) internal method is called with an origin (origin), a CredentialRequestOptions object (options), and a boolean which is true iff the calling context is same-origin with its ancestors. The algorithm returns a set of Credential objects that match the options provided. If no matching Credential objects are available, the returned set will be empty.
Define the value of the ExampleCredential interface object's [[type]] slot:
Define the value of the ExampleCredential interface object's [[discovery]] slot:
Extend (using partial dictionary) CredentialRequestOptions with the options the new credential type needs to respond reasonably to get().
Extend (using partial dictionary) CredentialCreationOptions with the data the new credential type needs to create Credential objects in response to create().
You might also find that new primitives are necessary. For instance, you might want to return many Credential objects rather than just one in some sort of complicated, multi-factor sign-in process. That might be accomplished in a generic fashion by adding a getAll() method to CredentialsContainer which returned a sequence<Credential>, and defining a reasonable mechanism for dealing with requesting credentials of distinct types.
The userAgentAllowsProtocol() method allows digital
credential verifiers to determine which exchange protocols and issuance protocols the user agent
allows.
This method does not convey exchange protocol or issuance protocol support in the underlying OS/platform.
User agents MUST NOT vary the response value based on any information about availability of hardware, presence or configuration of software, wallets, credential providers, or digital credentials, or user configuration or preferences. If the response value varied, the user agent would introduce risks both of fingerprinting and of silently revealing other details about user behavior or configuration. The response value SHOULD vary only by user agent major version and indicate whether the browser supports distributing requests with that protocol to underlying platform or provider.
When this method is invoked, the user agent MUST execute the following algorithm:
false.
true if the user agent allows protocol, otherwise return
false.
When invoked, the [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) internal method MUST:
Document.
NotAllowedError" DOMException.
NotAllowedError" DOMException.
digital's
requests member.
TypeError.
DigitalCredential.
When invoked, the [[Store]](credential, sameOriginWithAncestors)
MUST call the default implementation of Credential's
[[Store]](credential, sameOriginWithAncestors) internal
method with the same arguments.
When invoked, the [[Create]](origin, options,
sameOriginWithAncestors) internal method, if the user agent doesn't
support issuance, call the default implementation of Credential's
[[Create]](origin, options, sameOriginWithAncestors)
internal method with the same arguments. Otherwise:
Document.
NotAllowedError" DOMException.
NotAllowedError" DOMException.
digital's
requests member.
TypeError.
DigitalCredential with
protocol initialized to the protocol that was used
to issue this credential, and data initialized to
an issuance response defined by that issuance protocol.
The DigitalCredential interface object has an internal slot named
[[type]]
whose value is "digital".
The DigitalCredential interface object has an internal slot named
[[discovery]]
whose value is "remote".
This section is non-normative.
The Digital Credential API is a powerful feature that
requires express permission from an end-user. This requirement is
normatively enforced when calling CredentialsContainer's
get() method.
This specification defines a policy-controlled feature identified by the string "digital-credentials-get". Its default allowlist is 'self'.
Initiating the registration a protocol is done by filing an issue in our GitHub repository.
The following is the registry of exchange protocols and issuance protocols that are supported by this specification.
It is expected that this registry will be become a W3C registry in the future.
To be included in the registry, the exchange protocol:
DigitalCredentialGetRequest's
data member) and the issuance protocol request structure (i.e., the
dictionary which defines the semantics and validation of the
DigitalCredentialCreateRequest's
data member).
DigitalCredential's data
member.
To be included as a presentation protocol in the registry (used with
navigator.credentials.get), the exchange protocol:
To add a new exchange protocol to the registry, or to update an existing one:
navigator.credentials.get or "Issuance" for issuance
protocols used with navigator.credentials.create.
User agents MUST support the following exchange protocols:
| Protocol identifier | Type | Description | Specification |
|---|---|---|---|
| Coming soon... | |||
This section is non-normative.
This section is a work in progress as this document evolves.
The documents listed below outline initial security considerations for Digital Credentials, both broadly and for presentation on the web. Their contents will be integrated into this document gradually.
Explain that while the API provides security at the browser API level, that security for the underlying credential issuance or presentation protocol is a separate concern and that developers need to understand that layer of the stack to get a total picture of the protections that are in place during any given transaction.
Explain that cross-device issuance or presentation uses a separate protocol that has its own security characteristics.
Explain that the API is designed to avoid the problem of quishing (phishing via QR Codes) and other QR Code and non-browser API-based attacks and to be aware of exposure of QR Codes during digital credential interactions.
Explain that the API does not provide data integrity on the digital credential requests or responses and that responsibility is up to the underlying protocol used for the request or response.
Explain that authentication (such as a PIN code to unlock) to a particular app, such as a digital wallet, that responds to an API request is crucial in high-risk use cases.
Explain what attacks are possible via XSS and CSRF, if any.
Explain that once a secure session is established at a website using credentials exchanged over this API, that the subsequent security is no longer a function of the credential used or this API and is up to the session management utilized on the website.
This section is non-normative.
This section is a work in progress as this document evolves.
The Digital Credentials API integrates into a complex ecosystem with multiple technology layers and various participants (including but not limited to Verifiers, Holders and Issuers), each of which have to consider different aspects of user privacy. This specification does not attempt to exhaustively list all considerations for the different participants. We would like to refer these parties to a variety of other resources that explore the digital credentials threat model more holistically:
Instead, these considerations focus on the Digital Credentials API itself, and describe how user agents can satisfy their user agent duties in an implementation of the API, taking into account the relevant privacy properties of the ecosystem it interacts with.
The privacy considerations for digital credentials are not static. They will evolve over time as the ecosystem matures, and may be informed by the behavior of other actors in the ecosystem, improvements in other layers of the stack, new threats to user privacy, as well as changing societal norms and regulations.
It is expected that the various groups involved in the design and implementation of the Digital Credentials API actively monitor the evolving privacy landscape and participate in the corresponding evolution of the API.
The Digital Credentials API is designed to mediate requests for digital credentials from websites, being agnostic to the credential format and the information contained in it, as well as the protocol used to exchange it (within the bounds on the protocol registry inclusion criteria). This and other key design choices are derived from the goal of providing a more secure and private credential exchange experience for users than the existing alternatives (e.g., [custom-schemes]), that is still compatible with common exchange protocols for ease of adoption.
The API provides the connection interface between verifiers and holders, i.e. the means by which a credential exchange protocol is initiated and the user switches to the holder application to select a credential. Solutions that have been used for this purpose in the past include QR codes and custom URL schemes. As documented in Presenting Credentials on the Web and Concerns with custom schemes for identity presentment, those solutions have security, privacy, and accessibility concerns.
With adoption of digital credential technology being driven by ecosystem demand and regulatory mandates, the Web platform offers an alternative to the aforementioned less-desirable technologies that is easy to use for developers, is compatible with existing credential exchange protocols and, most importantly, has better user privacy, security, and accessibility properties than these alternatives.
The Digital Credentials API offers the user agent the ability to intermediate on behalf of the user (e.g. in the form of a credential chooser) to contextualize requests and prevent immediate exposure to holder applications. It also enforces certain minimum requirements on supported protocols, such as response encryption.
The Digital Credentials API serves a variety of use cases with different grades of data disclosure and individual users with different preferences depending on the context that they are in. Notably, the privacy properties of a credential exchange mediated by this API could be mandated by the legal and regulatory environment of an individual user.
This means that some users may not want, or be allowed, to use the most privacy-preserving means of exchanging credential information. Nonetheless, user agents need to serve users with an experience that is private by default and protect them from harm.
Because of this spectrum of preferences and use cases, it may be difficult for a user agent to discern whether a user means to expose their personal information or is being tricked into doing so. It is thus the user agent's responsibility to ensure that every user understands what data they are sharing and who will participate in the exchange of information, before the exchange begins.
Because the Digital Credentials API sits at the center of an exchange that involves multiple independent parties, the exchange protocol and credential format used by these parties for exchanging user information are crucial to the user agent's goal of protecting user privacy.
The protocol registry for the Digital Credentials API is designed to ensure that, among other requirements, supported protocols facilitate specific privacy-enhancing capabilities. Protocols are required to undergo privacy review by the W3C's Privacy Working Group.
There are two requirements for protocols that I think need further elaboration:
MUST have undergone privacy review [...]
And
MUST have undergone security review [...]
Technically, a review saying "this protocol is awful in every way" satisfies these criteria.
It would be more useful if there were a set of concrete privacy and security requirements that a protocol needed to satisfy, such a review would be able to say whether a standard was achieved or not. It might be the case that there are subjective elements to a review, but there should also be a minimum bar that each protocol needs to clear.
This goes beyond the present set of requirements in the current inclusion criteria. I don't have a comprehensive list to hand, but one should be possible to develop. And once developed, that list should be in the spec. For instance, does the protocol depend on phoning home? Does the protocol (or the formats it conveys) guarantee unlinkability of presentations? Or - given that unlinkability doesn't make sense for some use cases - under what conditions does the API require the protocol provide unlinkability? What sort of transparency affordances does the protocol include? What sorts of covert channels are acceptable?
Selective disclosure is a fundamental technique for data minimization that allows holders to share the minimum required information that is requested by a verifier. Protocols are expected to facilitate selective disclosure by allowing the verifier to specify the exact claims needed.
Unlinkability is a property that ensures that, if a user presents attributes from a credential multiple times, verifiers cannot link these separate presentations to conclude they concern the same user (verifier-verifier linkability), or that verifiers can not collude with issuers to report the exchange of a credential from a wallet to the issuer (verifier-issuer linkability). The former is a property that can be maintained by the wallet and issuer, e.g. through issuing fresh credentials for individual verifiers.
While the latter is achievable, e.g. through Zero-Knowledge Proofs, design choices of the API such as encrypted responses make it impossible for a user agent to prove that verifier-issuer unlinkability was achieved in practice. Nonetheless, protocols are requested to limit linkability wherever possible.
Note that unlinkability is exclusively a consideration for attributes that can not be linked to a specific user identity. Inherently linkable attributes such as names, driver's license numbers or phone numbers do not benefit from unlinkability.
Through the Digital Credentials API, the user agent can help verifiers and wallets exchange unlinkable attributes, but it can not guarantee that no linkable information is passed between verifiers and wallets. It is recommended that user agents account for this fact in their user permission experience.
Which level of unlinkability is the goal for this API? Can we normatively enforce support for any particular unlinkability features as part of the protocol registry inclusion criteria?
"Phoning home" refers to scenarios where the presentation or verification of a digital credential causes a notification or communication back to the issuer or another central entity, which can lead to tracking and profiling of individuals.
Similar to unlinkability, it is impossible for user agents to ensure that an issuer isn't actively involved in the creation or validation of credential presentations after a user has given permission to proceed with a credential request. From that point on, the wallet application owns this decision. While some wallets can be considered user agents, it is generally recommended that the user agent implementing the Digital Credentials API designs its permission experience to prevent exposure of a request to the wallet application before user confirmation (keeping in mind considerations for integrating multiple cooperating user agents).
Protocols are required to support mechanisms that allow issuers, wallets and verifiers avoid or reduce the dependence on "phone home" mechanisms.
Which level of unlinkability is the goal for this API? To what degree can the spec mandate restrictions to issuer involvement?
A common instance of issuer involvement in a credential exchange is for credential revocation checks. This is particularly challenging when presentations are intended to be verifier-issuer unlinkable. When credential presentations are made unlinkable through the use of e.g. Zero-Knowledge Proofs, the credential formats used in protocols are expected to support offline revocation methods such as Cryptographic Accumulators. It is further expected that protocol design and specification discourages the involvement of verifiers for the purpose of revocation where possible.
We should discuss whether unlinkable revocation techniques are practical enough to be required normatively.
User understanding and participation are non-negotiable properties of a credential exchange. The protocol is expected to help all involved parties enable user participation by providing the information vital for informed permission and/or consent.
To prevent exposure of user information to other parties in "transit", for example browser extensions loaded on verifier pages, and to encourage secure storage of user credentials by the verifier, protocols are required to support and mandate encrypted responses in a credential exchange.
Related to #49 and several other discussions we've had: do we want to say that the response must always be encrypted (and if so, by which algorithms), or are we OK leaving that as optional?
Explain how the API could be used to unnecessarily request digital credentials from individuals such as requesting a driver's license to log into a movie rating website and how the ecosystem can mitigate this risk.
Explain how the API could be used to request more data than necessary for a transaction and how the ecosystem can mitigate that over collection.
The Digital Credentials API enables the sharing of highly personal, sensitive, and at-risk user information with websites via credentials, potentially granting the ability to track users online and offline, through permanent, unique, irrevocable, cross-context identifiers. It also reveals parts of the user's browsing activity as well as their intent to identify to specific websites and/or wallets. One crucial responsibility of the user agent in a credential request is to gather permission from the user to proceed with the exchange of information.
Important context details that are needed for a user to make an informed decision about proceeding with a credential exchange include the following:
It is advised that user agents in their implementation ensure that the details listed are fully disclosed to the user before an exchange of any user-related information occurs.
Should these be normative in the spec?
Should the API be designed so the site can provide in-context explanations?
We need to describe concerns, tradeoffs and possible mitigations of handling multiple requests and responses for credential presentation.
Depending on the technical architecture of a user's system, it is likely that the definition of a "user agent" will include multiple cooperating layers of the software stack, such as a browser and the operating system. The greatest priority for these layers has to be a safe and well-informed user permission experience. As such, integration can be vital for user safety. Some layers may hold information that is inaccessible by other layers, such as the availability of a user's credentials. Overprompting or prompting without sufficient context could lead to (exploitable) confusion and prompt blindness.
For this reason, user agents prompting for permission are encouraged to integrate software layers for an ideal user experience, if they consider it safe to do so. This could happen, for example, if a browser trusts the API contract of an operating system to show an appropriate prompt, and thus does not show a prompt itself.
As part of the user permission flow, the user agent needs to ensure that users retain the power to choose whether to forward a credential request to a wallet, and which wallet to select. This is due to the information disclosure that happens as part of the request, and the ability of wallets to retain or share this information at the time of the request.
The permission mediated by the user agent is not consent, which has specific legal definitions which can vary among different legal and regulatory environments and may need to be collected by the digital wallet before sharing information with the verifier, or by the verifier itself before initiating the request. With frameworks and regulations for obtaining consent still being developed, this API aims to enable the exchange of the necessary information, which could include the following:
As more of this information becomes available in a structured format, we expect user agents and this specification to leverage it to improve the user permission experience as well.
This section is non-normative.
This section is a work in progress as this document evolves.
WebIDLpartial dictionary CredentialRequestOptions {
DigitalCredentialRequestOptions digital;
};
dictionary DigitalCredentialRequestOptions {
sequence<DigitalCredentialGetRequest> requests;
};
dictionary DigitalCredentialGetRequest {
required DOMString protocol;
required object data;
};
partial dictionary CredentialCreationOptions {
DigitalCredentialCreationOptions digital;
};
dictionary DigitalCredentialCreationOptions {
sequence<DigitalCredentialCreateRequest> requests;
};
dictionary DigitalCredentialCreateRequest {
required DOMString protocol;
required object data;
};
[Exposed=Window, SecureContext]
interface DigitalCredential : Credential {
readonly attribute DOMString protocol;
[SameObject] readonly attribute object data;
static boolean userAgentAllowsProtocol(DOMString protocol);
};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, and SHOULD 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.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: