Decentralized Identifiers (DIDs) are a new type of identifier for verifiable, "self-sovereign" digital identity. DIDs are fully under the control of the DID subject, independent from any centralized registry, identity provider, or certificate authority. DIDs resolve to DID Documents — simple documents that describe how to use that specific DID.

This document specifies the algorithms and guidelines for resolving DIDs and dereferencing DID URLs.

Comments regarding this document are welcome. Please file issues directly on GitHub, or send them to public-credentials@w3.org (subscribe, archives).

Portions of the work on this specification have been funded by the United States Department of Homeland Security's Science and Technology Directorate under contracts HSHQDC-17-C-00019. The content of this specification does not necessarily reflect the position or the policy of the U.S. Government and no official endorsement should be inferred.

Work on this specification has also been supported by the Rebooting the Web of Trust community facilitated by Christopher Allen, Shannon Appelcline, Kiara Robles, Brian Weller, Betty Dhamers, Kaliya Young, Kim Hamilton Duffy, Manu Sporny, Drummond Reed, Joe Andrieu, and Heather Vescent.

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 common requirements, algorithms including their inputs and results, architectural options, and various considerations for the DID Resolution and DID URL Dereferencing processes.

Note that while this specification defines some base-level functionality for DID Resolution, the actual steps required to communicate with a DID's Decentralized Identifier Registry are defined by the applicable DID method specification.

The difference between "resolving" a DID and "dereferencing" a DID URL is being thoroughly discussed by the community. E.g. see this comment.

Terminology

Binding
A concrete mechanism through which a Client invokes a DID Resolver. This could be a Local Binding such as a local command line tool or library API, or a Remote Binding such as the HTTP(S) Binding. See Section .
Client
Software and/or hardware that invokes a DID Resolver in order to execute the DID Resolution and/or DID URL Dereferencing algorithms. This invocation is done via a Binding. The term Client does not imply any specific network topology.
Decentralized Identifier (DID)
As defined in [[DECENTRALIZED-IDENTIFIERS]].
Decentralized Identifier Registry (DIR)
As defined in [[DECENTRALIZED-IDENTIFIERS]].
DID Document
As defined in [[DECENTRALIZED-IDENTIFIERS]].
DID Fragment
As defined in [[DECENTRALIZED-IDENTIFIERS]].
DID Method
As defined in [[DECENTRALIZED-IDENTIFIERS]].
DID Path
As defined in [[DECENTRALIZED-IDENTIFIERS]].
DID Query
As defined in [[DECENTRALIZED-IDENTIFIERS]].
DID Resolution
An algorithm that takes a DID plus additional options as input and returns a DID Document or a DID Resolution Result as output. This algorithm relies on the "Read" operation of the applicable DID method. See Section .
DID Resolver
Software and/or hardware that is capable of executing the DID Resolution and optionally DID URL Dereferencing algorithms for at least one DID method.
DID Resolution Result
A data structure that represents the result of the DID Resolution or DID URL Dereferencing algorithm. May contain a DID Document or other content. See Section .
DID URL
As defined in [[DECENTRALIZED-IDENTIFIERS]].
DID URL Dereferencing
An algorithm that takes a DID URL plus additional options as input and returns a DID Document, a DID Resolution Result, or various other types of resources as output. This algorithm relies on DID Resolution. See Section .
Local Binding
A Binding where the Client invokes a DID Resolver that runs on the same network host, e.g. via a local command line tool or library API. In this case, the DID Resolver is sometimes also called a "local DID Resolver". See Section .
Remote Binding
A Binding where the Client invokes a DID Resolver that runs on a different network host, e.g. via the HTTP(S) Binding. In this case, the DID Resolver is sometimes also called a "remote DID Resolver". See Section .
Service Endpoint
As defined in [[DECENTRALIZED-IDENTIFIERS]].
Unverifiable Read
A low confidence implementation of a DID method's "Read" operation between the DID Resolver and the Decentralized Identifier Registry, to obtain the DID Document. There is no guarantee about the integrity and correctness of the result. See Section .
Verifiable Read
A high confidence implementation of a DID method's "Read" operation between the DID Resolver and the Decentralized Identifier Registry, to obtain the DID Document. There are guarantees about the integrity and correctness of the result to the extent possible under the applicable DID method. See Section .

