W3C Candidate Recommendation Draft
Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
Decentralized identifier (DID) resolution is the process of obtaining a DID document and accompanying metadata for a specific DID. The process takes a DID and a set of resolution options as its input and returns a DID document and associated metadata about the resolved document and the resolution request. A resolved DID document is a set of information which enables cryptographically verifiable interactions with the DID subject, including mechanisms such as cryptographic public keys. This specification covers the algorithms and guidelines to be used for DID resolution and relies on the core DID specification, Decentralized Identifiers (DIDs) v1.0, which describes the underlying DID architecture in full detail.
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.
The W3C Decentralized Identifier Working Group has published this document as a W3C Candidate Recommendation and is requesting that software developers provide experimental implementations designed to test the implementability of all of the features in this document.
Implementers are cautioned that any open class 1, 2, or 3 issues listed in the issue tracker might result in changes to the specification.
To exit the W3C Candidate Recommendation phase, the W3C DID Working Group requires the following:
A feature is defined as one or more functionally related normative statements in the specification. For this specification, interoperability is defined as normative statements, such as those referring to data model properties and their values, being interpreted in the same way between two different DID Methods.
Comments regarding this document are welcome. Please file issues directly on GitHub, or send them to public-did-wg@w3.org (subscribe, archives).
The definition of the DID URL dereferencing feature is currently marked as at risk and will likely be changed or removed from the specification. The Working Group is seeking feedback from implementers regarding the value of the feature as defined by this specification.
Portions of the work on this specification have been funded by the United States Department of Homeland Security's Science and Technology Directorate under contracts HSHQDC-17-C-00019. 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.
Work on this specification has also been supported by the Rebooting the Web of Trust community facilitated by Christopher Allen, Shannon Appelcline, Kiara Robles, Brian Weller, Betty Dhamers, Kaliya Young, Kim Hamilton Duffy, Manu Sporny, Drummond Reed, Joe Andrieu, and Heather Vescent.
This document was published by the Decentralized Identifier Working Group as a Candidate Recommendation Draft using the Recommendation track.
Publication as a Candidate Recommendation does not imply endorsement by W3C and its Members. A Candidate Recommendation Draft integrates changes from the previous Candidate Recommendation that the Working Group intends to include in a subsequent Candidate Recommendation Snapshot.
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.
DID resolution is the process of obtaining a DID document for a given DID. This is one of four required operations that can be performed on any DID ("Read"; the other ones being "Create", "Update", and "Deactivate"). The details of these operations differ depending on the DID method. Building on top of DID resolution, DID URL dereferencing is the process of retrieving a representation of a resource for a given DID URL. Software and/or hardware that is able to execute these processes is called a DID resolver.
This specification defines a standard interface that clients can use to execute DID resolution and DID URL dereferencing requests, independent of any specific DID method's "Resolve" operation that a DID resolver supports. Additionally, this specification defines requirements, algorithms including their inputs and results, architectural options, and various security and privacy considerations relevant to implementing a DID resolver or DID URL dereferencer.
Note that while this specification defines some base-level functionality for DID resolution, the actual steps required to communicate with a DID's verifiable data registry are defined by the applicable DID method specification.
This section is non-normative.
By invoking a DID resolver using the standard resolve(did,
resolutionOptions) interface (as defined in the
DID Resolution section), one can obtain a DID document
and accompanying metadata (e.g., contentType, proof, versioning), which an
application can use to validate a user's cryptographic keys, service endpoints,
or status.
For example, to retrieve the state of the DID did:example:123 at a
time in the past, a client application could resolve the DID with the
versionTime resolution option, as in the
following:
resolve("did:example:123",
{"versionTime":"2021-05-10T17:00:00Z"}) Or a client could dereference
a DID URL like
did:example:123?service=files&relativeRef=/resume.pdf
to fetch a user's resume stored via a service declared in the DID document.
Further, the specification's DID URL dereferencing algorithm
shows how a client can follow a fragment (e.g., #key-1) to extract a
particular verification method from the DID document.
Implementers are encouraged to validate their resolver against the
DID Resolution Test Suite
which exercises normative MUSTs and error conditions (such as invalid DIDs,
deactivated DIDs, unsupported methods, relative URL expansion, etc.) so
that client applications can reliably depend on correct resolution behavior
across different DID methods.
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, NOT REQUIRED, OPTIONAL, RECOMMENDED, REQUIRED, 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.
A conforming DID resolver is any algorithm realized as software and/or hardware that complies with the relevant normative statements in 4. DID Resolution.
A conforming network-based DID resolver is a conforming DID resolver that additionally complies with the normative statements in 9.1 HTTP(S) Binding.
A conforming DID URL dereferencer is any algorithm realized as software and/or hardware that complies with the relevant normative statements in 5. DID URL Dereferencing.
This section is non-normative.
This specification has three primary audiences: implementers of conformant DID methods; implementers of conformant DID resolvers; and implementers of systems and services that wish to resolve DIDs using DID resolvers. The intended audience includes, but is not limited to, software architects, data modelers, application developers, service developers, testers, operators, and user experience (UX) specialists. Other people involved in a broad range of standards efforts related to decentralized identity, verifiable credentials, and secure storage might also be interested in reading this specification.
This section is non-normative.
The DID resolution specification is intended to support a broad range of use cases by defining a standardized interface to resolve DIDs and dereference DID URLs independent of the DID method of any particular DID. These usecases include:
This section defines the terms used in this specification and throughout decentralized identifier infrastructure. A link to these terms is included whenever they appear in this specification.
A set of parameters that can be used together with a process to independently verify a proof. For example, a cryptographic public key can be used as a verification method with respect to a digital signature; in such usage, it verifies that the signer possessed the associated cryptographic private key.
"Verification" and "proof" in this definition are intended to apply broadly. For example, a cryptographic public key might be used during Diffie-Hellman key exchange to negotiate a shared symmetric key for encryption. This guarantees the integrity of the key agreement process. It is thus another type of verification method, even though descriptions of the process might not use the words "verification" or "proof."
The DID URL syntax supports a simple format for parameters (see section Query in [DID-CORE]). Adding a DID parameter to a DID URL means that the parameter becomes part of the identifier for a resource.
did:example:123?versionTime=2021-05-10T17:00:00Z
did:example:123?service=files&relativeRef=/resume.pdf
For each DID parameter that is present, its associated value MUST be a scalar value string serialized into ASCII according to section 3.1 of RFC3987.
Some DID parameters are completely independent of any specific DID method and function the same way for all DIDs. Other DID parameters are not supported by all DID methods. Where optional parameters are supported, they are expected to operate uniformly across the DID methods that do support them. The following table provides common DID parameters that function the same way across all DID methods. Support for all DID Parameters is OPTIONAL.
| Parameter Name | Description |
|---|---|
service
|
Identifies a service from the DID document by service ID. |
serviceType
|
Identifies a set of one or more services from the DID document by service type. |
relativeRef
|
A relative URI reference according to
RFC3986 Section 4.2 that identifies a
resource at a DID service endpoint,
which is selected from a DID document by using
the service parameter.
|
versionId
|
Identifies a specific version of a DID document to be resolved (the version ID could be sequential, or a UUID, or method-specific). |
versionTime
|
Identifies a certain version timestamp of a
DID document to be resolved. That is, the most
recent version of the DID document that was
valid for a DID before the specified
versionTime. If present, the associated value MUST be
represented in the datetime format as defined in
3.1 Datetime.
|
Implementers as well as DID method specification authors might use additional DID parameters that are not listed here. For maximum interoperability, it is RECOMMENDED that DID parameters use the DID Document Properties Extensions mechanism [DID-EXTENSIONS-PROPERTIES], to avoid collision with other uses of the same DID parameter with different semantics.
The DID resolution and the DID URL dereferencing functions can be influenced by passing DID resolution options to a DID resolver. Such options are not part of the DID or DID URL. This is comparable to HTTP, where certain parameters could either be included in an HTTP URL, or alternatively passed as HTTP headers.
All datetime values in this specification MUST be an
ASCII string which is a valid XML datetime value
defined by the [VC-DATA-MODEL] in Verifiable Credentials Data Model v2.0.
Additionally, timestamps used in DID Resolution MUST be adjusted to
UTC without sub-second decimal precision. For example:
2020-12-20T19:17:47Z
DID URL query strings are routinely constructed, parsed, logged, cached, and compared by multiple independent components across a resolution pipeline — for example, a client, a caching proxy, a downstream resolver, and a DID method-specific resolver. Inconsistent normalization of DID URL query strings across these components can silently produce incorrect resolution results, cache poisoning, or broken interoperability. This section enumerates edge cases that implementers and DID method specification authors are encouraged to address explicitly.
The guidance in this section concerns how a DID URL query string is normalized for the purposes of parsing, comparison, and forwarding. It is distinct from the question of which parameters are passed as resolution options as opposed to being embedded in the DID URL, which is addressed at the end of 3. DID Parameters in the note on the distinction between DID parameters and resolution options.
This section is non-normative.
The percent-encoding of a character in a DID URL query string does not change the identity of the resource being identified, but different encodings of the same logical value could be treated as distinct strings by implementations that perform naive string comparison.
Implementations that compare, cache, or forward DID URLs are encouraged to normalize percent-encoding before comparison or storage. The following rules, consistent with RFC3986 Section 6.2.2: Syntax-Based Normalization, are suggested as a baseline:
%2F rather than %2f).
%26 for &, %3D for =), as doing so would
alter the parsed structure of the query string.
DID method specifications are encouraged to document which characters in their method-specific DID parameters are safe to decode during normalization.
The relativeRef DID parameter value will typically contain percent-encoded
path separators and query characters (e.g.,
relativeRef=%2Fresume.pdf%3Fversion%3D2). Avoid decoding these as part of
query-level normalization, as the encoded form is intentional and necessary for
the value to be correctly interpreted as a relative reference during
dereferencing.
The DID URL syntax does not prohibit duplicate
occurrences of the same query parameter name within a single DID URL (e.g.,
did:example:123?service=files&service=agent). The behavior of resolution and
dereferencing functions when duplicate parameters are present is otherwise
unspecified by this document.
Implementers are encouraged to define and document the behavior of their
implementations when a DID URL contains duplicate query
parameter names. Because all DID parameters defined in this specification have
scalar values (see 3. DID Parameters), a duplicate occurrence of
any of these parameters represents an ambiguous input with no well-defined
resolution behavior. One reasonable approach is to treat such a
DID URL as invalid and return an INVALID_DID_URL error
(see 8. Errors).
DID method specifications that define method-specific query parameters are encouraged to explicitly state whether duplicate occurrences of those parameters are permitted, and if so, to define the resolution semantics (e.g., first value wins, last value wins, set union).
The set of query parameters defined in 3. DID Parameters is not exhaustive. DID methods can define additional method-specific query parameters, and the canonical form of those parameters (including their names, value formats, and ordering) can vary by method.
DID method specifications are encouraged to specify a canonical form for any method-specific query parameters they define, covering the following considerations:
Implementations that need to test two DID URLs for logical equivalence (for example, for cache lookup) are encouraged to apply parameter-ordering-independent comparison after applying the percent-encoding normalization described in 3.2.1 Percent-Encoding Normalization, unless the applicable DID method specification defines a canonical parameter ordering with semantic significance.
The DID resolution function resolves a DID into a DID document by using the "Resolve" operation of the applicable DID method as described in Method Operations.
DID resolution is a part of DID URL dereferencing, as described in 5. DID URL Dereferencing.
To be able to dereference a DID URL, one first needs a DID document, which is the result of the DID resolution process. The DID document is used in various ways during the DID URL dereferencing process. The term DID resolution is consistent with "URI resolution" as defined in RFC3986 Section 1.2.2, since it provides "the appropriate parameters necessary to dereference a URI".
All conforming DID resolvers implement the function below, which has the following abstract form:
resolve(did, resolutionOptions) →
« didResolutionMetadata, didDocument, didDocumentMetadata »
All conforming DID resolvers MUST implement the DID resolution function for at least one DID method and MUST be able to return a DID document.
Conforming DID resolver implementations do not alter
the signature of this function in any way.
DID resolver implementations might map the
resolve function to a method-specific internal function to
perform the actual DID resolution process.
DID resolver implementations might implement and
expose additional functions with different signatures in addition to the
resolve function specified here.
The input variables of the resolve function are as follows:
resolve function in addition to the
did itself. This structure is further defined in
4.1 DID Resolution Options. This input is REQUIRED, but the
structure MAY be empty.
This function returns multiple values, and no limitations are placed on
how these values are returned together. The return values of
resolve are didResolutionMetadata,
didDocument, and didDocumentMetadata.
These values are described below:
error property describing
the error. See Section 8. Errors.
id
in the resolved DID document MUST be string equal
to the DID that was resolved. If the
resolution is unsuccessful, this value MUST be empty.
didDocument property.
If the resolution is unsuccessful, this output MUST be an
empty metadata structure.
This structure is further defined in 4.3 DID Document Metadata.
This is a metadata structure that contains input options for the DID Resolution process.
The possible properties within this structure and their possible values SHOULD be registered in the DID Resolution Extensions [DID-EXTENSIONS-RESOLUTION]. This specification defines the following common input options:
Accept
header value as defined in HTTP Semantics,
Section 12.5.1. The DID resolver
implementation SHOULD use this value to determine the representation
of the returned didDocument if such a representation
is supported and available. This property is OPTIONAL.
This is a metadata structure that contains metadata about the DID Resolution process.
This metadata typically changes between invocations of the DID Resolution function as it represents data about the resolution process itself.
The source of this metadata is the DID resolver.
Examples of DID Resolution Metadata include:
contentType).error) (see Section 8. Errors).
The possible properties within this structure and their possible values SHOULD be registered in the DID Resolution Extensions [DID-EXTENSIONS-RESOLUTION]. This specification defines the following common metadata properties:
didDocument. This
property is OPTIONAL. If present, the value of this property MUST be
an ASCII string that is the Media Type of the
conformant representations. In this case, the caller
of the resolve function MUST use this value when
determining how to parse and process the didDocument.
Some DID resolvers and DID URL dereferencers use proofs when executing the DID Resolution or DID URL Dereferencing functions.
DID resolution metadata MAY include a proof property.
If present, the value MUST be a set where each
item is a map that represents a proof. The use
of this property and the types of proofs are DID method-independent.
This is a metadata structure that contains metadata about the DID Resolution process.
This metadata typically does not change between invocations of the DID Resolution function unless the DID document changes, as it represents data about the DID document.
The sources of this metadata are the DID controller and/or the DID method. DID document metadata attested to by the DID controller comes with no inherent guarantee of accuracy. Clients are advised to proceed with caution when relying on DID document metadata to inform business logic.
Examples of DID document metadata include:
created,
updated, nextUpdate).
versionId,
nextVersionId).
proof).
The possible properties within this structure and their possible values SHOULD be registered in the DID Document Properties Extensions [DID-EXTENSIONS-PROPERTIES]. This specification defines the following common metadata properties.
created property
to indicate the timestamp of the
Create operation. The value of
the property MUST be represented in the datetime format as defined in
3.1 Datetime.
updated property to indicate the timestamp of the last
Update operation for the
document version which was resolved. The value of the property MUST be
represented in the datetime format as defined in 3.1 Datetime.
The updated property is omitted if an Update operation has
never been performed on the DID document. If an
updated property exists, it can be the same value as
the created property when the difference between the
two timestamps is less than one second.
true. If a DID has not been deactivated,
this property is OPTIONAL, but if included, MUST have the boolean value
false.
nextUpdate property if the resolved document version is
not the latest version of the document. It indicates the timestamp
of the next Update operation.
The value of the property MUST be represented in the datetime format as defined
in 3.1 Datetime.
versionId property to indicate the version of the last
Update operation for the document
version which was resolved. The value of the property MUST be an
ASCII string.
nextVersionId property if the resolved document version
is not the latest version of the document. It indicates the version
of the next Update operation.
The value of the property MUST be an ASCII string.
A DID method can define different forms of a DID that are
logically equivalent. An example is when a DID takes one form
prior to registration in a verifiable data registry and
another form after such registration. In this case, the
DID method specification might need to express one or more DIDs
that are logically equivalent to the resolved DID as a property of the
DID document. This is the purpose of the
equivalentId property.
DID document metadata MAY include an
equivalentId property. If present, the value MUST be
a set where each item is a
string that conforms to the rules in
Section Decentralized Identifiers (DIDs) v1.0. The relationship is a
statement that each
equivalentId value is logically
equivalent to the id property value and thus refers
to the same DID subject. Each
equivalentId DID value MUST be
produced by, and a form of, the same
DID method as the id property
value. (e.g., did:example:abc ==
did:example:ABC)
A conforming DID method specification MUST
guarantee that each
equivalentId value is logically
equivalent to the id property value.
A requesting party is expected to retain the values from the
id and
equivalentId properties to ensure
any subsequent interactions with any of the values they contain
are correctly handled as logically equivalent (e.g., retain all
variants in a database so an interaction with any one maps to the
same underlying account).
equivalentId is a much stronger form of equivalence than
alsoKnownAs because the
equivalence MUST be guaranteed by the governing DID method. The use of
equivalentId means that the same DID document
describes both the equivalentId DID and the
id property DID.
If a requesting party does not retain the values from the id and
equivalentId properties and ensure
any subsequent interactions with any of the values they contain
are correctly handled as logically equivalent, there might be
negative or unexpected issues that arise. Implementers are
strongly advised to observe the directives related to this
metadata property.
The canonicalId property is identical to the
equivalentId property except: a)
it is associated with a single value rather than a set, and b) the
DID is defined to be the canonical ID
for the DID subject within the scope of the
containing DID document.
DID document metadata MAY include a canonicalId property.
If present, the value MUST be a string that
conforms to the rules in Section Decentralized Identifiers (DIDs) v1.0.
The relationship is a statement that the canonicalId
value is logically equivalent to the id property value and that
the canonicalId value is defined by the DID method
to be the canonical ID for the DID subject in the scope of the
containing DID document. A canonicalId value MUST be
produced by, and a form of, the same DID method as the id
property value. (e.g., did:example:abc ==
did:example:ABC).
A conforming DID method specification MUST guarantee that the
canonicalId value is logically equivalent to the
id property value.
A requesting party is expected to use the
canonicalId value as its primary
ID value for the DID subject and treat all
other equivalent values as secondary aliases (e.g., update
corresponding primary references in their systems to reflect the
new canonical ID directive).
canonicalId is the same statement of equivalence as
equivalentId except it is constrained to a single value
that is defined to be canonical for the DID subject in the scope of the
DID document. Like equivalentId, the use of
canonicalId means that the same DID document
describes both the canonicalId DID and the
id property DID.
If a resolving party does not use the
canonicalId value as its primary
ID value for the DID subject and treat all other equivalent values
as secondary aliases, there might be negative or unexpected issues
that arise related to user experience. Implementers are strongly
advised to observe the directives related to this metadata
property.
Many DID methods use proofs when executing method operations.
DID document metadata MAY include a
proof property. If present, the value MUST be a
set where each item is a
map that represents a proof. The use
of this property and the types of proofs are
DID method-specific.
A DID resolver implements the following DID resolution algorithm.
did rule of the DID Syntax.
If not, the DID resolver MUST return the following result:
https://www.w3.org/ns/did#INVALID_DID
null«[ ]»https://www.w3.org/ns/did#METHOD_NOT_SUPPORTED
null«[ ]»https://www.w3.org/ns/did#FEATURE_NOT_SUPPORTED
null«[ ]»https://www.w3.org/ns/did#INVALID_OPTIONS
null«[ ]»https://www.w3.org/ns/did#NOT_FOUND
null«[ ]»«[ ... ]»null«[ "deactivated" → true, ... ]»
expandRelativeUrls option with a value of
true:
id property is a relative DID URL,
or if a verification relationship is a
relative DID URL:
«[ "contentType" → output DID document media type, ... ]»«[ ... ]»
If the DID resolver encounters any unexpected errors during the execution of the DID Resolution algorithm, it MUST return the following result:
https://www.w3.org/ns/did#INTERNAL_ERROR
null«[ ]»Dereferencing means taking a reference to a resource and bringing that resource into the current computational context, often by invoking a handler specific to the resource type.
Dereferencing a HTTP(S) URL means retrieving a representation of a resource from a web server and invoking a handler specific to the media type of the retrieved resource. For web pages, that means displaying the retrieved HTML in the browser, with the appropriate rendering view.
Dereferencing a DID URL means retrieving the resource referred to by the DID URL and invoking an appropriate function that applies it in the current context.
DIDs allow for a number of distinct handling strategies to enable DID URLs that refer to resources made available in a variety of ways, including web-based resources, resources embedded in DID Documents, resources secured by integrity proofs in DID documents, and resources stored "on chain" with a decentalized system.
Regardless of the appropriate handling strategy, all DID URL Dereferencing requires resolving the DID embedded in the DID URL and using the result of Resolve — typically a DID Document — to determine, and then invoke, the appropriate handler.
The following DID URL dereferencing algorithm describes how a conforming client of a conforming DID Resolver prepares for, executes, and handles the response to a call to Resolve.
All conformant clients MUST execute the steps in this algorithm. The only required inputs are the DID URL to be dereferenced, the context in which that DID URL is being used, and configuration details regarding any preferred resolvers and available handlers. The expected side effect of dereferencing is the invocation of a handler that applies any retrieved resource to the current context. The interfaces for such handlers are outside the scope of this specification.
All conforming clients MUST allow DID URL Users to set specific resolvers to be used for any specific DID Method. Similarly, conforming clients SHOULD allow DID URL Users to set the handlers to be used for any specific handling strategy. How these settings are exposed to the user is outside the scope of this specification.
The dereferencing algorithm in this section is an alternative approach to the one in the previous section and is currently marked as at risk. The Working Group is likely to converge on a revision to the dereferencing algorithms in this specification being discussed here.
The Working Group is currently exploring this new DID URL Dereferencing algorithm, which has a more modular approach than the previous one, and is based on using the DID URL and the result from Resolution to determine a handling strategy and invoke an appropriate handler.
did-url rule of the
DID
URL Syntax.
If not, the DID URL client MUST end
without further processing, indicating a failure due to
an
https://www.w3.org/ns/did#INVALID_DID_URL
did:ex:abc#key-1 contains the DID did:ex:abc.
After successfully resolving the DID document and accompanying metadata, the next step is to determine the appropriate strategy for handling the DID URL. This involves analyzing the contents of the DID resolution result, including the DID document and its metadata, along with the path and query components of the DID URL, to determine the method for retrieving the resource.
Using the result from resolution, execute the following steps starting with the Services Step until a handling strategy is determined. End processing as soon as a strategy is set.
If service is present as a DID query Parameter,
first check whether multiple service parameters are present in the
DID URL. If there are, raise an error
DEREFERENCING_ERROR_MULTIPLE_SERVICE_PARAMETERS and continue to
the Default DID Document step. If there is just
one service parameter, use the service
selection algorithm to select the appropriate service
object. Then, if there is no matching service object, raise an
error DEREFERENCING_ERROR_SERVICE_NOT_FOUND and continue to the Default DID Document Step. If
the selected object's service type has defined a handling
strategy, set the strategy to that. If the service type does not
define a handling strategy, set strategy to the Default
Service Handler Strategy. Otherwise, continue with the
PathHandlers Step.
If the DID URL contains a non-empty path part, then use the PathHandler Path Matching Algorithm to select a path handler object. If no path handler objects are selected, continue to the Document Properties step. If there are multiple handler objects selected, raise an error DEREFERENCING_ERROR_MULTIPLE_MATCHING_PATH_HANDLERS and continue to the Default DID Document Step. If the sole selected path handling object has a secondary type that defines a handler strategy, set the strategy to that strategy. If it doesn't, raise an error DEREFERENCING_ERROR_PATH_HANDLER_HANDLER_NOT_DEFINED and continue to the Default DID Document Step.
If the DID document contains any properties known to define a handler strategy, check whether any of those properties apply to the DID URL. If not, continue with the Method-Specific Step. If the DID document contains multiple properties that apply to the DID URL, raise an error DEREFERENCING_ERROR_MULTIPLE_DOCUMENT_PROPERTIES and continue to the Default DID Document Step. If the DID document contains a single property with a known handler strategy that applies to the DID URL, set the strategy to the strategy defined by that property. Otherwise, continue to the Method-Specific Step.
If the DID method defines a method-specific handler strategy, check whether that handler applies to the DID URL. If it does, set the handler strategy to that specified by the DID method. If there is no applicable method-specific handler strategy, continue with the Query Parameters Step.
If there are query parameters that require a specific handling strategy, check to see if there are more than one. If there are, then raise an error DEREFERENCING_ERROR_MULTIPLE_QUERY_PARAMETERS and continue to the Default DID Document Step. If there is only one such query parameter, set the strategy to that defined by the query parameter specification. Otherwise, continue with the Metadata Step.
Not all query parameters will change the handling strategy. For
example, versionTime and versionId only change the resolution result, but
do not impact the dereferencing step.
If either the DID resolution metadata or DID document metadata contain any properties known to define a handler strategy, check to see if any of those properties apply to the DID URL. If there is only one such property, set the strategy to the strategy defined by that property. If there are multiple applicable properties, raise an error DEREFERENCING_ERROR_MULTIPLE_METADATA_PROPERTIES and continue to the Default DID Document Step. Otherwise, continue to Default DID Document Step.
The final step is to use the result of invoking the handler to complete the DID URL dereferencing process in the context in which dereferencing was initiated. This might involve
A DID URL may contain query parameters expected to be applied during
dereferencing, such as the transformKeys
extension. It is expected that implementations supporting such
extensions would apply those extensions in this stage when appropriate.
When a DID URL contains a service parameter use the
following algorithm to determine which service should be used for
dereferencing the DID URL.
did:example:1234?service=%23files
id property matches
the value of the service DID query parameter. If either the
id property or the service DID parameter
or both contain relative references, the corresponding absolute URIs MUST be
computed and used for determining
the match, using the rules specified in RFC3986 Section 5:
Reference Resolution
and in section Relative
DID URLs in Decentralized Identifiers (DIDs) v1.0.
If a selected service lacks a type with a specific handler, or if the service's
only type value is PathHandler, use this default handler strategy. When
invoked, execute the following algorithm.
Consider the following DID URL and DID Document section:
did:example:abc/image.png?service=#FileServer
service : [{
"id":"#FileServer",
"path":"/",
"serviceEndpoint": [
"https://example.com/didimages/",
"https://example.com/otherImages/",
"https://example.com/lastImages/"]
...
}]
serviceEndpoint is a single value,
use it. If serviceEndpoint is instead an array, randomly pick one of the
service's serviceEndpoint values as a starting point. Since each
value in the array is expected to resolve to the same set of resources (and any
given DID URL triggering that service will retrieve the same resource from any
of the endpoints), successfully dereferencing any one of them is sufficient.
Implementations MUST keep track of each endpoint as it is attempted, so that
each is exercised until either a successful result is returned or the complete
set of endpoints has been attempted. In other words raise a failure error
DEREFERENCING_ERROR_NO_SERVICE_ENDPOINTS_SUCCEED only after all of the
endpoints fail.
serviceEndpoint = "https://example.com/didimages/"
DID URL and appending it to the path
of the serviceEndpoint. First extract the non-matching part of the DID URL
path as the pathExtension. The pathExtension in the above example is
"image.png", after stripping the service's path value of "/" from the path
part of the DID URL
/image.png.
pathExtension = "image.png";
Append the pathExtension to the path part of the serviceEndpoint to
define the resourcePath.
resourcePath = /didimages/image.png
ResourcePath to create
a NormalizedResourcePath by removing dot segments, as defined in
[RFC3986] Section 5.2.4 Remove Path Segments. Then test the resulting
NormalizedResourcePath to see if the leftmost characters of the
NormalizedResourcePath match the leftmost characters of the path part of the
serviceEndpoint. If they do not match, raise an error
DEREFERENCE_ERROR_PATH_NORMALIZATION_ERROR.
ResourceUrl = https://example.com/didimages/image.png
ResourceUrl according to its scheme. For example, for an https
URL, perform a GET operation on that URL.
This default handler does not process relativeRef
parameters. Other handlers are free to process relativeRef as well as use
any other DID URL query parameters; to use such handlers, specify the associated
type value in the service object in the DID document.
When a DID Document contains a path and one or more objects with a type of
PathHandler use the following algorithm to determine
which object and handler should be used for dereferencing the DID URL.
PathHandler, select the
object whose path property has the longest complete
match from the beginning of the path part of the DID URL. The entire
value of the path property must be present in the path
part of the DID URL.
did:example:1234/image.png
and the following three PathHandling objects
service : [{
"id":"#PathServiceRoot",
"type":["PathHandler", "PathService"],
"path":"/"
...
},{
"id":"#PathServiceImage",
"type":["PathHandler", "PathService"],
"path":"/image"
...
}],
linkedResource : [{
"id":"#SecuredImage",
"type":["PathHandler", "LinkedResource"],
"path":"/image.png"
...
}]
In this scenario, the linkedResource with id SecuredImage would be
selected and it's handling strategy would be defined by the
LinkedResource specification.
When invoking this handler, simply return the DID Document retrieved from Resolve, including any dereferencing errors that may have been raised.
Dereferencing may produce several distinct errors, described below. Clients SHOULD use these errors when appropriate.
service query parameter) was not found
in the resolved document.
(Services Step)
Input and output metadata is often involved during the DID Resolution, DID URL dereferencing, and other DID-related processes. The structure used to communicate this metadata MUST be a map of properties. Each property name MUST be a string. Each property value, and each value within any complex data structure such as a map or list, MUST be a string, number, map, list, set, boolean, or null. The entire metadata structure MUST be serializable according to the JSON serialization rules in the [INFRA] specification. Implementations MAY serialize the metadata structure to other data formats.
All implementations of functions that use metadata structures as either input or output are able to fully represent all data types described here in a deterministic fashion. As inputs and outputs using metadata structures are defined in terms of data types and not their serialization, the method for representation is internal to the implementation of the function and is out of scope of this specification.
The following example demonstrates a JSON-encoded metadata structure that might be used as DID resolution options.
{
"accept": "application/did"
}
This example corresponds to a metadata structure of the following format:
«[
"accept" → "application/did"
]»
The next example demonstrates a JSON-encoded metadata structure that might be used as DID resolution metadata if a DID was not found.
{
"error": {
"type": "https://www.w3.org/ns/did#NOT_FOUND",
"title": "DID not found"
}
}
This example corresponds to a metadata structure of the following format:
«[
"error" → «[
"type" → "https://www.w3.org/ns/did#NOT_FOUND",
"title" → "DID not found"
]»
]»
The next example demonstrates a JSON-encoded metadata structure that might be used as DID document metadata to describe timestamps associated with the DID document.
{
"created": "2019-03-23T06:35:22Z",
"updated": "2023-08-10T13:40:06Z"
}
This example corresponds to a metadata structure of the following format:
«[
"created" → "2019-03-23T06:35:22Z",
"updated" → "2023-08-10T13:40:06Z"
]»
This section defines a JSON data structure that represents the result of the algorithm described in 4. DID Resolution. A DID resolution result contains the DID document as well as DID resolution metadata and DID document metadata.
The media type of this data structure is defined to be
application/did-resolution.
{
"didDocument": {
"@context": "https://www.w3.org/ns/did/v1",
"id": "did:example:123456789abcdefghi",
"authentication": [{
"id": "did:example:123456789abcdefghi#keys-1",
"type": "Ed25519VerificationKey2018",
"controller": "did:example:123456789abcdefghi",
"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}],
"service": [{
"id":"did:example:123456789abcdefghi#vcs",
"type": "VerifiableCredentialService",
"serviceEndpoint": "https://example.com/vc/"
}]
},
"didResolutionMetadata": {
"contentType": "application/did",
"retrieved": "2024-06-01T19:73:24Z",
},
"didDocumentMetadata": {
"created": "2019-03-23T06:35:22Z",
"updated": "2023-08-10T13:40:06Z",
"method": {
"nymResponse": {
"result": {
"data": "{\"dest\":\"WRfXPg8dantKVubE3HX8pw\",\"identifier\":\"V4SGRU86Z58d6TV7PBUe6f\",\"role\":\"0\",\"seqNo\":11,\"txnTime\":1524055264,\"verkey\":\"H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV\"}",
"type": "105",
"txnTime": 1.524055264E9,
"seqNo": 11.0,
"reqId": 1.52725687080231475E18,
"identifier": "HixkhyA4dXGz9yxmLQC4PU",
"dest": "WRfXPg8dantKVubE3HX8pw"
},
"op": "REPLY"
},
"attrResponse": {
"result": {
"identifier": "HixkhyA4dXGz9yxmLQC4PU",
"seqNo": 12.0,
"raw": "endpoint",
"dest": "WRfXPg8dantKVubE3HX8pw",
"data": "{\"endpoint\":{\"xdi\":\"http://127.0.0.1:8080/xdi\"}}",
"txnTime": 1.524055265E9,
"type": "104",
"reqId": 1.52725687092557056E18
},
"op": "REPLY"
}
}
}
}
The algorithms described in this specification throw specific types of errors. Implementers might find it useful to convey these errors to other libraries or software systems. This section provides specific URLs and descriptions for the errors, such that an ecosystem implementing technologies described by this specification might interoperate more effectively when errors occur. Additionally, this specification uses some errors defined in Section 3.5 Processing Errors of the [CID] specification.
Implementers SHOULD use [RFC9457] to encode the error data structure. If [RFC9457] is used:
type value of the error object MUST be a URL.
title value SHOULD provide a short but specific human-readable string for
the error.
detail value SHOULD provide a longer human-readable string for the error.
A specification that defines an error type not defined in this section MUST
define the URL to use as its type value, and MAY declare that it refines one
of the error types defined in this section.
A binding defined in Section 9. Bindings can use such a
declaration to determine how to convey that error type.
https://www.w3.org/ns/did#INVALID_DIDhttps://www.w3.org/ns/did#INVALID_DID_DOCUMENThttps://www.w3.org/ns/did#NOT_FOUNDaccept DID URL dereferencing option is not supported by
the DID method and/or
DID URL dereferencer implementation. See Section
5.1 DID URL Dereferencing Algorithm.
https://www.w3.org/ns/did#REPRESENTATION_NOT_SUPPORTED
https://www.w3.org/ns/did#INVALID_DID_URLhttps://www.w3.org/ns/did#METHOD_NOT_SUPPORTEDhttps://www.w3.org/ns/did#INVALID_OPTIONShttps://www.w3.org/ns/did#INTERNAL_ERRORdetail field SHOULD provide a longer
description of the feature that is not supported by the resolver.
https://www.w3.org/ns/did#FEATURE_NOT_SUPPORTED
This section defines bindings for the abstract algorithm in section 4. DID Resolution.
This section defines a DID resolver binding which exposes the DID resolution function (including all resolution options and metadata) via an HTTP(S) endpoint.
Use of an HTTP(S) resolver creates a reliance on a remote party and the privacy
of the requestor may be reduced through the inclusion of various HTTP headers
such as Referer, Origin, Cookies, and Authorization. Additionally,
caching by a component between the client and the
DID resolver may further reduce the privacy of the request.
The HTTP(S) binding requires a known HTTP(S) URL where a DID resolver can be invoked. This URL is called the DID resolver HTTP(S) endpoint.
This binding is generally considered a
remote binding, but could also be a
local binding if the HTTP(S) endpoint is run in a
local environment, such as on localhost.
All conforming DID resolvers MUST implement the GET version of the HTTPS binding and MAY implement the POST version. All HTTPS bindings MUST use TLS. Use of DNS names in certificates is NOT REQUIRED; resolvers MAY use TLS certificates issued for IP addresses.
Using this binding, the DID resolution function (see 4. DID Resolution) can be executed as follows:
https://resolver.example/1.0/identifiers/
https://resolver.example/1.0/identifiers/did:example:1234
Accept HTTP request header to
application/did-resolution to request a complete
7. DID Resolution Result, OR
Accept HTTP request header to
the value of the accept resolution option to
request only the didDocument value of the result.
GET request on the
request HTTP(S) URL. This invokes the
DID resolution function at the remote
DID resolver.
GET https://resolver.example/1.0/identifiers/did%3Aexample%3A1234?option1=value1&option2=value2 HTTP/1.1 Accept: application/did-resolution
POST request on the
request HTTP(S) URL. This invokes the
DID resolution function at the remote
DID resolver.
POST https://resolver.example/1.0/identifiers/did:example:1234 HTTP/1.1
Accept: application/did-resolution
{
"option1": "value1",
"option2": "value2"
}
type property of the error object, according to
the following table:
If the type property of the error object does not appear in
the table above, then the HTTP response status code is determined by the
implementation.
true in the didDocumentMetadata:
410,
even if a step below requires a different status code.Content-Type
HTTP response header is application/did-resolution:
200.
200.
Content-Type
HTTP response header. Its value MUST be the value
of the contentType metadata property in the
didResolutionMetadata (see
4.2 DID Resolution Metadata).
Content-Type HTTP response header.
See here for an OpenAPI definition corresponding to the HTTP(S) binding.
Given the following DID resolver HTTP(S) endpoint:
https://resolver.example/1.0/identifiers/
And given the following input DID:
did:example:123
Then the request HTTP(S) URL is:
https://resolver.example/1.0/identifiers/did:example:123
The resolve() function can be invoked over the HTTP(S)
binding as follows:
GET https://resolver.example/1.0/identifiers/did:example:123 HTTP/1.1 Accept: application/did-resolution
The response is as follows:
HTTP 200 OK
Content-Type: application/did-resolution
{
"didDocument": {
"@context": [ "https://www.w3.org/ns/did/v1.1" ],
"id": "did:example:123",
"verificationMethod": [{
...
}],
"service": [{
...
}]
},
"didResolutionMetadata": {
"contentType": "application/did"
},
"didDocumentMetadata": {
...
}
}
The resolve() function can be invoked over the HTTP(S)
binding as follows:
GET https://resolver.example/1.0/identifiers/did:example:123 HTTP/1.1 Accept: application/did
The response is as follows:
HTTP 200 OK
Content-Type: application/did
{
"@context": [ "https://www.w3.org/ns/did/v1.1" ],
"id": "did:example:123",
"verificationMethod": [{
...
}],
"service": [{
...
}]
}
This section contains a variety of security considerations that people using DID Resolution in production settings are advised to consider. Readers are urged to familiarize themselves with the general security advice provided in the Security Considerations section of the Decentralized Identifiers specification before reading this section.
DID resolution and DID URL dereferencing do not involve any authentication or authorization functionality. Similar to DNS resolution, anybody can perform the process, without requiring any credentials or non-public knowledge.
A DID resolver may maintain a generic cache of DID documents. It may also maintain caches specific to certain DID methods.
The noCache resolution option can be used to request a
certain kind of caching behavior.
This resolution option is OPTIONAL.
Possible values of this property are:
"false" (default value): Caching of DID documents is allowed.
"true": Request that caching is disabled and a fresh
DID document is retrieved from the
verifiable data registry.
Caching behavior can be controlled by configuration of the
DID resolver, by the
noCache resolution option, or by contents of the DID
document (e.g., a cacheMaxTtl field), or by a combination of these
properties.
Resolvers that implement noCache might be more vulnerable to denial of
service attacks, as malicious clients can bypass caching to force
expensive network requests and resource consumption. Clients
requesting resolution with noCache expect that some
resolvers will reject resolution requests that bypass caching.
Resolvers that deny resolution without caching MUST respond with a
FEATURE_NOT_SUPPORTED error that makes it clear that
bypassing the cache was not permitted so the client can attempt to
resolve without using noCache.
If JSON-LD Context files are fetched from a remote location, an attacker could alter the context file (for example, by compromising the server or intercepting the request via a man-in-the-middle attack).
Therefore, any DID resolver which performs remote retrieval of JSON-LD Context URLs is strongly advised to use a registry of context files and corresponding hashes (or a functionally equivalent mechanism) to help ensure end-to-end security. Implementations are expected to throw errors if the cryptographic hash value for a resource does not match the expected hash value.
If a versionId or
versionTime DID
parameter is provided, the DID resolution algorithm returns a
specific version of the DID document.
The DID parameters versionId and
versionTime are mutually exclusive.
The use of the versionId
DID parameter is specific to the DID method. Its possible values may
include sequential numbers, random UUIDs, content hashes, etc..
DID document metadata MAY contain a versionId property
that changes with each Update
operation that is performed on a DID document.
While most DID methods support the Update operation, there is no requirement for DID methods to keep all previous DID document versions, therefore not all DID methods support versioning.
DID methods that use a distributed system (such as a distributed ledger) as a VDR (verifiable data registry) need to manage the potential that network forks may occur. Therefore, the specification of a DID method that uses a distributed system as a VDR SHOULD specify a means by which the VDR they are using can be disambiguated from such forks.
When a DID URL dereferencer client dereferences identifiers
and linked resources in a DID document — especially
fields like verificationMethod, controller,
or alsoKnownAs — it might encounter a
dereferencing cycle. These can occur when a
DID document references another DID (or URL) that
eventually leads back to a previously dereferenced identifier, forming
a loop. A DID URL dereferencer can also encounter such a
situation when dereferencing a DID URL that
references a DID service endpoint.
did:example:alice
└── verificationMethod.controller → did:example:bob
└── verificationMethod.controller → did:example:alice
DID URL dereferencers and their clients that perform recursive dereferencing are expected to expect, detect, and handle such cycles.
Security and performance risks: If cycles are not detected and mitigated, recursive dereferencing could lead to:
Mitigation guidance: Components that recursively follow external DID document references are encouraged to track identifiers that have already been dereferenced and to detect when a cycle has occurred and take appropriate action. In addition, developers might wish to limit recursion depth or breadth to reduce the potential attack surface.
This section is non-normative.
The query component of a DID URL is used to pass DID parameters that affect resolution and dereferencing behavior (see 3. DID Parameters). Several aspects of query string handling carry security implications that implementers are advised to consider carefully.
The percent-decoded value of the relativeRef DID parameter is combined with
the serviceEndpoint URL as the base URI using the reference resolution
algorithm defined in RFC3986 Section 5, to construct a final
resource URL. If the value of relativeRef contains path traversal sequences, an attacker
might be able to cause the dereferencer to construct a resource URL that escapes the intended
path scope of the service endpoint.
Path traversal could be attempted using a variety of encodings. The following are non-exhaustive examples of sequences an attacker might use:
../%2E%2E%2F, %2E%2E/, .%2E/, %2E./
%252E%252E%252F..\ on Windows-derived path libraries)
Implementers are encouraged to:
relativeRef values that, after normalization, would produce a resource
URL whose path is not prefixed by the base path of the serviceEndpoint URL as
invalid inputs, for example by returning an INVALID_DID_URL error (see
8. Errors).
../) is not a reliable traversal detection mechanism.
This concern is particularly acute when the service endpoint URL is itself a DID
URL that will be recursively dereferenced. In such cases, a traversal sequence
in relativeRef could affect the resolution of a different DID document than
intended. See also 10.6 Dereferencing Cycles.
As described in 3.2 Query Normalization, the same logical DID URL can be represented by multiple syntactically distinct strings. In a proxied or multi-component resolution architecture, different components can apply different normalization rules (or no normalization at all).
An attacker aware of normalization inconsistencies between components could:
To mitigate these risks, implementers are encouraged to:
Implementations that construct DID URLs programmatically by string concatenation (for example, appending a caller-supplied value as a DID parameter) might be vulnerable to parameter injection if the input is not validated and encoded prior to concatenation.
For example, a caller-supplied service value of files&versionId=2 could, if
concatenated without encoding, inject an additional versionId parameter into
the DID URL, altering resolution behavior in ways the
caller might not have intended or authorized. This is analogous to query string
injection vulnerabilities in HTTP-based systems.
Implementers are encouraged to percent-encode all caller-supplied parameter values before concatenation into a DID URL query string, in accordance with RFC3986 Section 2.1, and to validate that parameter values, after decoding, conform to the expected value format for the parameter as defined in this specification (see 3. DID Parameters), in the applicable DID method specification, or in the DID Document Resolution Extensions [DID-EXTENSIONS-RESOLUTION].
This section details the privacy considerations specific to DID Resolution. Readers are urged to familiarize themselves with the general privacy advice provided in the Privacy Considerations sections of the Decentralized Identifiers specification and Controlled Identifiers specification before reading this section.
DID resolvers and DID URL dereferencers will be able to log requests to their services for resolution and dereferencing. Over time, these logs could be used to track and profile the clients making requests for these services. To mitigate this privacy risk, clients should make such requests to services they trust, for example, because of an existing business relationship or because the service is running on infrastructure they control.
Clients can also take steps to obfuscate their requests to a service to decrease the possibilities of correlation and profiling. Techniques for obfuscation include Oblivious HTTP, using a trusted proxy to execute the resolution requests, and using a trusted cache.
Different DID methods have different additional privacy implications and considerations depending on the design decisions and underlying VDR of the method. Implementers are advised to review the privacy considerations of the specific DID methods they intend to support. Designers of DID methods are encouraged to follow the W3C Threat Modeling Guide to produce a threat model, to help implementers understand the privacy implications of the method design.
One of the most common mechanisms used to resolve an identifier to an address on the Internet is the global Domain Name System (DNS) described in [RFC1034]. The DNS and the processes and systems used to map a Domain Name to an Internet Protocol address is a common requirement for hosting a website.
The Decentralized Identifiers (DIDs) v1.0 specification introduced a new type of identifier that lacks any dependency on the global Domain Name System and introduced the concept of an identifier resolution process that does not require the centralization of any part of the architecture. This new architecture allows the decentralized creation and management of globally-resolvable identifiers that combat identifier rent-seeking and censorship. It enables individuals to fully own and control their identifiers instead of renting the identifiers from a third party.
Individuals that acquire DID URLs use them in their software much like they continue to use DNS-based URLs. The software uses a DID resolver interface (defined in this specification) to determine the location of the resources to be retrieved. The process of DID resolution, much like the process of DNS resolution, is opaque to the individual and happens within the software without needing any direct involvement of the individual.
The research related to DNS centralization and the corresponding invention of DIDs and DID resolution is documented by the Decentralized Identifiers (DIDs) v1.0 specification in the section related to the history of DIDs.
This section is non-normative.
This section lists the changes since the publication of this specification as a W3C First Public Working Draft.
Changes since the Candidate Recommendation Snapshot include:
500 status code
for an error type that its status code table does not list; that
status code is now determined by the implementation. A
specification that defines an error type can declare which error
type defined in this specification it refines.contentType: The DID
Resolution algorithm now returns contentType in the
DID resolution metadata, where it is defined.200 status code for a
successful complete DID resolution result, applies its rules for
a bare DID document only to other responses, and lets
410 override other status codes.https://www.w3.org/ns/did#, which no longer
applies to any error type, is removed.Changes since the First Public Working Draft include:
resolve() (returning a data model) and
resolveRepresentation() (returning a byte
stream). The CR consolidates this into a single
resolve() function that handles returning the DID
document capable of being formatted into a conformant
representation.expandRelativeUrls. When set to true, the
resolver will automatically expand any relative DID URLs found
within the DID document into absolute DID URLs.service, serviceType,
relativeRef, versionId, and
versionTime. It also introduces a "Query
Normalization" section providing guidance on percent-encoding,
duplicate parameter handling, and method-specific
canonicalization.versionTime, created, and
updated), requiring them to be XML Datetime
strings adjusted to UTC without sub-second precision.verificationRelationship as a new dereferencing
option. During fragment dereferencing, the algorithm verifies
that the resolved verification method is formally authorized
for this specified relationship, throwing an error if it is
not.https://www.w3.org/ns/did#INVALID_DID), and new
errors such as INVALID_DID_DOCUMENT and
FEATURE_NOT_SUPPORTED were introduced.relativeRef parameter sequences
(e.g., ../).Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: