Try our Chrome extension
Easily add the current web-page from your browser directly into your changedetection.io tool, more great features coming soon!Changedetection.io needs your support!
You can help us by supporting changedetection.io on these platforms;
- Rate us at AlternativeTo.net
- Star us on GitHub
- Follow us at Twitter/X
- G2 Software reviews
- Check us out on LinkedIn
- And tell your friends and colleagues :)
The more popular changedetection.io is, the more time we can dedicate to adding amazing features!
Many thanks :)
changedetection.io team
Not yet seconds ago
False
Not yet seconds ago
2 days ago
| 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, [[[DID]]], which describes the underlying DID architecture in full detail. 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: 1. At least two independent interoperable implementations of every feature defined in the specification, where interoperability can be verified by passing open test suites, and two or more implementations interoperating with each other. In order to advance to Proposed Recommendation, each normative specification must have an open test suite of every feature defined in the specification. 2. For normative statements that are machine testable, at least two conforming implementations per feature. 3. For normative statements that are not machine testable, at least two demonstrations of implementation per feature. 4. Each of the independent implementations mentioned above support at least two DID methods which 1) have an open specification (freely available specification, freely implementable), and 2) are implemented interoperably by more than one of the independent implementations mentioned above. This means that there will exist at least two openly-specified DID methods that are each implemented by at least two independent implementations. 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. Introduction [=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. Implementer Overview 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 (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). 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. A conforming DID resolver is any algorithm realized as software and/or hardware that complies with the relevant normative statements in . A conforming network-based DID resolver is a [=conforming DID resolver=] that additionally complies with the normative statements in [[[#bindings-https]]]. A conforming DID URL dereferencer is any algorithm realized as software and/or hardware that complies with the relevant normative statements in . Audience 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. Use Cases 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: * A decentralized address book: By using DIDs as identifiers for people and organizations within an address book, the controllers of those DIDs can independently update the contents of their DID documents. Through DID resolution, these DIDs can be resolved to obtain the current state of the DID document for any given contact, enabling persistent stable identifiers with updatable services and verification material necessary for continued verifiable interactions. * Verifying a Verifiable Credential: Verifiable Credentials are signed by an issuer and given to a holder. The holder can then create a Verifiable Presentation that is presented to a verifier. By using DIDs to identify issuers and holders within a credential, an issuer enables a verifier to use DID resolution to resolve the DID documents of the identified issuers and holders to obtain the verification material necessary to verify the signatures on the Verifiable Presentation. * Auditability: DID resolution can be used to obtain the historical state of a DID document either at a specific point in time or for a specific version. This can be used to audit the historical verifiable actions of a DID controller; for example, the issuance of a verifiable receipt or the signing of a contract. * DID URL based resource retrieval: A DID controller can add service endpoints to their DID document that point to resources they control; for example, a profile picture. If DID URLs are used to reference these resources, web applications can use DID resolution and DID URL dereferencing to retrieve the current version of the resource(s). The DID URL can be used as a persistent, dereferenceable identifier for these resources, while the DID controller can independently change the resource over time. Terminology DID Parameters 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 . 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 or DID URL dereferencing options to a DID resolver or DID URL dereferencer. 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 during the dereferencing process. Datetime 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 . Additionally, timestamps used in DID Resolution MUST be adjusted to UTC without sub-second decimal precision. For example: 2020-12-20T19:17:47Z Query Normalization 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 (see ). 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 in the note on the distinction between DID parameters and resolution options. Percent-Encoding Normalization 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: 1. Percent-encoded octets that correspond to unreserved characters (as defined in RFC3986 Section 2.3: Unreserved Characters) can be decoded to their literal character form. 2. All remaining percent-encoded octets are best represented using uppercase hexadecimal digits (e.g., `%2F` rather than `%2f`). 3. Avoid decoding percent-encoded characters that are reserved delimiters within the query component (e.g., `%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 (see Dereferencing the Resource). Duplicate Parameter Handling 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 ), 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 ). 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). Canonicalization by DID Method The set of query parameters defined in 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: 1. Value format: The expected encoding, character set, and range of valid values for each parameter. 2. Parameter ordering: Whether the relative ordering of query parameters has semantic significance, and if so, what the canonical ordering is. In the absence of explicit guidance, it is reasonable to treat parameter ordering as insignificant when comparing DID URLs for logical equivalence. 3. Case sensitivity: Whether parameter names or values are case-sensitive. The parameter names defined in this specification are case-sensitive ASCII strings. In the absence of contrary guidance from a DID method specification, parameter values are best treated as case-sensitive. 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 , unless the applicable DID method specification defines a canonical parameter ordering with semantic significance. DID Resolution 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 . 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: did This is the DID to resolve. This input is REQUIRED and the value MUST be a conformant DID as defined in . resolutionOptions A metadata structure consisting of input options to the 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: didResolutionMetadata A metadata structure consisting of values relating to the results of the DID resolution process. This structure is REQUIRED, and in the case of an error in the resolution process, this MUST NOT be empty. This structure is further defined in . If the resolution is unsuccessful, this structure MUST contain an error property describing the error. See Section . didDocument If the resolution is successful, this MUST be a DID document that is capable of being represented in one of the conformant representations of the specification. The value of 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. didDocumentMetadata If the resolution is successful, this MUST be a metadata structure. This structure contains metadata about the DID document contained in the didDocument property. If the resolution is unsuccessful, this output MUST be an empty metadata structure. This structure is further defined in . DID Resolution Options 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 The media type of the caller's preferred representation of the DID document. The value MUST be expressed according to the `Accept` header value as defined in [[[RFC9110]]], 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. expandRelativeUrls A boolean flag which instructs a DID resolver to expand relative DID URLs in the DID document to absolute DID URLs conformant with DID URL Syntax. versionId See for the definition. versionTime See for the definition. DID Resolution Metadata 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: * Media type of the returned content (`contentType`). * Error object (`error`) (see Section ). * Proofs generated by the DID resolver, e.g., to establish trusted resolution (proof). * Duration of the DID resolution process. * Caching information (see Section ). * URLs, IP addresses, and/or other networking information about the verifiable data registry that was used during 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 metadata properties: contentType The Media Type of the returned 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. error An error data structure is defined in [[RFC9457]]. The errors defined by this specification can be found in Section . Additional errors SHOULD be registered in the DID Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]]. proof 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 represents a proof. The use of this property and the types of proofs are DID method-independent. DID Document Metadata 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: * Timestamps when the DID and its associated DID document were created or updated (e.g., `created`, `updated`, `nextUpdate`). * Versioning information about the DID document (e.g., `versionId`, `nextVersionId`). * Proofs added by the DID controller or generated by the DID method's verifiable data registry, which might be used to establish control authority or to enable verifiable resolution (e.g., `proof`). * Metadata about controllers, capabilities, delegations, etc. * Method-specific metadata, such as block number, index, transaction hash, number of confirmations, etc., of a record in the blockchain or other verifiable data registry. 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 DID document metadata SHOULD include a 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 . updated DID document metadata SHOULD include an 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 . 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. deactivated If a DID has been deactivated, DID document metadata MUST include this property with the boolean value true. If a DID has not been deactivated, this property is OPTIONAL, but if included, MUST have the boolean value false. nextUpdate DID document metadata MAY include a 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 . versionId DID document metadata SHOULD include a 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 DID document metadata MAY include a 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. equivalentId 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. canonicalId 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. proof 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 represents a proof. The use of this property and the types of proofs are DID method-specific. DID Resolution Algorithm A DID resolver implements the following DID resolution algorithm. 1. Validate that the input DID conforms to the `did` rule of the DID Syntax. If not, the DID resolver MUST return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#INVALID_DID 2. didDocument: null 3. didDocumentMetadata: «[ ]» 2. Determine whether the DID method of the input DID is supported by the DID resolver that implements this algorithm. If not, the DID resolver MUST return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#METHOD_NOT_SUPPORTED 2. didDocument: null 3. didDocumentMetadata: «[ ]» 3. Determine whether the input DID resolution options are supported by the DID resolver that implements this algorithm. If not, the DID resolver MUST return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#FEATURE_NOT_SUPPORTED 2. didDocument: null 3. didDocumentMetadata: «[ ]» 4. Determine whether the input DID resolution options are valid. If not, the DID resolver MUST return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#INVALID_OPTIONS 2. didDocument: null 3. didDocumentMetadata: «[ ]» 5. Obtain the DID document for the input DID by executing the Resolve operation, as defined by the input DID method: 1. If the input DID does not exist, return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#NOT_FOUND 2. didDocument: null 3. didDocumentMetadata: «[ ]» 2. If the input DID has been deactivated, return the following result: 1. didResolutionMetadata: «[ ... ]» 2. didDocument: null 3. didDocumentMetadata: «[ "deactivated" → true, ... ]» 3. Otherwise, the result of the Resolve operation is called the output DID document. This result MUST be represented in a conformant representation. 6. If the input DID resolution options contain the expandRelativeUrls option with a value of true: 1. Iterate over all services, verification methods, verification relationships and any extension-defined properties in the output DID document. 2. For each item, if the item is an object and the value of the id property is a relative DID URL, or if a verification relationship is a relative DID URL: 1. Resolve the relative DID URL to an absolute DID URL conformant with DID URL Syntax, according to the rules of section Relative DID URLs in [[[DID-CORE]]]. 3. Update the output DID document by replacing the relative DID URLs with the resolved absolute DID URLs. 7. Return the following result: 1. didResolutionMetadata: «[ ... ]» 2. didDocument: output DID document 3. didDocumentMetadata: «[ "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: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#INTERNAL_ERROR 2. didDocument: null 3. didDocumentMetadata: «[ ]» DID URL Dereferencing 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 Dereferencing Algorithm A visualization of the algorithm for Dereferencing a DID URL, described next. 1. Prepare for Resolution 2. Resolve the DID 3. Determine Handling Strategy 4. Invoke the Handler 5. Use the Handler Result Prepare for Resolution 1. Validate that the input DID URL conforms to the `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 2. Select a resolver that is capable of handling the DID's method. Implementers MUST enable users to choose the resolvers they trust for specific DID methods. It is expected that implementations will provide this through some configuration mechanism, the details of which are out of scope for this specification. 3. Extract the DID from the DID URL, e.g., the DID URL `did:ex:abc#key-1` contains the DID `did:ex:abc`. 4. Prepare DID resolution options. These may be promoted from DID URL query parameters or determined by the business rules of the context in which the DID URL is being dereferenced. It is the business context in which the client is executing the algorithm that determines whether or not any given query parameter should be promoted to a Resolution option. See the resolving algorithm for details about resolution options and their meaning. Resolve the DID 1. Call the resolve function on the selected resolver, passing the prepared resolution options and the DID, to obtain the authoritative DID document for the input DID URL. 2. Interpret the response to resolve to consider any errors or warnings. If appropriate, return without further processing and raise a [=DEREFERENCING_ERROR_RESOLUTION_ERROR=] that includes he error returned from the Resolve Operation. Otherwise, continue processing if the response provided enough information to do so. 3. Repeat as necessary until the final resolution result is returned. In cases when the initial result from resolution is incomplete or fails, the client may be able to adjust the resolution parameters and try again, based on the context in which dereferencing is occuring. For example, a resolver might require more input, or the client might heuristically attempt alternate resolver options to find a more appropriate DID document, such as requesting a version of the DID document from a particular point in time. Determine Handling Strategy 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. A flow chart visualization of the Determine Handling Strategy Algorithm described next. 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. 1. Services Step 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. 2. 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. 3. Document Properties 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. 4. 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. 5. 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. 6. Metadata 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. 7. Default DID Document Step If no other handler strategy has been determined, set the strategy to Return DID Document. Invoke the Handler 1. Execute the determined handler strategy using a handler that implements that strategy. If the client does not have a handler that implements the determined strategy, stop processing and raise an error [=DEREFERENCING_ERROR_HANDLER_NOT_FOUND=]. Use the Handler Result 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 1. displaying a returned resource, 2. applying a fragment identifier to a returned resource scrolling it into view within a display, 3. making the result available to the calling process, or 4. producing an error [=DEREFERENCING_ERROR_FAILED=] if dereferencing cannot be completed. 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. Service Selection Algorithm 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 1. Select the service from the DID document whose 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 [[[DID-CORE]]]. 2. If no service matches, stop further processing and raise an error [=DEREFERENCING_ERROR_SERVICE_NOT_FOUND=]; no service is selected. 3. If more than one service matches, stop further processing and raise an error [=DEREFERENCING_ERROR_MULTIPLE_MATCHING_SERVICES=]; no service is selected. 4. If a single service matches, that service is selected. Continue with the Services Step. Default Service Handler 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/"] ... }] 1. Select Service Endpoint If `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 dreferencing 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/" 2. Determine Resource Path Construct the resource path by extracting the non-matching part of the `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 resourchPath. resourcePath = /didimages/image.png 3. Normalize Path Normalize the resulting `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=]. 4. Construct Resource URLs Replace the path part in the selected serviceEndpoint with the Normalized Resource Path, leaving all other elements of the service endpoint URLs the same. ResourceUrl = https://example.com/didimages/image.png 5. Dereference Resource URL Dereference the resulting `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. PathHandler Path Matching Algorithm 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. 1. Of those objects with a type 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. Given 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. 2. If two or more objects have the same length match, stop processing and return an error [=DEREFERENCING_ERROR_MULTIPLE_MATCHING_PATH_HANDLERS=]. Return DID Document When invoking this handler, simply return the DID Document retrieved from Resolve, including any dereferencing errors that may have been raised. Dereferencing Errors Dereferencing may produce several distinct errors, described below. Clients SHOULD use these errors when appropriate. DEREFERENCING_ERROR_FAILED A generic or unclassified internal error occurred, causing the overall dereferencing process to fail. (Use the Handler Result) DEREFERENCING_ERROR_HANDLER_NOT_FOUND No handler is available for the indicated handling strategy. (Invoke the Handler) DEREFERENCING_ERROR_MULTIPLE_DOCUMENT_PROPERTIES The dereferencing process encountered multiple conflicting document properties when attempting to dereference the DID URL. (Document Properties Step) DEREFERENCING_ERROR_MULTIPLE_MATCHING_PATH_HANDLERS The dereferencing process found multiple distinct path handlers that match the requested path. (PathHandlers Step) DEREFERENCING_ERROR_MULTIPLE_METADATA_PROPERTIES Resolution Metadata contains multiple conflicting properties, preventing a definitive selection for dereferencing. (Metadata Step) DEREFERENCING_ERROR_MULTIPLE_QUERY_PARAMETERS The DID URL contains multiple, incompatible query parameters. (Query Parameters Step) DEREFERENCING_ERROR_MULTIPLE_SERVICE_PARAMETERS The DID URL contains multiple service parameters. (Sevices Parameter Step) DEREFERENCING_ERROR_MULTIPLE_MATCHING_SERVICES The dereferencing process identified multiple matching service endpoints based on the URL parameters, preventing an unambiguous selection. (Services Step, Service Selection Algorithm) DEREFERENCING_ERROR_NO_SERVICE_ENDPOINTS_SUCCEED Valid service endpoints were identified and network interactions were attempted, but none of the requests returned a successful response. (Default Service Handler) DEREFERENCE_ERROR_PATH_NORMALIZATION_ERROR The DID URL contains a path that normalizes to a URL outside the perview of the selected service endpoint. The DID URL path overwrote the path part of the service endpoint. (Default Service Handling Algorithm) DEREFERENCING_ERROR_PATH_HANDLER_HANDLER_NOT_DEFINED The DID URL contains a path and the DID Document contains a matching PathHandler object, but no appropriate handler is defined or registered within the dereferencing environment to process it. (PathHandlers Step) DEREFERENCING_ERROR_RESOLUTION_ERROR The dereferencing process failed because the underlying identifier resolution process encountered an error before dereferencing could be completed. (Resolve the DID) DEREFERENCING_ERROR_SERVICE_NOT_FOUND The specific service referenced during the dereferencing process (e.g., via a service query parameter) was not found in the resolved document. (Services Step) Metadata Structure 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. Numeric representations vary across platforms and serializations (for example, IEEE-754 floating-point vs. fixed-width integers vs. “bigint”/bignum types). The Infra standard does not yet provide comprehensive guidance for numbers. Implementers are advised to avoid metadata numbers that are likely to be represented differently on different platforms — notably the following: * non-integer values such as floating-point numbers or fractions * integers outside common fixed-width ranges, such as those larger than a 32-bit unsigned integer (maximum 232 - 1 or 4,294,967,295) Where such values are needed for interoperability, a good practice for property is definitions to use a canonical string serialization (for example, a string formatted as a floating-point number using a clearly defined precision and rounding strategy) and to document any expected range or format. 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": "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" ]» DID Resolution Architectures This section is currently marked as [=at risk=]. Method Architectures The DID resolution algorithm involves executing the Resolve 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: * A DID method might use an immutable blockchain, distributed ledger, distributed file system, peer-to-peer network, or other decentralized infrastructure as (part of) its verifiable data registry. * A DID method might use DNS, HTTP, or web servers as (part of) its verifiable data registry. * A DID method might use any combination of the above technical infrastructures. * A DID method might store an actual DID document in plain-text form in a verifiable data registry and might simply retrieve that document during the "Resolve" operation. * A DID method might define its "Resolve" operation in a more complex way that could involve intermediate, partial, or temporary DID documents, and use multi-step processes that construct the DID document "on-the-fly". * A DID method might require interaction with remote servers or networks during execution of the "Resolve" operation. * A DID method might execute the "Resolve" operation in an entirely local way that does not require any interaction with remote servers or networks. For example, in the [[?DID-KEY]] method, the DID itself wraps a public key, and the "Resolve" operation is simply a trivial, local transformation process. Based on the above considerations combined with the nature of a DID method's "Resolve" operation, the interaction between a DID resolver and the verifiable data registry could be considered either a verifiable resolution or an unverifiable resolution: A verifiable resolution implementation of a DID method. An unverifiable resolution implementation of a DID method. A verifiable resolution maximizes confidence in the integrity and correctness of the result of the "Resolve" operation, to the extent possible under the applicable DID method. This can be accomplished in a number of ways, such as the following: * A verifiable resolution can be accomplished if access to the verifiable data registry is possible in a local, trusted network environment. + For example, in blockchain-based DID methods, a verifiable resolution might be accomplished if a blockchain full node is deployed on a local server. * If access to the verifiable data registry happens via a remote server, a verifiable resolution might still be accomplished if the remote server is trusted, and if it can be accessed via a secure channel. * If access to the verifiable data registry happens via a remote server, a verifiable resolution might be accomplished if the DID resolver has some way of verifying the DID document and DID document metadata returned by the DID method. + For example, in blockchain-based DID methods, even if direct access to a blockchain full node is not available, a verifiable resolution may still be possible by using a light client that processes metadata to verify the data. An unverifiable resolution does not have such guarantees and is therefore less desirable, for example: * An unverifiable resolution takes place if access to the verifiable data registry happens via a remote, untrusted intermediary. + For example, in the case of blockchain-based DID methods, a remote blockchain explorer API operated by an third party may be used to look up data from the blockchain. Whether or not a verifiable resolution 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 "Resolve" operation, and SHOULD offer guidance regarding at least one way to implement a verifiable resolution. The guarantees associated with a verifiable resolution 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 resolution 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 resolutions, many DID methods use digital signatures, state proofs, proofs of inclusion in Merkle trees, cryptographic event logs, or other types of proof. 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 "Resolve" 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 . Resolver Architectures 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: * A DID resolver might be invoked within an application by calling a software library or SDK. * A DID resolver might be invoked as a command line tool. * A DID resolver might be invoked over an HTTP(S) API or other network protocol, e.g., see . 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: A local binding for a DID resolver. A remote binding for a DID resolver. 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: * The remote binding SHOULD use a trusted instance of a DID resolver, ideally under the control of the client itself (e.g., self-hosted). * The remote binding SHOULD use a secure channel such as VPN and/or TLS with mutual authentication. * The client could query multiple DID resolvers over a remote binding and compare results. A DID resolver MAY also include proofs in a proof property of the DID resolution metadata. 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 "Resolve" operation of the applicable DID method is itself correct. See also . Multiple Methods A DID resolver might support the DID resolution algorithm for multiple DID methods: A DID resolver that supports multiple DID methods. In this case, the above considerations in about verifiable resolution and unverifiable resolution implementations apply to each supported DID method individually. Proxied Resolution 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. A client invokes a DID resolver via local binding, which invokes another DID resolver via remote binding, which in turn executes the resolution operation of the DID method. 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). Client-Side Dereferencing 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. Examples 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). Client-side dereferencing of a DID URL by a DID resolver and a client. 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 [=DID service endpoint=] URL), and the client could complete the DID URL dereferencing algorithm by Dereferencing the Fragment (i.e., a [=DID service endpoint=] URL with a fragment). Client-side dereferencing of a DID URL by a DID resolver and a client. 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). Client-side dereferencing (in combination with Proxied Resolution) of a DID URL by two DID resolvers and a client. DID Resolution Result 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`. Example { "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" } } } } DID URL Dereferencing Result This section is currently marked as [=at risk=] and may be heavily modified or removed during the Candidate Recommendation phase. 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`. Example { "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" } } } } Errors 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: * The `type` value of the error object MUST be a URL. Where the values listed in the section below do not define a URL, the values MUST be prepended with the URL `https://www.w3.org/ns/did#`. * The `title` value SHOULD provide a short but specific human-readable string for the error. * The `detail` value SHOULD provide a longer human-readable string for the error. A specification that defines an error type not defined in this section MAY declare that it refines one of the error types defined in this section. A binding defined in Section can use such a declaration to determine how to convey that error type. INVALID_DID An invalid DID was detected during DID Resolution. See Section . https://www.w3.org/ns/did#INVALID_DID INVALID_DID_DOCUMENT The [=DID document=] was malformed. See Section . https://www.w3.org/ns/did#INVALID_DID_DOCUMENT NOT_FOUND The DID resolver was unable to find the DID document resulting from this resolution request. See Section . https://www.w3.org/ns/did#NOT_FOUND REPRESENTATION_NOT_SUPPORTED The representation requested via the accept DID URL dereferencing option is not supported by the DID method and/or DID URL dereferencer implementation. See Section . https://www.w3.org/ns/did#REPRESENTATION_NOT_SUPPORTED INVALID_DID_URL An invalid DID URL was detected during DID URL dereferencing. See Section https://www.w3.org/ns/did#INVALID_DID_URL METHOD_NOT_SUPPORTED The DID method of the DID is not supported by the DID resolver. See Section . https://www.w3.org/ns/did#METHOD_NOT_SUPPORTED INVALID_OPTIONS One or more of the options provided for DID Resolution or DID URL dereferencing are invalid. https://www.w3.org/ns/did#INVALID_OPTIONS INTERNAL_ERROR An unexpected error occured during DID Resolution or DID URL dereferencing. https://www.w3.org/ns/did#INTERNAL_ERROR FEATURE_NOT_SUPPORTED The DID resolver does not support the requested feature. The value of the `detail` 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 Bindings This section defines bindings for the abstract algorithm in section . HTTP(S) Binding This section defines a DID resolver binding which exposes the DID resolution function (including all resolution options and metadata) via an HTTP(S) endpoint. See . 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 ) can be executed as follows: 1. Initialize a request HTTP(S) URL with the DID resolver HTTP(S) endpoint. https://resolver.example/1.0/identifiers/ 2. For the DID resolution function: 1. Append the input DID to the request HTTP(S) URL. https://resolver.example/1.0/identifiers/did:example:1234 2. Set the Accept HTTP request header to `application/did-resolution` to request a complete , OR 3. set the Accept HTTP request header to the value of the accept resolution option to request only the didDocument value of the result. 3. For the HTTP(S) GET binding: 1. If any other resolution options than accept are provided: 1. The input DID MUST be URL-encoded (as specified in RFC3986 Section 2.1). 2. Encode all resolution options except accept as query parameters in the request HTTP(S) URL. 2. Execute an HTTP 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 4. For the HTTP(S) POST binding: 1. If any other resolution options than accept are provided: 1. Encode all resolution options except accept as a JSON structure in the HTTP request's POST body. 2. Execute an HTTP 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" } 5. If the DID resolution function returns an error metadata property in the didResolutionMetadata, then the HTTP response status code MUST correspond to the type property of the error object, according to the following table: 5. error type URI HTTP status code https://www.w3.org/ns/did#INVALID_DID 400 https://www.w3.org/ns/did#INVALID_DID_URL 400 https://www.w3.org/ns/did#INVALID_OPTIONS 400 https://www.w3.org/ns/did#NOT_FOUND 404 https://www.w3.org/ns/did#REPRESENTATION_NOT_SUPPORTED 406 https://www.w3.org/ns/did#INVALID_DID_DOCUMENT 500 https://www.w3.org/ns/did#METHOD_NOT_SUPPORTED 501 https://www.w3.org/ns/did#FEATURE_NOT_SUPPORTED 501 https://www.w3.org/ns/did#INTERNAL_ERROR 500 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. 6. If the DID resolution function returns a deactivated metadata property with the value true in the didDocumentMetadata: 1. The HTTP response status code MUST be 410. 7. For the DID resolution function: 1. If the value of the Content-Type HTTP response header is `application/did-resolution`: 1. The HTTP body MUST contain a DID resolution result (see ) that is the result of the DID resolution function. 2. If the function is successful and returns a didDocument: 1. The HTTP response status code MUST be 200. 2. The HTTP response MUST contain a Content-Type HTTP response header. Its value MUST be the value of the contentType metadata property in the didResolutionMetadata (see ). 3. The HTTP response body MUST contain the didDocument that is the result of the DID resolution function, in the representation corresponding to the Content-Type HTTP response header. See here for an OpenAPI definition corresponding to the HTTP(S) binding. DID Resolution Examples 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 Example: Returning a DID Resolution Result 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": { ... } } Example: Returning a DID Document 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": [{ ... }] } Security Considerations 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. Authentication/Authorization 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. Caching 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. JSON-LD Context Integrity 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. Versioning 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. VDR Network Forks 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. Dereferencing Cycles 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: * Infinite loops or stack overflows in software. * Resource exhaustion (e.g., memory, network, or CPU). * Denial-of-service (DoS) vulnerabilities in clients or intermediaries. 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. Query String Normalization and Injection Risks The query component of a DID URL is used to pass DID parameters that affect resolution and dereferencing behavior (see ). Several aspects of query string handling carry security implications that implementers are advised to consider carefully. Path Traversal via `relativeRef` 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 (see ). 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: * Literal dot-dot-slash: `../` * Percent-encoded variants: `%2E%2E%2F`, `%2E%2E/`, .`%2E/`, `%2E./` * Doubly-encoded variants: `%252E%252E%252F` * Platform-specific variants (e.g., `..\` on Windows-derived path libraries) Implementers are encouraged to: * Normalize the resolved path after applying the RFC3986 Section 5 Reference Resolution algorithm, and verify that the resulting path does not traverse above the base path of the service endpoint URL. * Treat `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 ). * Apply normalization and validation after full percent-decoding, to guard against encoded traversal variants. Superficial string matching (e.g., checking only for the literal string `../`) 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 . Normalization Inconsistency as a Cache Bypass Vector As described in , the same logical DID URL can be represented by multiple syntactically distinct strings. In a proxied or multi-component resolution architecture (see ), different components can apply different normalization rules (or no normalization at all). An attacker aware of normalization inconsistencies between components could: * Construct a DID URL that is served from cache by one component but re-dereferenced from the verifiable data registry by another, potentially bypassing content integrity checks associated with cached responses. * Cause two logically identical DID URLs to be cached as distinct entries, inflating cache size and potentially enabling cache exhaustion. * Exploit differing duplicate-parameter handling between a caching proxy and an upstream resolver to inject unexpected parameter values into a resolution request. To mitigate these risks, implementers are encouraged to: 1. Apply query string normalization (per ) at the outermost entry point of the resolution pipeline, before any caching or forwarding occurs. 2. Use the normalized form of the DID URL as the cache key, and document the normalization algorithm applied. 3. Avoid assuming that a DID URL received from an upstream component has already been normalized; applying independent normalization before processing is a safer approach. Parameter Injection via Concatenation 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 ), in the applicable DID method specification, or in the DID Document Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]]. Privacy Considerations 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. Profiling of DID Resolution and Dereferencing Requesters 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. Method specific considerations 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. Relationship to Other Technologies 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. DID Resolution Resources 1. DID resolvers in DID Core specification 2. Universal Resolver 3. did-client 4. uPort DID resolver Revision History 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: * HTTP Status Codes for Other Error Types: The HTTP(S) Binding no longer requires a 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. * DID URL Dereferencing over HTTP(S): The HTTP(S) Binding, its examples and its OpenAPI definition no longer cover DID URL dereferencing, and the conformance class of a network-based DID URL dereferencer is removed. Changes since the First Public Working Draft include: * Document Scope and Structure Additions + Title and Authorship: The title was simplified to "Decentralized Identifier Resolution (DID Resolution) v1," and new editors (Stephen Curran, Joe Andrieu) were added. + Contextual Sections: The CR adds new, non-normative introductory sections for "Implementer Overview," "Audience," and "Use Cases" to provide better context for developers and architects. + Conformance Categories: The CR introduces two new conformance categories specifically for network-based implementations: "conforming network-based DID resolver" and "conforming network-based DID URL dereferencer". * Resolution Interface and Algorithms + Abstract Interface Simplification: The FPWD defined two distinct abstract functions: 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. + Relative URL Expansion: The CR introduces a new DID resolution option called expandRelativeUrls. When set to true, the resolver will automatically expand any relative DID URLs found within the DID document into absolute DID URLs. + DID Parameters and Normalization: The CR expands upon DID parameters by formally defining the behaviors of 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. + Datetime Standardization: The CR imposes a strict format for all datetime values (such as versionTime, created, and updated), requiring them to be XML Datetime strings adjusted to UTC without sub-second precision. * DID URL Dereferencing Changes + Feature at Risk: The CR explicitly flags the entire "DID URL Dereferencing" section and its corresponding data result structures as "at risk," noting that it may be heavily modified or removed. + Provisional Algorithm: Because of the "at risk" status, the CR introduces a "PROVISIONAL - DID URL Dereferencing" section that explores a modular, alternative approach based on sequential "handling strategies". + Verification Relationships: The CR adds 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. + Service Endpoint Construction Removal: The standalone algorithm for "Service Endpoint Construction" (Section 11 in the FPWD) was removed from the CR version. * Error Handling and Extensibility + RFC9457 Error Formats: Instead of using simple single-keyword ASCII strings for errors like the FPWD, the CR mandates the use of RFC9457 (Problem Details for HTTP APIs). + Error URIs: Error types in the CR are now mapped to specific W3C URIs (e.g., https://www.w3.org/ns/did#INVALID_DID), and new errors such as INVALID_DID_DOCUMENT and FEATURE_NOT_SUPPORTED were introduced. + Shift to Extensions: The CR shifts references for metadata and options registration away from the "DID Specification Registries" used in the FPWD, advising implementers to use the "DID Resolution Extensions" and "DID Document Properties Extensions" instead. * Expanded Security and Privacy Considerations + New Security Vectors: The CR vastly expands the Security Considerations section to address vulnerabilities such as: o Dereferencing Cycles: Risks of infinite loops or resource exhaustion when following nested DID document references. o Query String/Parameter Injection: Vulnerabilities arising from inconsistent cache normalization or unsafe programmatic string concatenation. o Path Traversal: Risks of an attacker escaping a service endpoint's intended path using malicious relativeRef parameter sequences (e.g., ../). o JSON-LD Integrity & Network Forks: Guidance on validating JSON-LD Context files and handling VDR (verifiable data registry) network forks. + New Privacy Section: The CR introduces a standalone "Privacy Considerations" section, highlighting the risk that DID resolvers and dereferencers can log and profile clients requesting resolution, advising mitigation strategies like using trusted proxies or Oblivious HTTP. | 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, [[[DID]]], which describes the underlying DID architecture in full detail. 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: 1. At least two independent interoperable implementations of every feature defined in the specification, where interoperability can be verified by passing open test suites, and two or more implementations interoperating with each other. In order to advance to Proposed Recommendation, each normative specification must have an open test suite of every feature defined in the specification. 2. For normative statements that are machine testable, at least two conforming implementations per feature. 3. For normative statements that are not machine testable, at least two demonstrations of implementation per feature. 4. Each of the independent implementations mentioned above support at least two DID methods which 1) have an open specification (freely available specification, freely implementable), and 2) are implemented interoperably by more than one of the independent implementations mentioned above. This means that there will exist at least two openly-specified DID methods that are each implemented by at least two independent implementations. 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. Introduction [=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. Implementer Overview 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. A conforming DID resolver is any algorithm realized as software and/or hardware that complies with the relevant normative statements in . A conforming network-based DID resolver is a [=conforming DID resolver=] that additionally complies with the normative statements in [[[#bindings-https]]]. A conforming DID URL dereferencer is any algorithm realized as software and/or hardware that complies with the relevant normative statements in . Audience 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. Use Cases 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: * A decentralized address book: By using DIDs as identifiers for people and organizations within an address book, the controllers of those DIDs can independently update the contents of their DID documents. Through DID resolution, these DIDs can be resolved to obtain the current state of the DID document for any given contact, enabling persistent stable identifiers with updatable services and verification material necessary for continued verifiable interactions. * Verifying a Verifiable Credential: Verifiable Credentials are signed by an issuer and given to a holder. The holder can then create a Verifiable Presentation that is presented to a verifier. By using DIDs to identify issuers and holders within a credential, an issuer enables a verifier to use DID resolution to resolve the DID documents of the identified issuers and holders to obtain the verification material necessary to verify the signatures on the Verifiable Presentation. * Auditability: DID resolution can be used to obtain the historical state of a DID document either at a specific point in time or for a specific version. This can be used to audit the historical verifiable actions of a DID controller; for example, the issuance of a verifiable receipt or the signing of a contract. * DID URL based resource retrieval: A DID controller can add service endpoints to their DID document that point to resources they control; for example, a profile picture. If DID URLs are used to reference these resources, web applications can use DID resolution and DID URL dereferencing to retrieve the current version of the resource(s). The DID URL can be used as a persistent, dereferenceable identifier for these resources, while the DID controller can independently change the resource over time. Terminology DID Parameters 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 . 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. Datetime 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 . Additionally, timestamps used in DID Resolution MUST be adjusted to UTC without sub-second decimal precision. For example: 2020-12-20T19:17:47Z Query Normalization 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 (see ). 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 in the note on the distinction between DID parameters and resolution options. Percent-Encoding Normalization 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: 1. Percent-encoded octets that correspond to unreserved characters (as defined in RFC3986 Section 2.3: Unreserved Characters) can be decoded to their literal character form. 2. All remaining percent-encoded octets are best represented using uppercase hexadecimal digits (e.g., `%2F` rather than `%2f`). 3. Avoid decoding percent-encoded characters that are reserved delimiters within the query component (e.g., `%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. Duplicate Parameter Handling 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 ), 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 ). 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). Canonicalization by DID Method The set of query parameters defined in 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: 1. Value format: The expected encoding, character set, and range of valid values for each parameter. 2. Parameter ordering: Whether the relative ordering of query parameters has semantic significance, and if so, what the canonical ordering is. In the absence of explicit guidance, it is reasonable to treat parameter ordering as insignificant when comparing DID URLs for logical equivalence. 3. Case sensitivity: Whether parameter names or values are case-sensitive. The parameter names defined in this specification are case-sensitive ASCII strings. In the absence of contrary guidance from a DID method specification, parameter values are best treated as case-sensitive. 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 , unless the applicable DID method specification defines a canonical parameter ordering with semantic significance. DID Resolution 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 . 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: did This is the DID to resolve. This input is REQUIRED and the value MUST be a conformant DID as defined in . resolutionOptions A metadata structure consisting of input options to the 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: didResolutionMetadata A metadata structure consisting of values relating to the results of the DID resolution process. This structure is REQUIRED, and in the case of an error in the resolution process, this MUST NOT be empty. This structure is further defined in . If the resolution is unsuccessful, this structure MUST contain an error property describing the error. See Section . didDocument If the resolution is successful, this MUST be a DID document that is capable of being represented in one of the conformant representations of the specification. The value of 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. didDocumentMetadata If the resolution is successful, this MUST be a metadata structure. This structure contains metadata about the DID document contained in the didDocument property. If the resolution is unsuccessful, this output MUST be an empty metadata structure. This structure is further defined in . DID Resolution Options 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 The media type of the caller's preferred representation of the DID document. The value MUST be expressed according to the `Accept` header value as defined in [[[RFC9110]]], 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. expandRelativeUrls A boolean flag which instructs a DID resolver to expand relative DID URLs in the DID document to absolute DID URLs conformant with DID URL Syntax. versionId See for the definition. versionTime See for the definition. DID Resolution Metadata 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: * Media type of the returned content (`contentType`). * Error object (`error`) (see Section ). * Proofs generated by the DID resolver, e.g., to establish trusted resolution (proof). * Duration of the DID resolution process. * Caching information (see Section ). * URLs, IP addresses, and/or other networking information about the verifiable data registry that was used during 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 metadata properties: contentType The Media Type of the returned 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. error An error data structure is defined in [[RFC9457]]. The errors defined by this specification can be found in Section . Additional errors SHOULD be registered in the DID Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]], together with the URL that their defining specification gives them (see Section ). proof 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 represents a proof. The use of this property and the types of proofs are DID method-independent. DID Document Metadata 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: * Timestamps when the DID and its associated DID document were created or updated (e.g., `created`, `updated`, `nextUpdate`). * Versioning information about the DID document (e.g., `versionId`, `nextVersionId`). * Proofs added by the DID controller or generated by the DID method's verifiable data registry, which might be used to establish control authority or to enable verifiable resolution (e.g., `proof`). * Metadata about controllers, capabilities, delegations, etc. * Method-specific metadata, such as block number, index, transaction hash, number of confirmations, etc., of a record in the blockchain or other verifiable data registry. 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 DID document metadata SHOULD include a 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 . updated DID document metadata SHOULD include an 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 . 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. deactivated If a DID has been deactivated, DID document metadata MUST include this property with the boolean value true. If a DID has not been deactivated, this property is OPTIONAL, but if included, MUST have the boolean value false. nextUpdate DID document metadata MAY include a 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 . versionId DID document metadata SHOULD include a 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 DID document metadata MAY include a 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. equivalentId 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. canonicalId 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. proof 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 represents a proof. The use of this property and the types of proofs are DID method-specific. DID Resolution Algorithm A DID resolver implements the following DID resolution algorithm. 1. Validate that the input DID conforms to the `did` rule of the DID Syntax. If not, the DID resolver MUST return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#INVALID_DID 2. didDocument: null 3. didDocumentMetadata: «[ ]» 2. Determine whether the DID method of the input DID is supported by the DID resolver that implements this algorithm. If not, the DID resolver MUST return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#METHOD_NOT_SUPPORTED 2. didDocument: null 3. didDocumentMetadata: «[ ]» 3. Determine whether the input DID resolution options are supported by the DID resolver that implements this algorithm. If not, the DID resolver MUST return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#FEATURE_NOT_SUPPORTED 2. didDocument: null 3. didDocumentMetadata: «[ ]» 4. Determine whether the input DID resolution options are valid. If not, the DID resolver MUST return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#INVALID_OPTIONS 2. didDocument: null 3. didDocumentMetadata: «[ ]» 5. Obtain the DID document for the input DID by executing the Resolve operation, as defined by the input DID method: 1. If the input DID does not exist, return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#NOT_FOUND 2. didDocument: null 3. didDocumentMetadata: «[ ]» 2. If the input DID has been deactivated, return the following result: 1. didResolutionMetadata: «[ ... ]» 2. didDocument: null 3. didDocumentMetadata: «[ "deactivated" → true, ... ]» 3. Otherwise, the result of the Resolve operation is called the output DID document. This result MUST be represented in a conformant representation. 6. If the input DID resolution options contain the expandRelativeUrls option with a value of true: 1. Iterate over all services, verification methods, verification relationships and any extension-defined properties in the output DID document. 2. For each item, if the item is an object and the value of the id property is a relative DID URL, or if a verification relationship is a relative DID URL: 1. Resolve the relative DID URL to an absolute DID URL conformant with DID URL Syntax, according to the rules of section Relative DID URLs in [[[DID-CORE]]]. 3. Update the output DID document by replacing the relative DID URLs with the resolved absolute DID URLs. 7. Return the following result: 1. didResolutionMetadata: «[ "contentType" → output DID document media type, ... ]» 2. didDocument: output DID document 3. didDocumentMetadata: «[ ... ]» If the DID resolver encounters any unexpected errors during the execution of the DID Resolution algorithm, it MUST return the following result: 1. didResolutionMetadata: error object with type set to https://www.w3.org/ns/did#INTERNAL_ERROR 2. didDocument: null 3. didDocumentMetadata: «[ ]» DID URL Dereferencing 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 Dereferencing Algorithm A visualization of the algorithm for Dereferencing a DID URL, described next. 1. Prepare for Resolution 2. Resolve the DID 3. Determine Handling Strategy 4. Invoke the Handler 5. Use the Handler Result Prepare for Resolution 1. Validate that the input DID URL conforms to the `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 2. Select a resolver that is capable of handling the DID's method. Implementers MUST enable users to choose the resolvers they trust for specific DID methods. It is expected that implementations will provide this through some configuration mechanism, the details of which are out of scope for this specification. 3. Extract the DID from the DID URL, e.g., the DID URL `did:ex:abc#key-1` contains the DID `did:ex:abc`. 4. Prepare DID resolution options. These may be promoted from DID URL query parameters or determined by the business rules of the context in which the DID URL is being dereferenced. It is the business context in which the client is executing the algorithm that determines whether or not any given query parameter should be promoted to a Resolution option. See the resolving algorithm for details about resolution options and their meaning. Resolve the DID 1. Call the resolve function on the selected resolver, passing the prepared resolution options and the DID, to obtain the authoritative DID document for the input DID URL. 2. Interpret the response to resolve to consider any errors or warnings. If appropriate, return without further processing and raise a [=DEREFERENCING_ERROR_RESOLUTION_ERROR=] that includes he error returned from the Resolve Operation. Otherwise, continue processing if the response provided enough information to do so. 3. Repeat as necessary until the final resolution result is returned. In cases when the initial result from resolution is incomplete or fails, the client may be able to adjust the resolution parameters and try again, based on the context in which dereferencing is occuring. For example, a resolver might require more input, or the client might heuristically attempt alternate resolver options to find a more appropriate DID document, such as requesting a version of the DID document from a particular point in time. Determine Handling Strategy 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. A flow chart visualization of the Determine Handling Strategy Algorithm described next. 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. 1. Services Step 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. 2. 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. 3. Document Properties 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. 4. 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. 5. 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. 6. Metadata 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. 7. Default DID Document Step If no other handler strategy has been determined, set the strategy to Return DID Document. Invoke the Handler 1. Execute the determined handler strategy using a handler that implements that strategy. If the client does not have a handler that implements the determined strategy, stop processing and raise an error [=DEREFERENCING_ERROR_HANDLER_NOT_FOUND=]. Use the Handler Result 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 1. displaying a returned resource, 2. applying a fragment identifier to a returned resource scrolling it into view within a display, 3. making the result available to the calling process, or 4. producing an error [=DEREFERENCING_ERROR_FAILED=] if dereferencing cannot be completed. 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. Service Selection Algorithm 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 1. Select the service from the DID document whose 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 [[[DID-CORE]]]. 2. If no service matches, stop further processing and raise an error [=DEREFERENCING_ERROR_SERVICE_NOT_FOUND=]; no service is selected. 3. If more than one service matches, stop further processing and raise an error [=DEREFERENCING_ERROR_MULTIPLE_MATCHING_SERVICES=]; no service is selected. 4. If a single service matches, that service is selected. Continue with the Services Step. Default Service Handler 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/"] ... }] 1. Select Service Endpoint If `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/" 2. Determine Resource Path Construct the resource path by extracting the non-matching part of the `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 3. Normalize Path Normalize the resulting `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=]. 4. Construct Resource URLs Replace the path part in the selected serviceEndpoint with the Normalized Resource Path, leaving all other elements of the service endpoint URLs the same. ResourceUrl = https://example.com/didimages/image.png 5. Dereference Resource URL Dereference the resulting `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. PathHandler Path Matching Algorithm 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. 1. Of those objects with a type 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. Given 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. 2. If two or more objects have the same length match, stop processing and return an error [=DEREFERENCING_ERROR_MULTIPLE_MATCHING_PATH_HANDLERS=]. Return DID Document When invoking this handler, simply return the DID Document retrieved from Resolve, including any dereferencing errors that may have been raised. Dereferencing Errors Dereferencing may produce several distinct errors, described below. Clients SHOULD use these errors when appropriate. DEREFERENCING_ERROR_FAILED A generic or unclassified internal error occurred, causing the overall dereferencing process to fail. (Use the Handler Result) DEREFERENCING_ERROR_HANDLER_NOT_FOUND No handler is available for the indicated handling strategy. (Invoke the Handler) DEREFERENCING_ERROR_MULTIPLE_DOCUMENT_PROPERTIES The dereferencing process encountered multiple conflicting document properties when attempting to dereference the DID URL. (Document Properties Step) DEREFERENCING_ERROR_MULTIPLE_MATCHING_PATH_HANDLERS The dereferencing process found multiple distinct path handlers that match the requested path. (PathHandlers Step) DEREFERENCING_ERROR_MULTIPLE_METADATA_PROPERTIES Resolution Metadata contains multiple conflicting properties, preventing a definitive selection for dereferencing. (Metadata Step) DEREFERENCING_ERROR_MULTIPLE_QUERY_PARAMETERS The DID URL contains multiple, incompatible query parameters. (Query Parameters Step) DEREFERENCING_ERROR_MULTIPLE_SERVICE_PARAMETERS The DID URL contains multiple service parameters. (Sevices Parameter Step) DEREFERENCING_ERROR_MULTIPLE_MATCHING_SERVICES The dereferencing process identified multiple matching service endpoints based on the URL parameters, preventing an unambiguous selection. (Services Step, Service Selection Algorithm) DEREFERENCING_ERROR_NO_SERVICE_ENDPOINTS_SUCCEED Valid service endpoints were identified and network interactions were attempted, but none of the requests returned a successful response. (Default Service Handler) DEREFERENCE_ERROR_PATH_NORMALIZATION_ERROR The DID URL contains a path that normalizes to a URL outside the perview of the selected service endpoint. The DID URL path overwrote the path part of the service endpoint. (Default Service Handling Algorithm) DEREFERENCING_ERROR_PATH_HANDLER_HANDLER_NOT_DEFINED The DID URL contains a path and the DID Document contains a matching PathHandler object, but no appropriate handler is defined or registered within the dereferencing environment to process it. (PathHandlers Step) DEREFERENCING_ERROR_RESOLUTION_ERROR The dereferencing process failed because the underlying identifier resolution process encountered an error before dereferencing could be completed. (Resolve the DID) DEREFERENCING_ERROR_SERVICE_NOT_FOUND The specific service referenced during the dereferencing process (e.g., via a service query parameter) was not found in the resolved document. (Services Step) Metadata Structure 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. Numeric representations vary across platforms and serializations (for example, IEEE-754 floating-point vs. fixed-width integers vs. “bigint”/bignum types). The Infra standard does not yet provide comprehensive guidance for numbers. Implementers are advised to avoid metadata numbers that are likely to be represented differently on different platforms — notably the following: * non-integer values such as floating-point numbers or fractions * integers outside common fixed-width ranges, such as those larger than a 32-bit unsigned integer (maximum 232 - 1 or 4,294,967,295) Where such values are needed for interoperability, a good practice for property is definitions to use a canonical string serialization (for example, a string formatted as a floating-point number using a clearly defined precision and rounding strategy) and to document any expected range or format. 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" ]» DID Resolution Architectures This section is currently marked as [=at risk=]. Method Architectures The DID resolution algorithm involves executing the Resolve 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: * A DID method might use an immutable blockchain, distributed ledger, distributed file system, peer-to-peer network, or other decentralized infrastructure as (part of) its verifiable data registry. * A DID method might use DNS, HTTP, or web servers as (part of) its verifiable data registry. * A DID method might use any combination of the above technical infrastructures. * A DID method might store an actual DID document in plain-text form in a verifiable data registry and might simply retrieve that document during the "Resolve" operation. * A DID method might define its "Resolve" operation in a more complex way that could involve intermediate, partial, or temporary DID documents, and use multi-step processes that construct the DID document "on-the-fly". * A DID method might require interaction with remote servers or networks during execution of the "Resolve" operation. * A DID method might execute the "Resolve" operation in an entirely local way that does not require any interaction with remote servers or networks. For example, in the [[?DID-KEY]] method, the DID itself wraps a public key, and the "Resolve" operation is simply a trivial, local transformation process. Based on the above considerations combined with the nature of a DID method's "Resolve" operation, the interaction between a DID resolver and the verifiable data registry could be considered either a verifiable resolution or an unverifiable resolution: A verifiable resolution implementation of a DID method. An unverifiable resolution implementation of a DID method. A verifiable resolution maximizes confidence in the integrity and correctness of the result of the "Resolve" operation, to the extent possible under the applicable DID method. This can be accomplished in a number of ways, such as the following: * A verifiable resolution can be accomplished if access to the verifiable data registry is possible in a local, trusted network environment. + For example, in blockchain-based DID methods, a verifiable resolution might be accomplished if a blockchain full node is deployed on a local server. * If access to the verifiable data registry happens via a remote server, a verifiable resolution might still be accomplished if the remote server is trusted, and if it can be accessed via a secure channel. * If access to the verifiable data registry happens via a remote server, a verifiable resolution might be accomplished if the DID resolver has some way of verifying the DID document and DID document metadata returned by the DID method. + For example, in blockchain-based DID methods, even if direct access to a blockchain full node is not available, a verifiable resolution may still be possible by using a light client that processes metadata to verify the data. An unverifiable resolution does not have such guarantees and is therefore less desirable, for example: * An unverifiable resolution takes place if access to the verifiable data registry happens via a remote, untrusted intermediary. + For example, in the case of blockchain-based DID methods, a remote blockchain explorer API operated by an third party may be used to look up data from the blockchain. Whether or not a verifiable resolution 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 "Resolve" operation, and SHOULD offer guidance regarding at least one way to implement a verifiable resolution. The guarantees associated with a verifiable resolution 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 resolution 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 resolutions, many DID methods use digital signatures, state proofs, proofs of inclusion in Merkle trees, cryptographic event logs, or other types of proof. 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 "Resolve" 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 . Resolver Architectures 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: * A DID resolver might be invoked within an application by calling a software library or SDK. * A DID resolver might be invoked as a command line tool. * A DID resolver might be invoked over an HTTP(S) API or other network protocol, e.g., see . 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: A local binding for a DID resolver. A remote binding for a DID resolver. 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: * The remote binding SHOULD use a trusted instance of a DID resolver, ideally under the control of the client itself (e.g., self-hosted). * The remote binding SHOULD use a secure channel such as VPN and/or TLS with mutual authentication. * The client could query multiple DID resolvers over a remote binding and compare results. A DID resolver MAY also include proofs in a proof property of the DID resolution metadata. 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 "Resolve" operation of the applicable DID method is itself correct. See also . Multiple Methods A DID resolver might support the DID resolution algorithm for multiple DID methods: A DID resolver that supports multiple DID methods. In this case, the above considerations in about verifiable resolution and unverifiable resolution implementations apply to each supported DID method individually. Proxied Resolution 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. A client invokes a DID resolver via local binding, which invokes another DID resolver via remote binding, which in turn executes the resolution operation of the DID method. 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). Client-Side Dereferencing 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, the fragment is handled by the client in using the DID URL dereferencing handler result. Examples Given the DID URL did:xyz:1234#keys-1, a DID resolver could be invoked via local binding to execute the DID resolution algorithm, and the client completes the DID URL dereferencing algorithm by dereferencing the fragment (i.e., a part of the DID document). Client-side dereferencing of a DID URL by a DID resolver and a client. Given the DID URL did:xyz:1234?service=agent&relativeRef=%2Fsome%2Fpath%3Fquery#frag, a DID resolver is invoked to execute the DID resolution algorithm, and the client completes the remainder of the DID URL dereferencing algorithm, processing the query parameters, dereferencing a resource, and then dereferencing the fragment within that resource. Client-side dereferencing of a DID URL by a DID resolver and a client. 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 to execute the DID resolution algorithm, and the client completes the DID URL dereferencing algorithm by dereferencing the fragment (i.e., a part of the DID document). Client-side dereferencing (in combination with Proxied Resolution) of a DID URL by two DID resolvers and a client. DID Resolution Result 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`. Example { "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" } } } } Errors 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: * The `type` value of the error object MUST be a URL. * The `title` value SHOULD provide a short but specific human-readable string for the error. * The `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 can use such a declaration to determine how to convey that error type. INVALID_DID An invalid DID was detected during DID Resolution. See Section . https://www.w3.org/ns/did#INVALID_DID INVALID_DID_DOCUMENT The [=DID document=] was malformed. See Section . https://www.w3.org/ns/did#INVALID_DID_DOCUMENT NOT_FOUND The DID resolver was unable to find the DID document resulting from this resolution request. See Section . https://www.w3.org/ns/did#NOT_FOUND REPRESENTATION_NOT_SUPPORTED The representation requested via the accept DID URL dereferencing option is not supported by the DID method and/or DID URL dereferencer implementation. See Section . https://www.w3.org/ns/did#REPRESENTATION_NOT_SUPPORTED INVALID_DID_URL An invalid DID URL was detected during DID URL dereferencing. See Section https://www.w3.org/ns/did#INVALID_DID_URL METHOD_NOT_SUPPORTED The DID method of the DID is not supported by the DID resolver. See Section . https://www.w3.org/ns/did#METHOD_NOT_SUPPORTED INVALID_OPTIONS One or more of the options provided for DID Resolution or DID URL dereferencing are invalid. https://www.w3.org/ns/did#INVALID_OPTIONS INTERNAL_ERROR An unexpected error occured during DID Resolution or DID URL dereferencing. https://www.w3.org/ns/did#INTERNAL_ERROR FEATURE_NOT_SUPPORTED The DID resolver does not support the requested feature. The value of the `detail` 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 Bindings This section defines bindings for the abstract algorithm in section . HTTP(S) Binding This section defines a DID resolver binding which exposes the DID resolution function (including all resolution options and metadata) via an HTTP(S) endpoint. See . 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 ) can be executed as follows: 1. Initialize a request HTTP(S) URL with the DID resolver HTTP(S) endpoint. https://resolver.example/1.0/identifiers/ 2. For the DID resolution function: 1. Append the input DID to the request HTTP(S) URL. https://resolver.example/1.0/identifiers/did:example:1234 2. Set the Accept HTTP request header to `application/did-resolution` to request a complete , OR 3. set the Accept HTTP request header to the value of the accept resolution option to request only the didDocument value of the result. 3. For the HTTP(S) GET binding: 1. If any other resolution options than accept are provided: 1. The input DID MUST be URL-encoded (as specified in RFC3986 Section 2.1). 2. Encode all resolution options except accept as query parameters in the request HTTP(S) URL. 2. Execute an HTTP 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 4. For the HTTP(S) POST binding: 1. If any other resolution options than accept are provided: 1. Encode all resolution options except accept as a JSON structure in the HTTP request's POST body. 2. Execute an HTTP 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" } 5. If the DID resolution function returns an error metadata property in the didResolutionMetadata, then the HTTP response status code MUST correspond to the type property of the error object, according to the following table: 5. error type URI HTTP status code https://www.w3.org/ns/did#INVALID_DID 400 https://www.w3.org/ns/did#INVALID_DID_URL 400 https://www.w3.org/ns/did#INVALID_OPTIONS 400 https://www.w3.org/ns/did#NOT_FOUND 404 https://www.w3.org/ns/did#REPRESENTATION_NOT_SUPPORTED 406 https://www.w3.org/ns/did#INVALID_DID_DOCUMENT 500 https://www.w3.org/ns/did#METHOD_NOT_SUPPORTED 501 https://www.w3.org/ns/did#FEATURE_NOT_SUPPORTED 501 https://www.w3.org/ns/did#INTERNAL_ERROR 500 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. 6. If the DID resolution function returns a deactivated metadata property with the value true in the didDocumentMetadata: 1. The HTTP response status code MUST be 410, even if a step below requires a different status code. 7. For the DID resolution function: 1. If the value of the Content-Type HTTP response header is `application/did-resolution`: 1. If the function is successful, the HTTP response status code MUST be 200. 2. The HTTP body MUST contain a DID resolution result (see ) that is the result of the DID resolution function. 2. Otherwise, if the function is successful and returns a didDocument: 1. The HTTP response status code MUST be 200. 2. The HTTP response MUST contain a Content-Type HTTP response header. Its value MUST be the value of the contentType metadata property in the didResolutionMetadata (see ). 3. The HTTP response body MUST contain the didDocument that is the result of the DID resolution function, in the representation corresponding to the Content-Type HTTP response header. See here for an OpenAPI definition corresponding to the HTTP(S) binding. DID Resolution Examples 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 Example: Returning a DID Resolution Result 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": { ... } } Example: Returning a DID Document 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": [{ ... }] } Security Considerations 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. Authentication/Authorization 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. Caching 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. JSON-LD Context Integrity 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. Versioning 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. VDR Network Forks 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. Dereferencing Cycles 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: * Infinite loops or stack overflows in software. * Resource exhaustion (e.g., memory, network, or CPU). * Denial-of-service (DoS) vulnerabilities in clients or intermediaries. 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. Query String Normalization and Injection Risks The query component of a DID URL is used to pass DID parameters that affect resolution and dereferencing behavior (see ). Several aspects of query string handling carry security implications that implementers are advised to consider carefully. Path Traversal via `relativeRef` 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: * Literal dot-dot-slash: `../` * Percent-encoded variants: `%2E%2E%2F`, `%2E%2E/`, .`%2E/`, `%2E./` * Doubly-encoded variants: `%252E%252E%252F` * Platform-specific variants (e.g., `..\` on Windows-derived path libraries) Implementers are encouraged to: * Normalize the resolved path after applying the RFC3986 Section 5 Reference Resolution algorithm, and verify that the resulting path does not traverse above the base path of the service endpoint URL. * Treat `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 ). * Apply normalization and validation after full percent-decoding, to guard against encoded traversal variants. Superficial string matching (e.g., checking only for the literal string `../`) 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 . Normalization Inconsistency as a Cache Bypass Vector As described in , the same logical DID URL can be represented by multiple syntactically distinct strings. In a proxied or multi-component resolution architecture (see ), different components can apply different normalization rules (or no normalization at all). An attacker aware of normalization inconsistencies between components could: * Construct a DID URL that is served from cache by one component but re-dereferenced from the verifiable data registry by another, potentially bypassing content integrity checks associated with cached responses. * Cause two logically identical DID URLs to be cached as distinct entries, inflating cache size and potentially enabling cache exhaustion. * Exploit differing duplicate-parameter handling between a caching proxy and an upstream resolver to inject unexpected parameter values into a resolution request. To mitigate these risks, implementers are encouraged to: 1. Apply query string normalization (per ) at the outermost entry point of the resolution pipeline, before any caching or forwarding occurs. 2. Use the normalized form of the DID URL as the cache key, and document the normalization algorithm applied. 3. Avoid assuming that a DID URL received from an upstream component has already been normalized; applying independent normalization before processing is a safer approach. Parameter Injection via Concatenation 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 ), in the applicable DID method specification, or in the DID Document Resolution Extensions [[?DID-EXTENSIONS-RESOLUTION]]. Privacy Considerations 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. Profiling of DID Resolution and Dereferencing Requesters 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. Method specific considerations 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. Relationship to Other Technologies 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. DID Resolution Resources 1. DID resolvers in DID Core specification 2. Universal Resolver 3. did-client 4. uPort DID resolver Revision History 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: * HTTP Status Codes for Other Error Types: The HTTP(S) Binding no longer requires a 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. * DID URL Dereferencing over HTTP(S): The HTTP(S) Binding, its examples and its OpenAPI definition no longer cover DID URL dereferencing, and the conformance class of a network-based DID URL dereferencer is removed. * Location of contentType: The DID Resolution algorithm now returns contentType in the DID resolution metadata, where it is defined. * Status Codes for Complete Results: The HTTP(S) Binding now requires a 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. * URLs for Other Error Types: A specification that defines an error type now has to define its URL. The rule for prepending https://www.w3.org/ns/did#, which no longer applies to any error type, is removed. Changes since the First Public Working Draft include: * Document Scope and Structure Additions + Title and Authorship: The title was simplified to "Decentralized Identifier Resolution (DID Resolution) v1," and new editors (Stephen Curran, Joe Andrieu) were added. + Contextual Sections: The CR adds new, non-normative introductory sections for "Implementer Overview," "Audience," and "Use Cases" to provide better context for developers and architects. + Conformance Categories: The CR introduces two new conformance categories specifically for network-based implementations: "conforming network-based DID resolver" and "conforming network-based DID URL dereferencer". * Resolution Interface and Algorithms + Abstract Interface Simplification: The FPWD defined two distinct abstract functions: 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. + Relative URL Expansion: The CR introduces a new DID resolution option called expandRelativeUrls. When set to true, the resolver will automatically expand any relative DID URLs found within the DID document into absolute DID URLs. + DID Parameters and Normalization: The CR expands upon DID parameters by formally defining the behaviors of 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. + Datetime Standardization: The CR imposes a strict format for all datetime values (such as versionTime, created, and updated), requiring them to be XML Datetime strings adjusted to UTC without sub-second precision. * DID URL Dereferencing Changes + Feature at Risk: The CR explicitly flags the entire "DID URL Dereferencing" section and its corresponding data result structures as "at risk," noting that it may be heavily modified or removed. + Provisional Algorithm: Because of the "at risk" status, the CR introduces a "PROVISIONAL - DID URL Dereferencing" section that explores a modular, alternative approach based on sequential "handling strategies". + Verification Relationships: The CR adds 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. + Service Endpoint Construction Removal: The standalone algorithm for "Service Endpoint Construction" (Section 11 in the FPWD) was removed from the CR version. * Error Handling and Extensibility + RFC9457 Error Formats: Instead of using simple single-keyword ASCII strings for errors like the FPWD, the CR mandates the use of RFC9457 (Problem Details for HTTP APIs). + Error URIs: Error types in the CR are now mapped to specific W3C URIs (e.g., https://www.w3.org/ns/did#INVALID_DID), and new errors such as INVALID_DID_DOCUMENT and FEATURE_NOT_SUPPORTED were introduced. + Shift to Extensions: The CR shifts references for metadata and options registration away from the "DID Specification Registries" used in the FPWD, advising implementers to use the "DID Resolution Extensions" and "DID Document Properties Extensions" instead. * Expanded Security and Privacy Considerations + New Security Vectors: The CR vastly expands the Security Considerations section to address vulnerabilities such as: o Dereferencing Cycles: Risks of infinite loops or resource exhaustion when following nested DID document references. o Query String/Parameter Injection: Vulnerabilities arising from inconsistent cache normalization or unsafe programmatic string concatenation. o Path Traversal: Risks of an attacker escaping a service endpoint's intended path using malicious relativeRef parameter sequences (e.g., ../). o JSON-LD Integrity & Network Forks: Guidance on validating JSON-LD Context files and handling VDR (verifiable data registry) network forks. + New Privacy Section: The CR introduces a standalone "Privacy Considerations" section, highlighting the risk that DID resolvers and dereferencers can log and profile clients requesting resolution, advising mitigation strategies like using trusted proxies or Oblivious HTTP. |
For now, Differences are performed on text, not graphically, only the latest screenshot is available.
Screenshot requires Playwright/WebDriver enabled