Resolving a DID

This section defines the inputs and the algorithm of DID Resolution, which returns a DID Document or a DID Resolution Result as output. This algorithm relies on the "Read" operation of the applicable DID method.

The abstract interface to this algorithm is:

resolve ( did, input-options )

Input

The inputs of the DID Resolution algorithm are an input DID and additional input options.

DID

The input DID is REQUIRED for the DID Resolution algorithm.

The `method-name` component of the input DID is called the input DID method.

result-type

The result-type input option can be used to request a certain type of result.

This input option is OPTIONAL.

Possible values of this option are:

Discuss what this means for certain bindings (such as ).

version-id

The version-id input option can be used to request a specific version of a DID Document.

This input option is OPTIONAL. It is mutually exclusive with .

See Section for additional considerations.

The possible values of this option are specific to the input DID method.

Possible values may include sequential numbers, random UUIDs, content hashes, etc.

version-time

The version-time input option can used to request a specific version of a DID Document.

This input option is OPTIONAL. It is mutually exclusive with .

See Section for additional considerations.

The value of this option MUST be a string value of an [[!RFC3339]] combined date and time string representing the date and time the DID Document was current for the input DID.

no-cache

The no-cache input option can be used to request a certain kind of caching behavior.

This input option is OPTIONAL.

Possible values of this option are:

See Section for additional considerations.

Algorithm

