Decentralized identifiers (DIDs) are a new type of identifier for verifiable, "self-sovereign" digital identity. DIDs are fully under the control of the DID controller, independent from any centralized registry, identity provider, or certificate authority. DIDs resolve to DID Documents — simple documents that describe how to use that specific DID.
This document specifies the algorithms and guidelines for resolving DIDs and dereferencing DID URLs. Additionally, this document describes the input and output metadata related to the DID resolution processes and further describes the data structures that may be returned from a DID resolution request. This document relies on the core DID specification, Decentralized Identifiers (DIDs) v1.1, which describes the underlying DID architecture in full detail.
Comments regarding this document are welcome. Please file issues directly on GitHub, or send them to public-did-wg@w3.org (subscribe, archives).
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.
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 common requirements, algorithms including their inputs and results, architectural options, and various considerations for the DID resolution and DID URL dereferencing processes.
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.
The difference between "resolving" a DID and "dereferencing" a DID URL is being thoroughly discussed by the community. For example, see this comment.
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, a wallet app could resolve
did:example:123?versionTime=2021-05-10T17:00:00Z
(see here for detailed example)
using the `versionTime` parameter to retrieve the state of that DID
at a past time, or a client could dereference a DID URL like
did:example:123/resume.pdf (see
here for detailed example) 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 (see here
for detailed example). In practice, implementers 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.) to ensure that client applications can reliably depend on correct resolution behavior
across different DID methods.
A conforming DID resolver is any algorithm realized as software and/or hardware that complies with the relevant normative statements in .
A conforming DID URL dereferencer is any algorithm realized as software and/or hardware that complies with the relevant normative statements in .
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.
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:
The DID resolution function resolves a DID into a DID document by using the "Read" operation of the applicable DID method as described in Method Operations.
All conforming DID resolvers implement the function below, which has the following abstract form:
resolve(did, resolutionOptions) →
« didResolutionMetadata, didDocument, didDocumentMetadata »
All conformant DID resolvers MUST implement the DID resolution function for at least one DID method and MUST be able to return a DID document in at least one conformant representation.
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 . 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 .
id in the resolved DID document MUST
match 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 .
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:
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:
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. See for details.
DID resolution metadata MAY include a proof property.
If present, the value MUST be a set where each item is a
map that contains 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.
Examples of DID document metadata include:
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 a string
formatted as an XML Datetime
normalized to UTC 00:00:00 and without sub-second decimal precision. For
example: 2020-12-20T19:17:47Z.
updated property to
indicate the timestamp of the last Update
operation for the document version which was resolved. The value of the
property MUST follow the same formatting rules as the created
property. 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 follow the same formatting rules
as the created property.
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 . 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 . 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. See for details.
DID document metadata MAY include a proof property.
If present, the value MUST be a set where each item is a
map that contains a proof. The use of this property
and the types of proofs are DID method-specific.
The following DID resolution algorithm MUST be implemented by a conformant DID resolver.
null«[ ]»null«[ ]»null«[ ]»«[ ... ]»null«[ "deactivated" → true, ... ]»expandRelativeUrls option with a value of true:
id property of a service or
verification method
(including those embedded in verification relationships) is a
relative DID URL, or if a
verification relationship is a
relative DID URL:
«[ ... ]»«[ "contentType" → output DID document media type, ... ]»Should we define functionality that enables discovery of the list of DID methods or other capabilities that are supported by a DID resolver? Or is this implementation-specific and out-of-scope for this spec? For example, see here and here.
The DID URL dereferencing function dereferences a DID URL into a resource with contents depending on the DID URL's components, including the DID method, method-specific identifier, path, query, and fragment. This process depends on DID resolution of the DID contained in the DID URL. DID URL dereferencing might involve multiple steps (e.g., when the DID URL being dereferenced includes a fragment), and the function is defined to return the final resource after all steps are completed. The following figure depicts the relationship described above.
The top left part of the diagram contains a rectangle with black outline, labeled "DID".
The bottom left part of the diagram contains a rectangle with black outline, labeled "DID URL". This rectangle contains four smaller black-outlined rectangles, aligned in a horizontal row adjacent to each other. These smaller rectangles are labeled, in order, "DID", "path", "query", and "fragment.
The top right part of the diagram contains a rectangle with black outline, labeled "DID document". This rectangle contains three smaller black-outlined rectangles. These smaller rectangles are labeled "id", "(property X)", and "(property Y)", and are surrounded by multiple series of three dots (ellipses). A curved black arrow, labeled "DID document - relative fragment dereference", extends from the rectangle labeled "(property X)", and points to the rectangle labeled "(property Y)".
The bottom right part of the diagram contains an oval shape with black outline, labeled "Resource".
A black arrow, labeled "resolves to a DID document", extends from the rectangle in the top left part of the diagram, labeled "DID", and points to the rectangle in the top right part of diagram, labeled "DID document".
A black arrow, labeled "refers to", extends from the rectangle in the top right part of the diagram, labeled "DID document", and points to the oval shape in the bottom right part of diagram, labeled "Resource".
A black arrow, labeled "contains", extends from the small rectangle labeled "DID" inside the rectangle in the bottom left part of the diagram, labeled "DID URL", and points to the rectangle in the top left part of diagram, labeled "DID".
A black arrow, labeled "dereferences to a DID document", extends from the rectangle in the bottom left part of the diagram, labeled "DID URL", and points to the rectangle in the top right part of diagram, labeled "DID document".
A black arrow, labeled "dereferences to a resource", extends from the rectangle in the bottom left part of the diagram, labeled "DID URL", and points to the oval shape in the bottom right part of diagram, labeled "Resource".
All conforming DID URL dereferencers implement the function below, which has the following abstract form:
dereference(didUrl, dereferenceOptions) →
« dereferencingMetadata, contentStream, contentMetadata »
The input variables of the dereference function are as follows:
While it is valid for any didUrl to be passed to a DID URL
dereferencer, implementers are expected to refer to to
further understand common patterns for how a DID URL is expected
to be dereferenced.
dereference function in addition to the
didUrl itself. This structure is further defined in . 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 dereference are
dereferencingMetadata, contentStream, and
contentMetadata. These values are described below:
error property
describing the error. See Section .
dereferencing function was called and successful, this MUST
contain a resource corresponding to the DID URL. The
contentStream MAY be a resource such as a DID
document that is serializable in one of the conformant
representations, a verification
method, a service, or any other resource format that
can be identified via a Media Type and obtained through the resolution process.
If the dereferencing is unsuccessful, this value MUST be empty.
contentStream. If the contentStream
is a DID document, this MUST be a didDocumentMetadata structure as
described in DID Resolution. If the dereferencing is unsuccessful, this
output MUST be an empty metadata structure.
This structure is further defined in .
Conforming DID URL dereferencing implementations do not alter the
signature of these functions in any way. DID URL dereferencing
implementations might map the dereference function to a
method-specific internal function to perform the actual DID URL
dereferencing process. DID URL dereferencing implementations might
implement and expose additional functions with different signatures in addition
to the dereference function specified here.
This is a metadata structure that contains input options for the DID URL Dereferencing 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:
contentStream. The Media
Type MUST be expressed as an ASCII string. The
DID URL dereferencer implementation SHOULD use this value to determine
the contentType of the representation contained in the
returned value if such a representation is supported and available.
This is a metadata structure that contains metadata about the DID URL Dereferencing process.
This metadata typically changes between invocations of the DID URL Dereferencing function as it represents data about the dereferencing process itself.
The source of this metadata is the DID URL dereferencer.
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:
contentStream SHOULD be expressed
using this property if dereferencing is successful. The Media
Type value MUST be expressed as an ASCII string.
Some DID resolvers and DID URL dereferencers use proofs when executing the DID Resolution or DID URL Dereferencing functions. See for details.
DID URL dereferencing metadata MAY include a proof property.
If present, the value MUST be a set where each item is a
map that contains 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 URL Dereferencing process.
This metadata typically does not change between invocations of the DID URL Dereferencing function unless the content changes, as it represents data about the content.
The sources of this metadata are the DID controller and/or the DID method.
The possible properties within this structure and their possible values SHOULD be registered in the DID Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]]. This specification defines no common properties.
A DID URL consists of a DID, optionally followed by additional URL components — any combination of a path, zero or more query parameters, and/or a fragment identifier — as defined in RFC3986. This section defines how these components MUST be interpreted by DID Resolvers when dereferencing a DID URL.
The interpretation of DID URL components is conceptually similar to that of HTTP URLs having the same components:
The similarity ends there. DID Resolvers do not support arbitrary server logic or content negotiation. Instead, the interpretation of DID URL components is deterministic and governed by this specification, the applicable DID method specification, and any DID Document Properties Extensions [[?DID-EXTENSIONS-PROPERTIES]] supported by the DID Resolver.
This section describes the structure, constraints, and required handling of each DID URL component. These rules form the basis for the DID URL dereferencing algorithm.
A DID URL MAY include not more than one fragment component, as specified in RFC3986 Section 3.5. If present, the fragment component appears after all other components of the DID URL.
As with HTTP/S dereferencing, the fragment is not processed by the DID Resolver. Instead, its interpretation is the responsibility of the client that receives the dereferenced resource from the resolver. The meaning of the fragment depends on the media type of the resolved content and may be used to reference a specific node in a DID Document or a part of another structured resource. For example, if the resolved resource is a DID Document, the fragment may be used to identify a verification method to be used by the client in processing a cryptographic signature.
DID Method-specific and DID Document Properties Extensions [[?DID-EXTENSIONS-PROPERTIES]] MUST define guidance for how a DID Resolver Client should process a node in a DID Document that is referenced by a fragment. Such guidance can specify how to interpret the node's structure, expected data type, or its use in further processing (for example, verifying a signature or retrieving related resources).
A DID URL MAY include one or zero query component(s), which, if present, MAY include zero or more query parameters, as defined in RFC3986 Section 3.4. Query parameters appear after the DID and any path component, and their structure and encoding MUST follow standard URL syntax conventions. Their interpretation depends on the context in which the DID URL is used and can influence the dereferencing result.
Unlike HTTP query parameters, which are interpreted by customized web server implementations, DID parameters in DID URLs MUST have predefined semantics. A DID Resolver MUST process only recognized query parameters — specifically those defined in this specification (see the DID Parameter definitions), the applicable DID method specification, and/or DID Document Properties Extensions [[?DID-EXTENSIONS-PROPERTIES]]. All other query parameters MAY be passed through unchanged for downstream processing, such as dereferencing a DID URL path.
Query parameters may affect dereferencing behavior, such as by specifying a versioned resource or by influencing how a path is to be processed. The impact of specific query parameters defined in this specification in combination with a DID URL path is described in the next section of this specification.
A DID URL MAY include not more than one path component, as defined in RFC3986 Section 3.3. If present, the path component appears immediately after the DID and before any query or fragment component(s). Its structure and encoding MUST conform to URI syntax rules.
When a DID URL path is present, the following processing steps MUST be followed:
prefix
attribute of each relevant service entry in the
DID Document that includes such an attribute.
If the service and/or serviceType
DID Parameters are
present, the DID Resolver MUST consider only services
with the respectively specified id and/or
type values. Otherwise, all
service entries MUST be considered in the
matching process. In matching the path and
prefix, the DID Resolver MUST track the
length of the match for each service.
service with the longest matching prefix.
services have the same
longest matching prefix, the resolver
MUST fail resolution with an
appropriate error.type of the selected
service to determine how the
DID URL path is to be used in assembling the URL of the
resource to be resolved. The algorithm for assembling this
URL MUST be defined in the corresponding service type
specification. A service type specification MAY appear in
the DID Service
Types section of this document, the applicable DID
method specification, or in the DID Document
Properties Extensions [[?DID-EXTENSIONS-PROPERTIES]].
FileService type is currently the
only service type defined in this specification. See
the FileService
Service Type section for its definition.
Example 1 — Basic path resolution using a
FileService with a root (/) prefix
// DID URL:
did:web:example.com/path/to/file.txt
// DID Document service section:
{
"service": [
{
"type": "FileService",
"serviceEndpoint": "https://example.com/",
"prefix": "/"
}
]
}
// Resulting URL:
https://example.com/path/to/file.txt
Example 2 — Path maps directly to a single resource (e.g., a Verifiable Presentation describing the DID subject)
// DID URL:
did:webvh:example.com/whois
// DID Document service section:
{
"service": [
{
"type": "FileService",
"serviceEndpoint": "https://example.com/whois.vp",
"prefix": "/whois"
}
]
}
// Resulting URL:
https://example.com/whois.vp
Example 3 — Use of a non-FileService type that performs
content verification
(ExampleVerifiedFileService)
This demonstrates a (currently) fictitious service type that
behaves like FileService, but with additional
content verification logic. The final segment of the DID URL
path is treated as a hash, removed before URL assembly, and used
to verify the integrity of the resolved content.
// DID URL:
did:web:example.com/example/resume.pdf/<hash>
// DID Document service section:
{
"service": [
{
"type": "ExampleVerifiedFileService",
"serviceEndpoint": "https://example.com/example/files/",
"prefix": "/example/"
}
]
}
// Resulting URL:
https://example.com/example/files/resume.pdf
The resource is resolved from the assembled URL. Its content is hashed and compared with the <hash> value from the DID URL path to verify integrity.
Example 4 — Multiple services supporting different types of resources under distinct path prefixes
This example shows a DID Document with two service entries: one
using FileService for general file access, and
another using the ExampleVerifiedFileService from
the previous example for integrity-verified files. The path
prefix determines which service to use.
// DID URLs:
did:web:example.com/path/to/file.txt
did:web:example.com/example/resume.pdf/<hash>
// DID Document service section:
{
"service": [
{
"type": "FileService",
"serviceEndpoint": "https://example.com/",
"prefix": "/"
},
{
"type": "ExampleVerifiedFileService",
"serviceEndpoint": "https://example.com/example/files/",
"prefix": "/example/"
}
]
}
// Resulting URLs:
https://example.com/path/to/file.txt
https://example.com/example/files/resume.pdf (with hash verification after resolution)
This section defines the normative algorithm for dereferencing a DID URL into a resource. It builds on the rules in the DID URL Components Handling section of this specification.
didpathquery parameters (stored as a working set qp)fragmentqp
that affect DID Resolution (e.g., versionId,
versionTime),
including any DID Method-specific and DID Document
Property Extension [[?DID-EXTENSIONS-PROPERTIES]] DID parameters that are understood by the
DID Resolver.did into a
didDocument and
didResolutionMetadata.qp working set.path is present, resolution is
complete and the path-handling step is skipped.
qp working set.qp,
add them to the constructed URL as query parameters,
ensuring they are formatted according to RFC3986 Section
3.4.Resolving an assembled URL from a path might result in a resolution cycle, which is a set of steps that result in an infinite loop. For example, a URL assembled from a path might indirectly point back through a sequence of resolutions to a previously dereferenced URL. A DID resolver is expected to detect and handle recursive cycles when resolving a URL assembled from a path, to prevent an infinite loop or other resolution failure. For further guidance, see Section Resolution Cycles.
content: the resolved DID document
with selected servicescontentMetadata: metadata about the
resolved DID documentdereferencingMetadata: any metadata
about the dereferencing processcontent: the resolved resourcecontentType: the media type of the
resolved resourcedereferencingMetadata: any metadata
about the dereferencing processThis section defines the set of DID URLquery parameters and service types that are reserved for use within the DID Resolution algorithm and DID URL dereferencing process defined in this specification.
These values are not DID Method-specific. All DID Methods that are capable of implementing these query parameters and service types SHOULD recognize and correctly process them. DID Methods that do not support the capabilities required for a specific query parameter (e.g., historical DID Document version resolution) SHOULD recognize these query parameters and return an appropriate error.
Identifies a specific version of a DID Document to be
resolved. If present, the associated value MUST be
an ASCII string. If the DID Method does not support updating
or the tracking of DID Document versions, or if the specified
version does not match any DID Document's
versionId property, the DID Resolver
MUST return a Not Found error
indicating that the requested version could not be found.
Example: did:example:123456789abcdefghi?versionId=5e3b
Resolves the DID Document with the specific version ID "5e3b".
Identifies a point in time to resolve the version of the
DID Document active at that timestamp. The value
MUST be a valid XML datetime normalized to UTC and
without sub-second precision. If the DID Method does not
support updating or the tracking of DID Document versions or
version times, or if the DID did not exist at the specified time the
DID Resolver MUST return a Not Found error
indicating that the requested version could not be found.
Example: did:example:123456789abcdefghi?versionTime=2025-10-01T12:00:00Z
Resolves the DID Document valid on October 1, 2025 at noon UTC.
Indicates that only the service entry or entries with the specified
id are to be considered when processing the path component of a
DID URL. If present, each value MUST be an ASCII string
that is percent-encoded as required by
RFC3986 Section 2.1, and
MAY be either a relative or absolute URI reference. The
service query parameter MAY appear multiple times
in a DID URL. If no matching services are found, the
dereferencing process MUST fail.
A service query parameter can also be used in
conjunction with the deprecated relativeRef
parameter. See the relativeRef
section for more details.
Example: did:example:123456789abcdefghi/path/to/file.txt?service=%23files
Considers only the service in the resolved DID
Document with the specified id value of (percent
decoded) #files in determining how to process the
DID URL path.
Indicates that only the service entry or entries with the specified
type are to be considered when processing the path
component of a DID URL. If present, each value
MUST be an ASCII string. The service query
parameter MAY appear multiple times in a DID
URL. If no matching services are found, the dereferencing
process MUST fail.
Example: did:example:123456789abcdefghi/path/to/file.txt?serviceType=FileService
Considers only the service in the resolved DID
Document with the type value of FileService in determining how to process the
DID URL path.
A relative URI reference to a resource at a selected service endpoint. This parameter is deprecated and replaced by explicit path-based dereferencing.
If present, each value
MUST be an ASCII string representing a relative
URL path that is percent-encoded as required by RFC3986.
The relativeRef query parameter
MUST be used in conjunction with a single
service query parameter. The service
query parameter is used to identify a specific
service entry in the DID Document, and the
value of the relativeRef query parameter is
percent-decoded and appended to the serviceEndpoint
of the selected service. The resulting URL is then
resolved, and if successful, the resolved resource and metadata
are returned. If there is no service parameter, or
no service is identified in the resolved DID
Document, the dereferencing process MUST
fail with an error.
Example: did:example:123456789abcdefghi&service=storage&relativeRef=invoices%2Fnov2025.pdf
Append "invoices/nov2025.pdf" to the serviceEndpoint of
the storage service and attempt to retrieve the
resource at that URL, returning the resulting resource and
metadata or an error.
The value of the parameter is a hashlink (as defined in Hashlink). If present, it MUST be an ASCII string representing the expected multihash of the resource content. The DID Resolver MUST calculate the multihash of the dereferenced content using the steps below and compare the result to the provided hashlink. If the values match, proceed with returning the resource and metadata. If the values do not match, the DID Resolver MUST return an error.
Hash calculation steps:
hl value match. If they do not match, return an
error.Example: did:example:123456789abcdefghi?hl=hl:zQmYw5...oTwD
Ensures the integrity of the resolved content by verifying that it matches the specified hashlink.
A FileService is a service defined in a
DID Document that includes a prefix
attribute that enables participation in the deterministic
mapping of the DID URL path component to a resolvable
resource URL as described in the DID URL
Path handling section. When a service of type
FileService is selected during that process, the
DID Resolver MUST perform the following steps to
construct resource URL and dereference that URL.
prefix value from the DID URL path.serviceEndpoint URL.The prefix value MUST begin with a forward slash
(/) and MUST represent a valid path as defined by
RFC3986 Section 3.3.
The serviceEndpoint value must be a valid URL as defined by
RFC3986
and serves as the base for resources referenced by the
DID URL Path.
See DID URL Path
Examples for practical usage of FileService,
including cases with overlapping prefixes, non-root mappings,
and multi-service DID Documents.
This section provides illustrative examples of DID URLs and their corresponding dereferencing behavior.
An optional fragment identifier #fragment may
be appended to any of these examples to reference a specific node within
the returned resource. Fragment processing is performed by the client
and is not handled by the DID Resolver.
The following is the DID document that is used in all of the following examples.
{
"@context": "https://www.w3.org/ns/did/v1",
"id": "did:example:123456789abcdefghi",
"versionId": "2",
"versionTime": "2025-10-17T17:58:43Z",
"verificationMethod": [
{
"id": "did:example:123456789abcdefghi#keys-1",
"type": "Multikey",
"controller": "did:example:123456789abcdefghi",
"publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
}
],
"service": [
{
"type": "FileService",
"serviceEndpoint": "https://example.com/",
"prefix": "/"
},
{
"type": "ExampleFileService",
"serviceEndpoint": "https://example.com/files/",
"prefix": "/example/"
},
{
"type": "FileService",
"serviceEndpoint": "https://example.com/whois.vp",
"prefix": "/whois"
}
]
}
DID URL:
did:example:123456789abcdefghi
Dereferencing result:
The full, most recent
DID Document version and DID metadata is returned. A fragment
(`#keys-1`) could be appended to direct the client to use a specific
verification method
within the DID Document after resolution
versionTime Query ParameterDID URL:
did:example:123456789abcdefghi?versionTime=2025-10-01T12:00:00Z
Dereferencing result:
The DID Document
as it existed at the given time is returned, if DID Document
versioning is supported by the
DID Method. If the DID Method does not support
versioning, an error is returned.
versionTime Query ParameterDID URL:
did:example:123456789abcdefghi/path/to/file.txt?versionTime=2025-10-01T12:00:00Z
Dereferencing result:
The full, most recent
DID Document version is resolved. The path component
/resume.pdf is processed using the rules defined by
DID URL path handling, and the set of
services in the resolved
DID Document. This results in the use of the
service with "type": "FileService" and
"prefix": "/" being selected. The
FileService processing steps from the FileService
specification are followed and the resource found at:
https://example.com/path/to/file.txt
is resolved. If successful, the resolved resource and related
metadata is returned.
DID URL:
did:example:123456789abcdefghi/example/resume.pdf
Dereferencing result:
The full, most recent
DID Document version and DID metadata is returned.
The path component /example/resume.pdf is processed
using the rules defined by DID URL path
handling, using the full set of services in the
DID Document. This results in the use of the
service with "type": "ExampleFileService" and
"prefix": "/example/" being selected. The
ExampleFileService processing steps (which, for this
example, we'll assume are the same as for FileService)
are followed and the resource found at:
https://example.com/files/resume.pdf
is resolved. If successful, the resolved resource and related
metadata is returned.
DID URL:
did:example:123456789abcdefghi/example/resume.pdf?service=FileService
Dereferencing result:
The full, most recent
DID Document version is resolved. The path component
/resume.pdf is processed using the rules defined by
DID URL path handling, with the serviceType query parameter limiting the
service entries from the DID Document to be
considered to those with "type": "FileService". This
results in the use of the service with "type":
"FileService" and
"prefix": "/" being selected. The
FileService Service Type
processing steps are followed and the resource found at:
https://example.com/example/resume.pdf
is resolved. If successful, the resolved resource and related
metadata is returned.
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 MUST be a string, number, map, list, set, boolean, or null. The values within any complex data structure such as a map or list MUST be one of these data types as well. All metadata property definitions registered in the DID Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]] MUST define the value type, including any additional formats or restrictions to that value (for example, a string formatted as a date). It is RECOMMENDED that property definitions use strings for values. 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 input metadata.
{
"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": "notFound"
}
This example corresponds to a metadata structure of the following format:
«[ "error" → "notFound" ]»
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" ]»
TODO: Describe how DID resolvers are implemented and used, describe the relevance of DID methods. Explain the difference between "method architectures" and "resolver architectures".
The DID resolution algorithm involves executing the Read operation on a DID according to its DID method (see ).
Every DID method defines this method operation, i.e., how a DID resolver can obtain a DID document from a DID. The underlying data formats, protocols, technical infrastructures, and processes can vary considerably among DID methods.
Examples of DID method considerations include the following:
Based on the above considerations combined with the nature of a DID method's "Read" operation, the interaction between a DID resolver and the verifiable data registry could be considered either a verifiable read or an unverifiable read:
A verifiable read maximizes confidence in the integrity and correctness of the result of the "Read" operation, to the extent possible under the applicable DID method. This can be accomplished in a number of ways, such as the following:
An unverifiable read does not have such guarantees and is therefore less desirable, for example:
Whether or not a verifiable read is possible depends not only on a DID method itself, but also on the way a DID resolver implements that DID method. DID methods MAY allow multiple ways of implementing their "Read" operation, and SHOULD offer guidance regarding at least one way to implement a verifiable read.
The guarantees associated with a verifiable read are always limited by the architecture(s), protocol(s), cryptographic element(s), and other aspects of the DID method's underlying verifiable data registry. The forms of verifiable read implementation that are considered strongest are those that require no interaction with any remote network (for example, see [[DID-KEY]]), and those that minimize dependencies on specific network infrastructure, reducing the "root of trust" to proven entropy and cryptography (for example, see [[KERI]]).
To enable verifiable reads, many DID methods use digital signatures, state proofs, proofs of inclusion in Merkle trees, cryptographic event logs, or other types of proofs. If a DID method uses such proofs, it MUST specify in its DID method specification how they are used for verification of the correctness of the result of a "Read" operation.
A DID method MAY also include such proofs in the DID document itself, or
in a proof property of the
DID document metadata.
This can potentially enable a client to independently verify the results of a
DID Resolution process, even if it does not trust the DID resolver.
Note that proofs originating from the DID method are DID method-specific and must be understood within the technology of the applicable DID method. A simple signature on a DID document or DID document metadata does not necessarily prove control of a DID, nor guarantee that the DID document is the correct one for the DID. These proofs help to verify the integrity and authenticity of the results of a DID Resolution process as far as the DID method itself is concerned. However, they do not guarantee that the binding between a client and the DID resolver is secure. See also .
The algorithms for DID resolution and DID URL dereferencing are defined as abstract functions (see and ).
Those algorithms are implemented by DID resolvers and DID URL dereferencers, which are invoked by a client via a binding. Bindings define how the abstract functions are accessed using concrete programming or communication interfaces.
Examples of bindings include the following:
Based on the above considerations combined with the nature of the binding, the interaction between a client and the DID resolver or DID URL dereferencer could be considered either a local binding or a remote binding:
Whenever possible, local bindings are preferred, as they minimize dependencies on third parties and intermediaries, reduce security risks, and maximize confidence in the integrity and correctness of the results of the DID resolution and DID URL dereferencing functions.
In some cases, it might not be possible to use a local binding; for example, in constrained IoT (Internet of Things) environments, or when a DID method requires complex infrastructure, or when many different DID methods should be supported.
If a client uses a remote binding, the following considerations apply:
A DID resolver MAY also include proofs
in a proof property of the
DID resolution metadata.
This inclusion can potentially enable a client to independently verify the results of a
DID Resolution process, as long as it trusts the DID resolver.
Note that proofs originating from a DID resolver are DID method-independent and can be universally applied by a DID resolver, across all DID methods. These proofs help to verify the integrity and authenticity of the results of a DID Resolution process as far as the DID resolver itself is concerned. However, they do not guarantee that the result from the "Read" operation of the applicable DID method is itself correct. See also .
A DID resolver MUST support the DID resolution algorithm for at least one DID method and MAY support it for multiple DID methods:
In this case, the above considerations in about verifiable read and unverifiable read implementations apply to each supported DID method individually.
A DID resolver MAY invoke another DID resolver, which serves as a proxy that executes the DID resolution algorithm as defined in .
The first DID resolver then acts as a client and chooses a suitable binding for invoking the second DID resolver. For example, a DID resolver may be invoked via a local binding (such as a command line tool), which in turn invokes another DID resolver via a remote binding (such as the HTTP(S) binding).
When using proxied resolution, a "downstream" resolver SHOULD preserve all DID resolution metadata and DID document metadata from an "upstream" resolver in a transparent manner, including any proofs that may be present. In this process, the "downstream" resolver MAY add its own DID resolution metadata, including any metadata about the proxied resolution process itself.
This is similar to a "stub resolver" invoking a "recursive resolver" in DNS architecture, although the concepts are not entirely comparable (DNS Resolution uses a single concrete protocol, whereas DID resolution is an abstract function realized by different DID methods and different bindings).
Different parts of the DID URL dereferencing algorithm may be performed by different components of a Resolver Architecture.
Specifically, when a DID URL with a DID fragment is dereferenced, then dereferencing the resource is done by the DID resolver, and dereferencing the fragment is done by the client.
Given the DID URL did:xyz:1234#keys-1, a DID resolver could be invoked
via local binding
for dereferencing the resource (i.e., the DID document),
and the client could complete the DID URL dereferencing algorithm by
dereferencing the fragment (i.e., a part of the DID document).
Given the DID URL did:xyz:1234?service=agent&relativeRef=%2Fsome%2Fpath%3Fquery#frag, a DID resolver could be invoked
for dereferencing the resource (i.e., a service endpoint URL),
and the client could complete the DID URL dereferencing algorithm by
dereferencing the fragment (i.e., a service endpoint URL with a fragment).
Given the DID URL did:xyz:1234#keys-1, a DID resolver could be invoked via
local binding, which invokes another DID resolver via remote binding
for dereferencing the resource (i.e., the DID document),
and the client could complete the DID URL dereferencing algorithm by
dereferencing the fragment (i.e., a part of the DID document).
This section defines a JSON data structure that represents the result of the algorithm described in . 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"
}
}
}
}
Need to define how this data structure works exactly, and whether it always contains a DID document or can also contain other results.
For certain data, it may be debatable whether it should be part of the DID document (i.e., data that describes the DID Subject), or whether it is metadata (i.e., data about the DID document or about the DID resolution process). For example the URL of the "Continuation DID document" in the BTCR method.
This section defines a JSON data structure that represents the result of the algorithm described in . A DID URL dereferencing result contains the content as well as DID URL dereferencing metadata and DID URL content metadata.
The media type of this data structure is defined to be `application/did-url-dereferencing`.
{
"content": {
"@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/"
}]
},
"didUrlDereferencingMetadata": {
"contentType": "application/did",
"retrieved": "2024-06-01T19:73:24Z",
},
"contentMetadata": {
"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:
accept input metadata property
is not supported by the DID method and/or DID resolver implementation.
See Section .
This section defines bindings for the abstract algorithms in sections and .
This section defines a DID resolver binding which exposes the DID resolution and/or DID URL dereferencing functions (including all resolution/dereferencing options and metadata) via an HTTP(S) endpoint. See .
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.
Using this binding, the DID resolution function (see ) and/or DID URL dereferencing function (see ) 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 , ORAccept HTTP request header to the value of the accept resolution option
to request only the didDocument value of the result.https://resolver.example/1.0/identifiers/did:example:1234?service=files&relativeRef=/resume.pdf
Accept HTTP request header to `application/did-url-dereferencing`
to request a complete , ORAccept HTTP request header to the value of the accept dereferencing option
to request only the contentStream value of the result.GET request on the request HTTP(S) URL. This invokes the DID resolution or
DID URL dereferencing 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
GET https://resolver.example/1.0/identifiers/did%3Aexample%3A1234%3Fservice%3Dfiles%26relativeRef%3D%2Fresume.pdf?option1=value1&option2=value2 HTTP/1.1 Accept: application/did-url-dereferencing
POST request on the request HTTP(S) URL. This invokes the DID resolution or
DID URL dereferencing 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"
}
POST https://resolver.example/1.0/identifiers/did:example:1234?service=files&relativeRef=/resume.pdf HTTP/1.1
Accept: application/did-url-dereferencing
{
"option1": "value1",
"option2": "value2"
}
| error | HTTP status code |
|---|---|
INVALID_DID
|
400
|
INVALID_DID_URL
|
400
|
INVALID_OPTIONS
|
400
|
NOT_FOUND
|
404
|
REPRESENTATION_NOT_SUPPORTED
|
406
|
INVALID_DID_DOCUMENT
|
500
|
METHOD_NOT_SUPPORTED
|
501
|
INVALID_PUBLIC_KEY
|
500
|
INVALID_PUBLIC_KEY_LENGTH
|
500
|
INVALID_PUBLIC_KEY_TYPE
|
500
|
UNSUPPORTED_PUBLIC_KEY_TYPE
|
501
|
INTERNAL_ERROR
|
500
|
| (any other value) |
500
|
true in the didDocumentMetadata or contentMetadata:
410.Content-Type HTTP response header is `application/did-resolution`:
200.Content-Type HTTP response header. Its value MUST be the value of the
contentType metadata property in the didResolutionMetadata (see ).Content-Type HTTP response header.Content-Type HTTP response header is `application/did-url-dereferencing`:
text/uri-list in the dereferencingMetadata:
303.Location header. The value of this header
MUST be the selected service endpoint URL.200.Content-Type HTTP response header. Its value MUST be the value of the
contentType metadata property in the dereferencingMetadata (see ).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": [{
...
}]
}
The dereference() function can be invoked over the HTTP(S) binding as follows:
GET https://resolver.example/1.0/identifiers/did:example:123?versionId=2 HTTP/1.1 Accept: application/did-url-dereferencing
The response is as follows:
HTTP 200 OK
Content-Type: application/did-url-dereferencing
{
"content": {
"@context": [ "https://www.w3.org/ns/did/v1.1" ],
"id": "did:example:123",
"verificationMethod": [{
...
}],
"service": [{
...
}]
},
"dereferencingMetadata": {
"contentType": "application/did"
},
"contentMetadata": {
...
}
}
The dereference() function can be invoked over the HTTP(S) binding as follows:
GET https://resolver.example/1.0/identifiers/did:example:123?versionId=2 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": [{
...
}]
}
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.
Explain that DIDs are not necessarily globally resolvable, such as pairwise or N-wise "peer" DIDs.
See [[RFC3339]]: URIs have a global scope and are interpreted consistently regardless of context, though the result of that interpretation may be in relation to the end-user's context.
An advanced idea is that the result of DID resolution could be contextual or depend on policies, see this comment.
A related topic is whether (parts of) DID document could be encrypted, e.g., w3c/did-core/issues/25. Also see the use of the fragment in the IPID DID method.
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:
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.
See corresponding open issue.
Perhaps we can re-use caching mechanisms of other protocols such as HTTP.
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.
There is discussion on the relationship between DID resolution and resolution of non-DID identifiers such as domain names, HTTP URIs, or e-mail addresses. This includes the questions how DIDs can be discovered from non-DID identifiers, and how links between identifiers can be verifiable.
When a DID resolver client dereferences identifiers and linked resources in a DID document —
especially fields like verificationMethod, controller,
or alsoKnownAs — it might encounter a resolution 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 resolver can
also encounter such a situation when dereferencing a DID URL that references
a service endpoint.
did:example:alice
└── verificationMethod.controller → did:example:bob
└── verificationMethod.controller → did:example:alice
DID resolvers 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.
TODO: Define privacy considerations for DID resolution
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 in order to limit the possibilities of correlation and profiling.
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 [[[DID]]] 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 [[[?DID]]] specification in the section related to the history of DIDs.