The following DID Resolution algorithm MUST be implemented by a conformant DID Resolver.

  1. Validate that the input DID conforms to the `did` rule of the Generic DID Syntax. If not, the DID Resolver MUST raise an error.
  2. Determine if the input DID method is supported by the DID Resolver that implements this algorithm. If not, the DID Resolver MUST raise an error.
  3. Obtain the DID Document for the input DID by executing the Read operation against the input DID's Decentralized Identifier Registry, as defined by the input DID method:
    1. Besides the input DID, all additional input options of this algorithm MUST be passed to the Read operation of the input DID method.
    2. If the input DID does not exist, return a null result.
    3. The result of the Read operation is called the output DID Document.
  4. Validate that the output DID Document conforms to the serialization of the DID Document data model. If not, the DID Resolver MUST raise an error.
  5. If the value of result-type input option is null or "did-document":
    1. Return the output DID Document.
  6. If the value to of result-type input option is "resolution-result":
    1. Construct a DID Resolution Result and populate it with the output DID Document as well as metadata about the processes that produced the result (see . This is called the output DID Resolution Result.
    2. Return the output DID Resolution Result.

There is discussion how a DID that has been deactivated should be treated during the DID Resolution process.

Specify how signatures/proofs on a DID Document should be verified during the DID Resolution process.

Should we define functionality that enables discovery of the list of DID methods or other capabilities that are supported by a DID Resolver? Or is this implementation-specific and out-of-scope for this spec? E.g. see here and here.

Dereferencing a DID URL

This section defines the inputs and the algorithm of DID URL Dereferencing, which returns a DID Document, a DID Resolution Result, or various other types of resources as output. This algorithm relies on DID Resolution.

The abstract interface to this algorithm is:

dereference ( did-url, input-options )

Input

The inputs of the DID URL Dereferencing algorithm are an input DID URL and additional input options.

DID URL

The input DID URL is REQUIRED for the DID URL Dereferencing algorithm.

The `did̀` component of the input DID URL is called the input DID.

result-type

The result-type input option can be used to request a certain type of result.

This input option is OPTIONAL.

Possible values of this option are:

Discuss what this means for certain bindings (such as ).

Discuss additional result types that may exist for DID URL Dereferencing but do not exist for DID Resolution.

service-type

The service-type input option can be supplied by a client to select a specific service from the DID Document.

This input option is OPTIONAL.

See comments by Dave Longley about `service-type`.

follow-redirect

The follow-redirect input option can be supplied by a client as a hint to instruct whether redirects should be followed.

This input option is OPTIONAL.

See Section .

Algorithm

The following DID URL Dereferencing algorithm MUST be implemented by a conformant DID Resolver. In accordance with [[RFC3986]], it consists of the following steps: Resolving the DID, dereferencing the primary resource, and dereferencing the secondary resource (only if the input DID URL contains a DID Fragment:

  1. Obtain the DID Document for the input DID by executing the DID Resolution algorithm as defined in . All generic matrix parameters as well as method-specific matrix parameters of the input DID URL MUST be passed as input options to the DID Resolution algorithm. If the input DID does not exist, return a null result. Otherwise, the result is called the resolved DID Document.
  2. If present, separate the DID Fragment from the input DID URL. Execute the algorithm for , with the input DID URL adjusted accordingly.
  3. If the original input DID URL contained a DID Fragment, execute the algorithm for .

Dereferencing the Primary Resource

  1. If the input DID URL contains the generic matrix parameter service and optionally a DID Path and/or DID Query:
    did:example:1234;service=agent/profile?query
    1. From the resolved DID Document, select the service endpoint whose id property contains a fragment which matches the value of the service matrix parameter of the input DID URL. This is called the input service endpoint.
    2. Execute the Service Endpoint Construction algorithm:
      1. Read the value of the serviceEndpoint property of the input service endpoint. This is called the input service endpoint URL.
      2. Pass the input DID URL and input service endpoint URL to the Service Endpoint Construction algorithm.
      3. The result is called the output service endpoint URL.
    3. Return the output service endpoint URL.
  2. Otherwise, if the input DID URL contains method-specific matrix parameters:
    did:example:1234;example:object=myprofile
    1. Defer to the applicable DID Method specification to determine how to dereference the input DID URL.
  3. Otherwise, if the input DID URL contains no DID Path and no DID Query:
    did:example:1234
    1. Return the resolved DID Document.
  4. Otherwise, if the input DID URL contains a DID Path and/or DID Query:
    did:example:1234/custom/path?customquery
    1. The applicable DID Method MAY specify how to dereference the input DID URL.
    2. The client MAY be able to dereference the input DID URL in an application-specific way.
  5. If neither this algorithm, nor the applicable DID Method, nor the client is able to dereference the input DID URL:
    1. Return a null result.

Dereferencing the Secondary Resource

If the input DID URL contains a DID Fragment, then dereferencing of the secondary resource identified by the URL is dependent not on the URI scheme, but on the media type ([[RFC2046]]) of the primary resource, i.e. on the result of .

  1. If the result of is a resolved DID Document with MIME type application/did+ld+json, and the input DID URL contains a DID Fragment:
    did:example:1234#keys-1
    1. From the resolved DID Document, select the JSON-LD object whose id property matches the input DID URL, e.g. a public key or service endpoint in the DID Document. This is called the output resource. Selecting the JSON-LD object from the DID Document MUST take into account relative IRIs and the base IRI of the resolved DID Document.
    2. Return the output resource.

      Mention relative IRIs and that the DID itself is considered the base IRI for the JSON-LD parser. Mention potential attack vector if @base is injected into the DID Document.

      Also see this discussion on fully qualified DID URLs as the value of the id field.

      This use of the DID Fragment is consistent with the definition of the fragment identifier in [[RFC3986]]. It identifies a secondary resource which is a subset of the primary resource (the DID Document).

      This use of the DID Fragment is furthermore consistent with the concept of Hash URIs for the Semantic Web [[COOL-URIS]].

      Perhaps we can find a good reference somewhere from RDF, JSON-LD or Solid specifications that defines clearly the ability to use the fragment for identifying a specific resource in an RDF document.

  2. Otherwise, if the result of is an output service endpoint URL, and the input DID URL contains a DID Fragment:
    did:example:1234;service=agent/profile?query#frag
    1. Append the DID Fragment to the output service endpoint URL. In other words, the output service endpoint URL "inherits" the DID Fragment of the input DID URL.
    2. Return the output service endpoint URL.
    3. This behavior of the DID Fragment is analogous to the handling of a fragment in an HTTP URL in the case when dereferencing it returns an HTTP 3xx (Redirection) response with a Location header (see section 7.1.2 of [[RFC7231]].

  3. Otherwise, dereference the secondary resource as defined by the media type ([[RFC2046]]) of the primary resource.

Additional Features

This section lists additional DID URL Dereferencing features that are under discussion and have not yet been incorporated into the algorithm.

Redirect

A service endpoint may have a serviceEndpoint property with a value that is itself a DID. This is interpreted as a "DID redirect" from the input DID to another. In this case, a "child" DID Resolution process can be launched to get to a "final" service endpoint.

See corresponding open issue.

DID redirects could not only apply to a single service endpoint, but to an entire DID Document, therefore enabling portability use cases.

{
   "id": "did:example:123456789abcdefghi#hub1",
   "type": "HubService",
   "serviceEndpoint": "did:example:xyz"
}

Proxy

A DID Document may contain a "proxy" service type which would provide a mapping that needs to be followed in order to resolve to a final service URL.

{
   "id": "did:example:123456789abcdefghi",
   "type": "ProxyService",
   "serviceEndpoint": "https://mydomain.com/proxy"
}

JSON Pointer

Several ways of selecting parts of a DID Document are being discussed, including the use of JSON pointer.

See corresponding PR.

Examples

Given the following resolved DID Document:

{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:example:123456789abcdefghi",
  "publicKey": [{
    "id": "did:example:123456789abcdefghi#keys-1",
    "type": "RsaVerificationKey2018",
    "publicKeyPem": "-----BEGIN PUB...0101010..END PUB -----\r\n"
  }],
  "service": [{
    "id": "did:example:123456789abcdefghi#agent",
    "type": "AgentService",
    "serviceEndpoint": "https://agent.example.com/8377464"
  }, {
    "id": "did:example:123456789abcdefghi#hub",
    "type": "HubService",
    "serviceEndpoint": "https://hub.example.com/.identity/did:example:0123456789abcdef/"
  }, {
    "id": "did:example:123456789abcdefghi#messages",
    "type": "MessagingService",
    "serviceEndpoint": "https://example.com/messages/8377464"
  }]
}

Given the following input DID URL and the resolved DID Document above:

did:example:123456789abcdefghi#keys-1

Then the result of the algorithm is the following output resource:

{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:example:123456789abcdefghi#keys-1",
  "type": "RsaVerificationKey2018",
  "publicKeyPem": "-----BEGIN PUB...0101010..END PUB -----\r\n"
}

Given the following input DID URL and the resolved DID Document above:

did:example:123456789abcdefghi;service=messages/some/path?query#frag

Then the result of the algorithm is the following output service endpoint URL:

https://example.com/messages/8377464/some/path?query#frag
Diagram showing how a DID URL can be dereferencing to a service endpoint URL
Dereferencing a DID URL to a service endpoint URL.

Change the diagram and/or examples to make them consistent.

DID Resolution Architectures

TODO: Describe how DID Resolvers are implemented and used, describe the relevance of DID methods. Explain the difference between "method architectures" and "resolver architectures".

Method Architectures

The DID Resolution algorithm involves executing the Read operation on a DID according to its DID method (see ).

The mechanics of the "Read" operation can vary considerably between DID methods. In particular, no assumption should be made that:

As an example, mention what it means to "resolve" peer/off-ledger/microledger/edgechain DIDs (e.g. see [[DID-PEER]] and here).

As an example, mention what it means to "resolve" DIDs that are simply wrapped public keys (e.g. see [[DID-KEY]] and here).

Depending on the exact nature of the DID method's "Read" operation, the interaction between a DID Resolver and the Decentralized Identifier Registry may be implemented as a Verifiable Read or Unverifiable Read:

Diagram showing a 'Verifiable Read' implementation of a DID method.
A Verifiable Read implementation of a DID method.
Diagram showing an 'Unverifiable Read' implementation of a DID method.
An Unverifiable Read implementation of a DID method.

A Verifiable Read maximizes confidence in the integrity and correctness of the result of the "Read" operation ‐ to the extent possible under the applicable DID method. It can be implemented in a variety of ways, for example:

An Unverifiable Read does not have such guarantees and is therefore less desirable, for example:

Whether or not a Verifiable Read is possible depends not only on a DID method itself, but also on the way how a DID Resolver implements it. DID methods MAY define multiple different ways of implementing their "Read" operation(s) and SHOULD offer guidance on how to implement a Verifiable Read in at least one way.

The guarantees associated with a Verifiable Read are still always limited by the architectures, protocols, cryptography, and other aspects of the underlying Decentralized Identifier Registry. The strongest forms of Verifiable Read implementations are considered those that do not require any interaction with a remote network at all (for example, see [[DID-KEY]]), or that minimize dependencies on specific network infrastructure and reduce the "root of trust" to proven entropy and cryptography alone (for example, see [[KERI]]).

TODO: Describe how a client can potentially verify the result of a "Read" operation independently even if it does not trust the DID resolver (e.g. using state proofs).

A DID Resolver MUST support the DID Resolution algorithm for at least one DID method and MAY support it for multiple DID methods:

Diagram showing a DID Resolver that supports multiple DID methods.
A DID Resolver that supports multiple DID methods.

In this case, the above considerations about Verifiable Read and Unverifiable Read implementations apply to each supported DID method individually.

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. A DID Resolver is invoked by a Client via a Binding. Bindings define how the abstract functions are realized using concrete programming or communication interfaces. It is possible to distinguish between Local Bindings (such as a local command line tool or library API) and Remote Bindings (such as the HTTP(S) Binding).

Diagram showing a DID Resolver with a 'Local Binding'.
A Local Binding for a DID Resolver.
Diagram showing a DID Resolver with a 'Remote Binding'.
A Remote Binding for a DID Resolver.

TODO: Describe Local Bindings vs. Remote Bindings, and implications for privacy, security and trust.

Also describe mitigations against potential downsides of Remote Bindings, e.g.:

TODO: Discuss DID Resolution in constrained user agents such as mobile apps and browsers.

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).

Diagram showing two DID Resolvers, one invoked via 'Local Binding', the other invoked via 'Remote Binding'.
A client invokes a DID Resolver via Local Binding which invokes another DID Resolver via Remote Binding, which in turn supports resolving multiple DID methods.

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 Primary Resource is done by the DID Resolver, and Dereferencing the Secondary Resource is done by the Client.

Example: Given the DID URL did:xyz:1234#keys-1, a DID Resolver could be invoked via Local Binding for Dereferencing the Primary Resource (i.e. the DID Document), and the Client could complete the DID URL Dereferencing algorithm by Dereferencing the Secondary Resource (i.e. a part of the DID Document).

Diagram showing client-side dereferencing of a DID URL by a DID Resolver and a Client
Client-side dereferencing of a DID URL by a DID Resolver and a Client.

Example: 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 Primary Resource (i.e. the DID Document), and the Client could complete the DID URL Dereferencing algorithm by Dereferencing the Secondary Resource (i.e. a part of the DID Document).

Diagram showing client-side dereferencing of a DID URL by two DID Resolvers and a Client
Client-side dereferencing (in combination with Proxied Resolution) of a DID URL by two DID Resolvers and a Client.

Example: Given the DID URL did:xyz:1234;service=agent/path?query#frag, a DID Resolver could be invoked for Dereferencing the Primary Resource (i.e. a service endpoint URL), and the Client could complete the DID URL Dereferencing algorithm by Dereferencing the Secondary Resource (i.e. a service endpoint URL with a fragment).

Diagram showing client-side dereferencing of a DID URL by a DID Resolver and a Client
Client-side dereferencing of a DID URL by a DID Resolver and a Client.

DID Resolution Result

This section defines a data structure that in some cases represents the result of the algorithms described in and . A DID Resolution Result contains a DID Document or other result as well as metadata about the processes that produced the result.

See corresponding open issue.

Need to define how this data structure works exactly, and whether it always contains a DID Document or can also contain other results.

Example

{
	"@context": "https://www.w3.org/ns/did-resolution/v1",
	"didDocument": {
		"@context": "https://www.w3.org/ns/did/v1",
		"id": "did:sov:WRfXPg8dantKVubE3HX8pw",
		"service": {
			"type": "xdi",
			"serviceEndpoint": "http://127.0.0.1:8080/xdi"
		},
		"authentication": {
			"type": "Ed25519SignatureAuthentication2018",
			"publicKey": ["did:sov:WRfXPg8dantKVubE3HX8pw#key-1"]
		},
		"publicKey": [{
			"id": "did:sov:WRfXPg8dantKVubE3HX8pw#key-1",
			"type": "Ed25519VerificationKey2018",
			"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
		}]
	},
	"resolverMetadata": {
		"driverId": "did:sov",
		"driver": "HttpDriver",
		"retrieved": "2019-06-01T19:73:24Z",
		"duration": 1015
	},
	"methodMetadata": {
		"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 Document

A DID Document associated with a DID. The result of .

Resolver Metadata

TODO: Describe DID Resolution metadata that is not method-specific, e.g.:

  • Duration of the DID Resolution process.
  • Versioning information about the DID Document (see Section ).
  • Caching information about the DID Document (see Section ).

Method Metadata

TODO: Describe DID Resolution metadata that is method-specific, e.g.:

For certain data, it may be debatable whether it should be part of the DID Document (i.e. data that describes the DID Subject), or whether it is metadata (i.e. data about the DID Document or about the DID Resolution process). For example the URL of the "Continuation DID Document" in the BTCR method.

Service Endpoint Construction

This section defines the inputs and the algorithm of Service Endpoint Construction, which returns a service endpoint URL as output. This algorithm is used when service endpoints are selected during DID URL Dereferencing (see ).

In this section, path, query, and fragment are understood as defined in [[RFC3986]].

Input

The inputs of the Service Endpoint Construction algorithm are an input DID URL and an input service endpoint URL.

The requirements for the inputs of the Service Endpoint Construction algorithm are as follows:

Algorithm

  1. Initialize a string output service endpoint URL to the value of the input service endpoint URL
  2. If the output service endpoint URL has a query component, remove it.
  3. If the output service endpoint URL has a fragment component, remove it.
  4. Append the path component of the input DID URL to the output service endpoint URL.
  5. If the input service endpoint URL has a query component, append ? plus the query to the output service endpoint URL.
  6. If the input DID URL has a query component, append ? plus the query to the output service endpoint URL.
  7. If the input service endpoint URL has a fragment component, append # plus the fragment to the output service endpoint URL.
  8. If the input DID URL has a fragment component, append # plus the fragment to the output service endpoint URL.
  9. Return the output service endpoint URL.

We could potentially allow a query components on both the input DID URL and input service endpoint URL, if they both contain lists of key/value parameters that can be merged.

Details of the Service Endpoint Construction algorithm have been discussed in April 2019 on the CCG mailing list, e.g. here or here.

Instead of defining our own algorithm, we could potentially re-use the "Relative Resolution" algorithm defined in [[RFC3986]].

Example

Given the following input service endpoint URL:

https://example.com/messages/8377464

And given the following input DID URL:

did:example:123456789abcdefghi;service=messages/some/path?query#frag

Then the output service endpoint URL is:

https://example.com/messages/8377464/some/path?query#frag

Bindings

This section defines bindings for the abstract algorithms in sections and .

HTTP(S) Binding

This section defines a DID Resolver Binding which exposes the DID Resolution and/or DID URL Dereferencing functions (including all input options and output data) via an HTTP(S) endpoint. See .

TODO: Define HTTP(S) Binding for DID Resolution and DID URL Dereferencing, including the following topics:

  • How are input options passed via HTTP(S)? Using the query string and/or HTTP headers?
  • How is the output data (DID Document, DID Resolution Result) returned via HTTP(S)
  • What is the MIME type of a DID Document? How should Accept and Content-Type HTTP headers be used?
  • Are two separate HTTP(S) endpoints required/allowed for the resolve() and dereference() functions, or can/must a single HTTP(S) endpoint be used?

The HTTP(S) Binding for DID Resolvers requires a known HTTP(S) URL called the DID Resolver HTTP(S) endpoint.

Using this binding, the DID Resolution function (see ) and/or DID URL Dereferencing function (see ) can be executed as follows:

  1. Construct a request HTTP(S) URL by appending the input DID or input DID URL to the DID Resolver HTTP(S) endpoint.
  2. Execute an HTTP GET request on the request HTTP(S) URL.
  3. If the input DID does not exist (i.e. the DID Resolution function returns a null result):
    1. The HTTP response status code MUST be 404.
  4. If the input DID exists and the result is (part of) a DID Document:
    1. The HTTP response status code MUST be 200.
    2. The HTTP response MUST contain a Content-Type header. The value of this header MUST be application/did+ld+json.
    3. The HTTP response body MUST contain the resolved DID Document or other output resources that is the reult of the DID Resolution or DID URL Dereferencing function.
  5. If the input DID exists and the result is a service endpoint URL:
    1. The HTTP response status code MUST be 303.
    2. The HTTP response MUST contain an Location header. The value of this header MUST be the output service endpoint URL.

Example

Given the following DID Resolver HTTP(S) endpoint:

https://uniresolver.io/1.0/identifiers/

And given the following input DID:

did:sov:WRfXPg8dantKVubE3HX8pw

Then the request HTTP(S) URL is:

https://uniresolver.io/1.0/identifiers/did:sov:WRfXPg8dantKVubE3HX8pw

The HTTP(S) Binding can be invoked as follows:

curl -X GET https://uniresolver.io/1.0/identifiers/did:sov:WRfXPg8dantKVubE3HX8pw

Errors

Do we need to define a list of error conditions, codes, etc.

Security and Privacy Considerations

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.

Explain that DIDs are not necessarily globally resolvable, such as pairwise or N-wise "peer" DIDs.

See [[RFC3339]]: URIs have a global scope and are interpreted consistently regardless of context, though the result of that interpretation may be in relation to the end-user's context.

An advanced idea is that the result of DID Resolution could be contextual or depend on policies, see this comment.

A related topic is whether (parts of) DID Document could be encrypted, e.g. see w3c-ccg/did-spec/issues/172. Also see the use of the fragment in the IPID DID method.

Caching

A DID Resolver may maintain a generic cache of DID Documents. It may also maintain caches specific to certain DID methods.

Caching behavior can be controlled by configuration of the DID Resolver, by the `no-cache` input option, or by contents of the DID Document (e.g. a `time-to-live` field), or by a combination of these options.

See corresponding open issue.

Perhaps we can re-use caching mechanisms of other protocols such as HTTP.

Versioning

If a `version-id` or `version-time` input option is provided, the DID Resolution algorithm returns a certain version of the DID Document.

A DID Document MAY contain a version identifier that changes with each Update operation that is performed on a DID.

See corresponding open issue.

While all DID methods MUST 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.

Non-DID Identifiers

There is discussion on the relationship between DID Resolution and resolution of non-DID identifiers such as domain names, HTTP URIs, or e-mail addresses. This includes the questions how DIDs can be discovered from non-DID identifiers, and how links between identifiers can be verifiable.

DID Method Governance

Describe which methods a DID Resolver should support, and potential implications.

DID Resolution Resources

  1. DID Resolvers in DID spec
  2. Universal Resolver
  3. did-client
  4. uPort DID Resolver