Decentralized identifiers (DIDs) are a new type of identifier that enables verifiable, decentralized digital identity. A DID identifies any subject (e.g., a person, organization, thing, data model, abstract entity, etc.) that the controller of the DID decides that it identifies. In contrast to typical, federated identifiers, DIDs have been designed so that they may be decoupled from centralized registries, identity providers, and certificate authorities. Specifically, while other parties might be used to help enable the discovery of information related to a DID, the design enables the controller of a DID to prove control over it without requiring permission from any other party. DIDs are URLs that associate a DID subject with a DID document allowing trustable interactions associated with that subject. Each DID document can express cryptographic material, verification methods, or service endpoints, which provide a set of mechanisms enabling a DID controller to prove control of the DID. Service endpoints enable trusted interactions associated with the DID subject. A DID document might contain semantics about the subject that it identifies. A DID document might contain the DID subject itself (e.g. a data model).

This document specifies a common data model, a URL format, and a set of operations for DIDs, DID documents, and DID methods.

This specification is under active development and implementers are advised against implementing the specification unless they are directly involved with the W3C DID Working Group. There are use cases [[?DID-USE-CASES]] in active development that establish requirements for this document.

At present, there exist 40 experimental implementations and a preliminary test suite that will eventually determine whether or not implementations are conformant. Readers are advised that Appendix contains a list of concerns and proposed changes that will most likely result in alterations to this specification.

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

Portions of the work on this specification have been funded by the United States Department of Homeland Security's Science and Technology Directorate under contracts HSHQDC-16-R00012-H-SB2016-1-002 and 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

As individuals and organizations, many of us use globally unique identifiers in a wide variety of contexts. They serve as communications addresses (telephone numbers, email addresses, usernames on social media), ID numbers (for passports, drivers licenses, tax IDs, health insurance), and product identifiers (serial numbers, barcodes, RFIDs). Resources on the Internet are identified by globally unique identifiers in the form of MAC addresses; URIs (Uniform Resource Identifiers) are used for resources on the Web and each web page you view in a browser has a globally unique URL (Uniform Resource Locator).

The vast majority of these globally unique identifiers are not under our control. They are issued by external authorities that decide who or what they identify and when they can be revoked. They are useful only in certain contexts and recognized only by certain bodies (not of our choosing). They may disappear or cease to be valid with the failure of an organization. They may unnecessarily reveal personal information. And in many cases they can be fraudulently replicated and asserted by a malicious third-party ("identity theft").

The Decentralized Identifiers (DIDs) defined in this specification are a new type of globally unique identifier designed to enable individuals and organizations to generate our own identifiers using systems we trust, and to prove control of those identifiers (authenticate) using cryptographic proofs (for example, digital signatures, privacy-preserving biometric protocols, and so on).

Because we control the generation and assertion of these identifiers, each of us can have as many DIDs as we need to respect our desired separation of identities, personas, and contexts (in the everyday sense of these words). We can scope the use of these identifiers to the most appropriate contexts. We can interact with other people, institutions or systems that require us to identify ourselves (or things we control) while maintaining control over how much personal or private data should be revealed, and without depending on a central authority to guarantee the continued existence of the identifier.

This specification does not require any particular technology or cryptography to underpin the generation, persistence, resolution or interpretation of DIDs. Rather, it defines: a) the generic syntax for all DIDs, and b) the generic requirements for performing the four basic CRUD operations (create, read, update, deactivate) on the metadata associated with a DID (called the DID document).

This enables implementers to design specific types of DIDs to work with the computing infrastructure they trust (e.g., blockchain, distributed ledger, decentralized file system, distributed database, peer-to-peer network). The specification for a specific type of DID is called a DID method. Implementers of applications or systems using DIDs can choose to support the DID methods most appropriate for their particular use cases.

This specification is for:

DID methods can also be developed for identifiers registered in federated or centralized identity management systems. Indeed, almost all types of identifier systems can add support for DIDs. This creates an interoperability bridge between the worlds of centralized, federated, and decentralized identifiers.

A Simple Example

A DID is a simple text string consisting of three parts, the:

did:example:123456789abcdefghi
      

The example DID above resolves to a DID document. A DID document contains information associated with the DID, such as ways to cryptographically authenticate the DID controller, as well as services that can be used to interact with the DID subject.

{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:example:123456789abcdefghi",
  "authentication": [{
    // used to authenticate as did:...fghi
    "id": "did:example:123456789abcdefghi#keys-1",
    "type": "Ed25519VerificationKey2018",
    "controller": "did:example:123456789abcdefghi",
    "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
  }],
  "service": [{
    // used to retrieve Verifiable Credentials associated with the DID
    "id":"did:example:123456789abcdefghi#vcs",
    "type": "VerifiableCredentialService",
    "serviceEndpoint": "https://example.com/vc/"
  }]
}
      

Design Goals

Decentralized Identifiers are a component of larger systems, such as the Verifiable Credentials ecosystem [[VC-DATA-MODEL]], which drove the design goals for this specification. This section summarizes the primary design goals for this specification.

Goal Description
Decentralization Eliminate the requirement for centralized authorities or single point failure in identifier management, including the registration of globally unique identifiers, public verification keys, service endpoints, and other metadata.
Control Give entities, both human and non-human, the power to directly control their digital identifiers without the need to rely on external authorities.
Privacy Enable entities to control the privacy of their information, including minimal, selective, and progressive disclosure of attributes or other data.
Security Enable sufficient security for relying parties to depend on DID documents for their required level of assurance.
Proof-based Enable DID controllers to provide cryptographic proof when interacting with other entities.
Discoverability Make it possible for entities to discover DIDs for other entities, to learn more about or interact with those entities.
Interoperability Use interoperable standards so DID infrastructure can make use of existing tools and software libraries designed for interoperability.
Portability Be system- and network-independent and enable entities to use their digital identifiers with any system that supports DIDs and DID methods.
Simplicity Favor a reduced set of simple features to make the technology easier to understand, implement, and deploy.
Extensibility Where possible, enable extensibility provided it does not greatly hinder interoperability, portability, or simplicity.

Architecture Overview

This section provides a basic understanding of the major elements of DID architecture. Formal definitions of terms are provided in .


Diagram showing that DIDs are recorded on a Verifiable Data Registry; DIDs
resolve to DID documents; DIDs identify DID subjects; a DID controller can
modify a DID document; a DID method generates a DID; a DID method instructs a
DID resolver.
The basic components of DID architecture.
DIDs and DID URLs
A DID, or Decentralized Identifier, is a URI composed of three parts: the scheme "did:", a method identifier, and a unique, method-specific identifier generated by the DID method. DIDs are resolvable to DID documents. A DID URL extends the syntax of a basic DID to incorporate other standard URI components (path, query, fragment) in order to locate a particular resource—for example, a public key inside a DID document, or a resource available external to the DID document.
DID Subjects
The subject of a DID is, by definition, the entity identified by the DID. The DID subject may also be the DID controller. Anything can be the subject of a DID: person, group, organization, physical thing, logical thing, etc.
DID Controllers
The controller of a DID is the entity (person, organization, or autonomous software) that has the capability—as defined by a DID method—to make changes to a DID document. This capability is typically asserted by the control of a set of cryptographic keys used by software acting on behalf of the controller, though it may also be asserted via other mechanisms. Note that a DID may have more than one controller, and the controller(s) may include the DID subject.
Verifiable Data Registries
In order to be resolvable to DID documents, DIDs are typically recorded on an underlying system or network of some kind. Regardless of the specific technology used, any such system that supports recording DIDs and returning data necessary to produce DID documents is called a verifiable data registry. Examples include distributed ledgers, decentralized file systems, databases of any kind, peer-to-peer networks, and other forms of trusted data storage.
DID documents
DID documents contain metadata associated with a DID. They typically express verification methods (such as public keys) and services relevant to interactions with the DID subject. A DID document is serialized according to a particular syntax (see ). The DID itself is the value of the `id` property. The generic properties supported in a DID document are specified in . The properties present in a DID document may be updated according to the applicable operations outlined in .
DID Methods
DID methods are the mechanism by which a particular type of DID and its associated DID document are created, resolved, updated, and deactivated using a particular verifiable data registry. DID methods are defined using separate DID method specifications (see ).

Conceptually, the relationship between this specification and a DID method specification is similar to the relationship between the IETF generic URI specification ([[RFC3986]]) and a specific URI scheme ([[IANA-URI-SCHEMES]] (such as the http: and https: schemes specified in [[RFC7230]]). It is also similar to the relationship between the IETF generic URN specification ([[RFC8141]]) and a specific URN namespace definition, (such as the UUID URN namespace defined in [[RFC4122]]). The difference is that a DID method specification, as well as defining a specific DID scheme, also specifies the methods creating, resolving, updating, and deactivating DIDs and DID documents using a specific type of verifiable data registry.

DID resolvers and DID resolution
A DID resolver is a software and/or hardware component that takes a DID (and associated options) as input and produces a conforming DID document (and associated metadata) as output. This process is called DID resolution. The inputs and outputs of the DID resolution process are defined in . The specific steps for resolving a specific type of DID are defined by the relevant DID method specification. Additional considerations for implementing a DID resolver are discussed in [[DID-RESOLUTION]].
DID URL dereferencers and DID URL dereferencing
A DID URL dereferencer is a software and/or hardware component that takes a DID URL (and associated options) as input and produces a resource (and associated metadata) as output. This process is called DID URL dereferencing. The inputs and outputs of the DID URL dereferencing process are defined in . Additional considerations for implementing a DID URL dereferencer are discussed in [[DID-RESOLUTION]].

This document contains examples that contain JSON, CBOR, and JSON-LD content. Some of these examples contain characters that are invalid, such as inline comments (//) and the use of ellipsis (...) to denote information that adds little value to the example. Implementers are cautioned to remove this content if they desire to use the information as valid JSON, CBOR, or JSON-LD.

Interoperability of implementations for DIDs and DID documents will be tested by evaluating an implementation's ability to create and parse DIDs and DID documents that conform to the specification. Interoperability for producers and consumers of DIDs and DID documents is provided by ensuring the DIDs and DID documents conform. Interoperability for DID method specifications is provided by the details in each DID method specification. It is understood that, in the same way that a web browser is not required to implement all known URI schemes, conformant software that works with DIDs is not required to implement all known DID methods (however, all implementations of a given DID method must be interoperable for that method).

A conforming DID is any concrete expression of the rules specified in Section and MUST comply with relevant normative statements in that section.

A conforming DID document is any concrete expression of the data model described in this specification and MUST comply with the relevant normative statements in Sections and . A serialization format for the conforming document MUST be deterministic, bi-directional, and lossless as described in Section . The conforming DID document MAY be transmitted or stored in any such serialization format.

A conforming DID method is any specification that complies with the relevant normative statements in Section .

A conforming producer is any algorithm realized as software and/or hardware and conforms to this specification if it generates conforming DIDs or conforming DID Documents. A conforming producer MUST NOT produce non-conforming DIDs or DID documents.

A conforming consumer is any algorithm realized as software and/or hardware and conforms to this specification if it consumes conforming DIDs or conforming DID documents. A conforming consumer MUST produce errors when consuming non-conforming DIDs or DID documents.

Terminology

Identifier

This section describes the formal syntax for DIDs and DID URLs. The term "generic" is used to differentiate the syntax defined here from syntax defined by specific DID methods in their respective specifications.

DID Syntax

The generic DID scheme is a URI scheme conformant with [[!RFC3986]].

The DID scheme name MUST be lowercase.

The DID method name MUST be lowercase.

(An ASCII lowercase letter is a Unicode code point in the range U+0061 (a) to U+007A (z), inclusive.)

The following is the ABNF definition using the syntax in [[!RFC5234]], which defines ALPHA and DIGIT. All other rule names not defined in this ABNF are defined in [[RFC3986]].

did                = "did:" method-name ":" method-specific-id
method-name        = 1*method-char
method-char        = %x61-7A / DIGIT
method-specific-id = *( *idchar ":" ) 1*idchar
idchar             = ALPHA / DIGIT / "." / "-" / "_"
      

A DID method specification MUST further restrict the generic DID syntax by defining its own method-name and its own method-specific-id syntax. Case sensitivity and normalization of the value of the method-specific-id rule MUST be defined by the governing DID method specification. For more information, see Section .

A DID is expected to be persistent and immutable. That is, a DID is bound exclusively and permanently to its one and only subject. Even after a DID is deactivated, it is intended that it never be repurposed.

Ideally, a DID would be a completely abstract decentralized identifier (like a UUID) that could be bound to multiple underlying verifiable data registries over time, thus maintaining its persistence independent of any particular system. However, registering the same identifier on multiple verifiable data registries makes it extremely difficult to identify the authoritative version of a DID document if the contents diverge between the different verifiable data registries. It also greatly increases implementation complexity for developers.

To avoid these issues, developers should refer to the Decentralized Characteristics Rubric [[?DID-RUBRIC]] to decide which DID method best addresses the needs of the use case.

DID URL Syntax

A DID URL always identifies a resource to be located. It can be used, for example, to identify a specific part of a DID document.

This following is the ABNF definition using the syntax in [[!RFC5324]]. It builds on the did scheme defined in . The path-abempty and fragment components are identical to the ABNF rules defined in [[!RFC3986]], and the did-query component is derived from the query ABNF rule.

did-url            = did path-abempty [ "?" did-query ]
                     [ "#" fragment ]
did-query          = param *( "&" param )
param              = param-name "=" param-value
param-name         = 1*pchar
param-value        = *pchar
      

This specification reserves the semicolon (;) character for possible future use as a sub-delimiter for parameters as described in [[?MATRIX-URIS]].

Generic DID URL Parameters

The DID URL syntax supports a simple, generalized format for parameters based on the query component (See ). The ABNF above specifies the basic syntax (the param rule) but does not specify any concrete parameter names.

Some generic DID parameter names (for example, for service selection) are completely independent of any specific DID method and MUST always function the same way for all DIDs. Other DID parameter names (for example, for versioning) MAY be supported by certain DID methods, but MUST operate uniformly across those DID methods that do support them.

Parameter names that are completely method-specific are described in Section .

The following table defines a set of generic DID parameter names.

Generic DID Parameter Name Description
hl A resource hash of the DID document to add integrity protection, as specified in [[?HASHLINK]].
service Identifies a service from the DID document by service ID.
version-id Identifies a specific version of a DID document to be resolved (the version ID could be sequential, or a UUID, or method-specific). Note that this parameter might not be supported by all DID methods.
version-time Identifies a certain version timestamp of a DID document to be resolved. That is, the DID document that was valid for a DID at a certain time. Note that this parameter might not be supported by all DID methods.

Additional considerations for processing these parameters are discussed in [[?DID-RESOLUTION]].

Two example DID URLs using the service and version-time generic DID parameters are shown below.

did:foo:21tDAKCERh95uGgKbJNHYp?service=agent
        
did:foo:21tDAKCERh95uGgKbJNHYp?version-time=2002-10-10T17:00:00Z
        

Adding a DID parameter to a DID URL means that the parameter becomes part of an identifier for a resource (the DID document or other). Alternatively, the DID resolution and the DID URL dereferencing functions can also be influenced by passing input metadata to a DID resolver that are not part of the DID URL. (See ). Such options could for example control caching or the desired encoding of a resolution result. 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. The important distinction is that DID parameters that are part of the DID URL should be used to specify what resource is being identified, whereas DID resolution options that are not part of the DID URL should be use to control how that resource is resolved or dereferenced.

DID parameters MAY be used if there is a clear use case where the parameter needs to be part of a URI that can be used as a link, or as a resource in RDF / JSON-LD documents.

DID parameters SHOULD NOT be used if there are already other, equivalent ways of constructing URIs that fulfill the same purpose (for example, using other syntactical constructs such as URI query strings or URI fragments).

DID parameters SHOULD NOT be used if the same functionality can be expressed by passing options to a DID resolver, and if there is no need to construct a URI for use as a link, or as a resource in RDF / JSON-LD documents.

Method-Specific DID URL Parameters

A DID method specification MAY specify additional method-specific parameter names. A method-specific parameter name MUST be prefixed by the method name, as defined by the method-name rule.

For example, if the method did:foo: defines the parameter bar, the parameter name must be foo:bar. An example DID URL using this method and this method-specific parameter would be as shown below.

did:foo:21tDAKCERh95uGgKbJNHYp?foo:bar=high
        

A method-specific parameter name defined by one DID method MAY be used by other DID methods.

did:example:21tDAKCERh95uGgKbJNHYp?foo:bar=low
        

Method-specific parameter names MAY be combined with generic parameter names in any order.

did:example:21tDAKCERh95uGgKbJNHYp?service=agent&foo:bar=high
        

Both DID method namespaces and method-specific parameter namespaces MAY include colons, so they might be partitioned hierarchically, as defined by a DID method specification. The following example DID URL illustrates both.

did:foo:baz:21tDAKCERh95uGgKbJNHYp?foo:baz:hex=b612
        

Review what exactly we want to say about method-specific parameters defined by one method but used in a DID URL with a different method. Also discuss hierarchical method namespaces in DID parameter names.

Path

A DID path is identical to a generic URI path and MUST conform to the path-abempty ABNF rule in [[!RFC3986]]. A DID path SHOULD be used to address resources available through a service endpoint. For more information, see Section .

A DID method specification MAY specify ABNF rules for DID paths that are more restrictive than the generic rules in this section.

did:example:123456/path
        

Query

A DID query is derived from a generic URI query and MUST conform to the did-query ABNF rule in Section . If a DID query is present, it MUST be used as described in Sections and .

A DID method specification MAY specify ABNF rules for DID queries that are more restrictive than the generic rules in this section.

did:example:123456?query=true
        

Fragment

A DID fragment is used as method-independent reference into the DID document to identify a component of the document (for example, a unique public key description or service endpoint). DID fragment syntax and semantics are identical to a generic URI fragment and MUST conform to RFC 3986, section 3.5. To dereference a DID fragment, the complete DID URL including the DID fragment MUST be used as input to the DID URL dereferencing function for the target component in the DID document object. For more information, see .

A DID method specification MAY specify ABNF rules for DID fragments that are more restrictive than the generic rules in this section.

did:example:123456#public-key-1
        

In order to maximize interoperability, implementers are urged to ensure that DID fragments are interpreted in the same way across representations (as described in ). For example, while JSON Pointer [[?RFC6901]] can be used in a DID fragment, it will not be interpreted in the same way across representations.

Additional semantics for fragment identifiers, which are compatible with and layered upon the semantics in this section, are described for JSON-LD representations in Section .

Relative DID URLs

A relative DID URL is any URL value in a DID document that does not start with did:<method-name>:<method-specific-id>. More specifically, it is any URL value that does not start with the ABNF defined in Section . The contents of the URL typically refers to a resource in the same DID document. Relative DID URLs MAY contain relative path components, query parameters, and fragment identifiers.

When resolving a relative DID URL reference, the algorithm specified in RFC3986 Section 5: Reference Resolution MUST be used. The base URI value is the DID that is associated with the DID subject, see Section . The scheme is did. The authority is a combination of <method-name>:<method-specific-id>, and the path, query, and fragment values are those defined in Section , Section , and Section , respectively.

Relative DID URLs are often used to identify verification methods and services in a DID Document without having to use absolute URLs, which tend to be more verbose than necessary.

{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:example:123456789abcdefghi",
  "publicKey": [{
    "id": "did:example:123456789abcdefghi#key-1",
    "type": "Ed25519VerificationKey2018",
    "controller": "did:example:123456789abcdefghi",
    "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
  }, ...],
  "authentication": [
    // a relative DID URL used to reference a verification method above
    "#key-1"
  ]
}
        

In the example above, the relative DID URL value will be transformed to an absolute DID URL value of did:example:123456789abcdefghi#key-1.

Data Model

This specification defines an abstract data model for DID documents, independent of any specific representation. This section provides a high-level description of the data model, a set of requirements for representations, and a set of requirements for extensibility.

Definition

A DID document consists of a collection of properties, which are name-value pairs (ie. a property name, and a property value). The definitions of each of these properties are specified in section . Specific representations are defined in section .

Representations

Following are the requirements for representations.

  1. A representation MUST define an unambiguous encoding and decoding of all property names and their associated values as defined in this specification. This means anything you can represent in the DID document data model can be represented in any compliant representation.
  2. The representation MUST be associated with an IANA-registered MIME type.
  3. The representation MUST define fragment processing rules for its MIME type that are conformant with the fragment processing rules defined in section of this specification.

The core representations are specified in section .

Extensibility

The data model supports two types of extensibility.

  1. For maximum interoperability, it is RECOMMENDED that extensions use the official W3C DID Specification Registries mechanism [[DID-SPEC-REGISTRIES]]. The use of this mechanism for new properties or other extensions is the only specified method that ensures that two different representations will be able to work together.
  2. Representations MAY define other extensibility mechanisms including methods for decentralized extensions. Such extension mechanisms MUST support lossless conversion into any other conformant representation.

It is always possible for two specific implementations to agree out-of-band to use a mutually understood extension or representation that is not recorded in the DID Core Registries [[DID-SPEC-REGISTRIES]]; interoperability between such implementations and the larger ecosystem will be less reliable.

Core Properties

A DID points to a DID document. DID documents are the serialization of the data model outlined in Section . The following sections define the properties in a DID document, including whether these properties are required or optional.

Identifiers

Identifiers are used in the data model to identify specific instances of people, organizations, devices, keys, services, and things in general. Identifiers are typically URLs, or more generally, URIs. Non-URI-based identifiers are not advised because, while the data model supports them, they are not easy to use with other Internet-based identifiers.

DID Subject

The DID subject is denoted with the id property. The DID subject is the entity that the DID document is about. That is, it is the entity identified by the DID and described by the DID document.

DID documents MUST include the id property.

id
The value of id MUST be a single valid DID.
{
  "id": "did:example:21tDAKCERh95uGgKbJNHYp"
}
      

DID method specifications can create intermediate representations of a DID document that do not contain the id property, such as when a DID resolver is performing DID resolution. However, the fully resolved DID document always contains a valid id property. The value of id in the resolved DID document is expected to match the DID that was resolved.

Verification Methods

A DID document can express verification methods, such as cryptographic keys, which can be used to authenticate or authorize interactions with the DID subject or associated parties. The information expressed often includes globally unambiguous identifiers and public key material, which can be used to verify digital signatures. For example, a public key can be used as a verification method with respect to a digital signature; in such usage, it verifies that the signer possessed the associated private key.

Verification methods might take many parameters. An example of this is a set of five cryptographic keys from which any three are required to contribute to a threshold signature. Methods need not be cryptographic. An example of this might be the contact information for a biometric service provider that compares a purported DID controller against a candidate biometric vector.

A DID document MAY include a verificationMethod property.

verificationMethod
If a DID document includes a verificationMethod property, the value of the property MUST be an unordered set of verification methods, where each verification method is described by a set of properties. The set of properties MUST include the id, type, controller, and specific verification method properties, and MAY include additional properties.

The value of the id property for a verification method MUST be a URI. When more than one verification method is present, the value of verificationMethod MUST NOT contain multiple entries with the same id. If the value of verificationMethod contains multiple entries with the same id, a DID document processor MUST produce an error.

The value of the type property MUST be exactly one verification method type. In order to maximize global interoperability, the verification method type SHOULD be registered in the [[DID-SPEC-REGISTRIES]].

The value of the controller property, MUST be a valid DID.

In order to maximize global interoperability, the verification method SHOULD be registered in the [[DID-SPEC-REGISTRIES]].

{
  "@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/v1"],
  "id": "did:example:123456789abcdefghi",
  ...
  "verificationMethod": [{
    "id": ...,
    "type": ...,
    "controller": ...,
    ...
  ]}
}
      

Public Keys

A public key is a verification method. Public keys are used for digital signatures, encryption and other cryptographic operations, which in turn are the basis for purposes such as authentication (see Section ) or establishing secure communication with service endpoints (see Section ). As well, public keys can play a role in authorization mechanisms of DID method operations (see Section ), which can be defined by DID method specifications.

Public keys can be included in a DID document using the publicKey or authentication properties, depending on what they are to be used for. Each public key has properties for an identifier (id) of its own, a type, and a controller, as well as other properties that depend on the type of key it is.

This specification strives to limit the number of formats for expressing public key material in a DID Document to the fewest possible, to increase the likelihood of interoperability. The fewer formats that implementers have to implement, the more likely it will be that they will support all of them. This approach attempts to strike a delicate balance between ease of implementation and supporting formats that have historically had broad deployment. The specific types of key formats that are supported in this specification are listed below.

A DID document MAY include a publicKey property.

publicKey
If a DID document includes a publicKey property, the value of the property MUST be an unordered set of public keys, where each public key is described by a set of properties. Each public key MUST have the id, type, controller, and specific public key properties, and MAY include additional properties.

The value of the id property MUST be a URI. The value of publicKey MUST NOT contain multiple entries with the same id. In this case, a DID document processor MUST produce an error.

The value of the type property MUST be exactly one public key type. For a registry of available key types and formats, see [[DID-SPEC-REGISTRIES]].

The value of the controller property, which identifies the controller of the corresponding private key, MUST be a valid DID.

The semantics of the controller property are the same when the subject of the relationship is the DID document as when the subject of the relationship is a key. Since a key can't control itself, and the key controller cannot be inferred from the DID document, it is necessary to explicitly express the identity of the controller of the key (which may be the DID controller or DID subject). The difference is that the value of controller on a key is not necessarily a DID controller. DID controller(s) are expressed using the controller property on the top level of the DID document; see Section .

The value of the id property MAY be structured as a compound key. This is especially useful for integrating with existing key management systems and key formats such as JWK. It is RECOMMENDED that JWK kid values are set to the public key fingerprint. It is RECOMMENDED that verification methods that use JWKs to represent their public keys utilize the value of kid as their fragment identifier. See the first key in EXAMPLE 15 for an example of a public key with a compound key identifier.

All public key property names MUST be registered in the [[DID-SPEC-REGISTRIES]].

If a public key does not exist in the DID document, it MUST be assumed the key was revoked or is invalid. The DID document MUST NOT express revoked keys using a verification relationship. Each DID method specification is expected to detail how revocation is performed and tracked.

Public keys of all types MUST be expressed in either JSON Web Key (JWK) format using the publicKeyJwk property or one of the formats listed in the table below. Public key expression MUST NOT use any other key format.

The Working Group is still debating whether the base encoding format used will be Base58 (Bitcoin) [[BASE58]], base64url [[RFC7515]], or base16 (hex) [[RFC4648]]. The entries in the table below currently assume PEM and Base58 (Bitcoin), but might change to base64url and/or base16 (hex) after the group achieves consensus on this particular issue.

The Working Group is still debating whether secp256k1 Schnorr public key values will be elaborated upon in this specification and if so, how they will be expressed and encoded.

Key Type Support
RSA RSA public key values MUST either be encoded as a JWK or be encoded in Privacy Enhanced Mail (PEM) format using the publicKeyPem property.
ed25519 Ed25519 public key values MUST either be encoded as a JWK or be encoded as the raw 32-byte public key value in Base58 Bitcoin format using the publicKeyBase58 property.
secp256k1-koblitz Secp256k1 Koblitz public key values MUST either be encoded as a JWK or be encoded as the raw 33-byte public key value in Base58 Bitcoin format using the publicKeyBase58 property.
secp256r1 Secp256r1 public key values MUST either be encoded as a JWK or be encoded as the raw 32-byte public key value encoded in Base58 Bitcoin format using the publicKeyBase58 property.
Curve25519 Curve25519 (also known as X25519) public key values MUST either be encoded as a JWK or be encoded as the raw 32-byte public key value in Base58 Bitcoin format using the publicKeyBase58 property.

Example:

{
  "@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/v1"],
  "id": "did:example:123456789abcdefghi",
  ...
  "publicKey": [{
    "id": "did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
    "type": "JwsVerificationKey2020",
    "controller": "did:example:123",
    "publicKeyJwk": {
      "crv": "Ed25519",
      "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ",
      "kty": "OKP",
      "kid": "_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"
    }
  }, {
    "id": "did:example:123456789abcdefghi#keys-1",
    "type": "Ed25519VerificationKey2018",
    "controller": "did:example:pqrstuvwxyz0987654321",
    "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
  }, {
    "id": "did:example:123456789abcdefghi#keys-2",
    "type": "Secp256k1VerificationKey2018",
    "controller": "did:example:123456789abcdefghi",
    "publicKeyHex": "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
  }],
  ...
}
      

A key MAY be embedded or referenced in a DID document. For example, the authentication property might refer to keys in both ways, as shown in the example below.

{
...

  "authentication": [
    // this key is referenced, it may be used with more than one verification relationship
    "did:example:123456789abcdefghi#keys-1",
    // this key is embedded and may *only* be used for authentication
    {
      "id": "did:example:123456789abcdefghi#keys-2",
      "type": "Ed25519VerificationKey2018",
      "controller": "did:example:123456789abcdefghi",
      "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
    }
  ],

...
}
      

The steps to use when processing a publicKey property in a DID document are:

  1. Let value be the data associated with the publicKey property and initialize result to null.
  2. If value is an object, the key material is embedded. Set result to value.
  3. If value is a string, the key is included by reference. Assume value is a URL.
    1. Dereference the URL and retrieve the publicKey properties associated with the URL. For example, process the publicKey property at the top-level of the dereferenced document.
    2. Iterating through each public key object, if the id property of the object matches value, set result to the object.
  4. If result does not contain at least the id, type, and controller properties, as well as any mandatory public cryptographic material, as determined by the type property of result, throw an error.

Caching and expiration of the keys in a DID document is entirely the responsibility of DID resolvers and other clients. For more information, see Section .

Authorization and Delegation

Authorization is the mechanism used to state how operations are performed on behalf of the DID subject. Delegation is the mechanism that the subject uses to authorize others to act on their behalf.

Note that Authorization is separate from . This is particularly important for key recovery in the case of key loss, when the subject no longer has access to their keys, or key compromise, where the DID controller's trusted third parties need to override malicious activity by an attacker. See Section .

A DID document MAY include a controller property to indicate the DID controller(s). If so:

controller
The value of the controller property MUST be one or more valid DIDs. The corresponding DID document(s) SHOULD contain verification relationships that explicitly permit the use of certain verification methods for specific purposes.

If the controller property is not present, the DID controller can be determined by consulting the respective DID method specification. It cannot be assumed that the DID subject is also the controller of its own DID, nor can it be assumed that only entities identified by DIDs present in the value of controller are capable of exerting control over the DID in question. Similarly, DID methods are not obliged to respect the value of controller and can specify means for updating the DID document that are unrelated to the controller property.

Each DID method MUST define how authorization and delegation are implemented, including any necessary cryptographic operations.

There are at least two suggested methods for implementing Authorization and Delegation, which may be layered:

{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:example:123456789abcdefghi",
  "controller": "did:example:bcehfew7h32f32h7af3",
  "service": [{
    // used to retrieve Verifiable Credentials
    associated with the DID
    "type": "VerifiableCredentialService",
    "serviceEndpoint": "https://example.com/vc/"
  }]
}
      

Verification Relationships

A verification relationship expresses the relationship between the DID subject and a verification method.

A DID document MAY include a property expressing a specific verification relationship. In order to maximize global interoperability, the property SHOULD be registered in [[DID-SPEC-REGISTRIES]].

A DID controller MUST be explicit about the verification relationship between the DID subject and the verification method. Verification methods that are not associated with a particular verification relationship MUST NOT be used for that verification relationship. See the sections below for more detailed examples of a verification relationship.

authentication

Authentication is a verification relationship which an entity can use to prove it is the DID subject or acting on behalf of the DID Subject as a DID Controller. The verifier of an authentication attempt can check if the authenticating party is presenting a valid proof of authentication, that is, that they are who they say they are. Note that a successful authentication on its own might or might not confer authority; that is up to the verifying application.

If authentication is established, it is up to the DID method or other application to decide what to do with that information. A particular DID method could decide that authenticating as a DID controller is sufficient to, for example, update or delete the DID document. Another DID method could require different keys, or a different verification method entirely, to be presented in order to update or delete the DID document than that used to authenticate. In other words, what is done after the authentication check is out of scope for the DID data model, but DID methods and applications are expected to define this themselves.

A DID document MAY include an authentication property. The authentication property is an example of a verification relationship.

authentication
The authentication property is a relationship between the DID subject and a set of verification methods (such as, but not limited to, public keys). It means that the DID subject has authorized some set of verification methods (per the value of the authentication property) for the purpose of authentication. The value of the authentication property SHOULD be an unordered set of verification methods. Each verification method MAY be embedded or referenced. An example of a verification method is a public key (see Section ).

This statement is useful to any authentication verifier that needs to check to see if an entity that is attempting to authenticate is, in fact, presenting a valid proof of authentication. When a verifier receives some data (in some protocol-specific format) that contains a proof that was made for the purpose of "authentication", and that says that an entity is identified by the DID, then that verifier checks to ensure that the proof can be verified using a verification method (e.g., public key) listed under authentication in the DID Document.

The verification method indicated by the authentication property of a DID document can only be used to authenticate the DID subject. To authenticate the DID controller (in cases where the DID controller is not also the DID subject) the entity associated with the value of controller (see Section ) needs to authenticate itself with its own DID document and attached authentication verification relationship.

Example:

{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:example:123456789abcdefghi",
  ...
  "authentication": [
    // this method can be used to authenticate as did:...fghi
    "did:example:123456789abcdefghi#keys-1",
    // this method can be used to authenticate as did:...fghi
    "did:example:123456789abcdefghi#biometric-1",
    // this method is *only* authorized for authentication, it may not
    // be used for any other proof purpose, so its full description is
    // embedded here rather than using only a reference
    {
      "id": "did:example:123456789abcdefghi#keys-2",
      "type": "Ed25519VerificationKey2018",
      "controller": "did:example:123456789abcdefghi",
      "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
    }
  ],
  ...
}
        

assertionMethod

The assertionMethod property is used to express a verification relationship which indicates that a verification method can be used to assert a statement on behalf of the DID subject. The verifier of an assertionMethod attempt can check proof of a statement asserted on behalf of the DID subject by checking if the verification method used with the proof is contained in the assertionMethod of the DID Document.

If assertionMethod is established, it is up to the verifier to validate that the verification method used for providing proof of an assertion is valid and is associated with the assertionMethod verification relationship. An example of when this property is useful is during the processing of a verifiable credential by a verifier. During validation, a verifier checks to see if a verifiable credential has been signed by the DID Subject by checking that the verification method used to assert the proof is associated with the assertionMethod property in the corresponding DID Document.

A DID document MAY include an assertionMethod property. The assertionMethod property is an example of a verification relationship.

Example:

{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:example:123456789abcdefghi",
  ...
  "assertionMethod": [
    // this method can be used to assert statements as did:...fghi
    "did:example:123456789abcdefghi#keys-1",
    // this method is *only* authorized for assertion of statements, it may not
    // be used for any other verification relationship, so its full description is
    // embedded here rather than using only a reference
    {
      "id": "did:example:123456789abcdefghi#keys-2",
      "type": "Ed25519VerificationKey2018",
      "controller": "did:example:123456789abcdefghi",
      "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
    }
  ],
  ...
}
        

keyAgreement

The keyAgreement property is used to express a verification relationship which an entity can use to engage in key agreement protocols on behalf of the DID subject. The counterparties in a key agreement protocol can use the keyAgreement verification relationship to check whether a party performing a key agreement protocol on behalf of the DID subject is authorized by checking if the verification method used during the key agreement protocol is associated with the keyAgreement property contained in the DID Document.

It is up to a verifier to validate that the verification method used during a key agreement exchange is valid and is associated with the keyAgreement property. An example of when this property is useful is during the establishment of a TLS session on behalf of the DID Subject. In this case, the counterparty checks that the verification method used during the protocol handshake is associated with the keyAgreement property in the DID Document.

A DID document MAY include an keyAgreement property. The keyAgreement property is an additional example of a verification relationship.

Example:

{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:example:123456789abcdefghi",
  ...
  "keyAgreement": [
    // this method can be used to perform key agreement as did:...fghi
    "did:example:123456789abcdefghi#keys-1",
    // this method is *only* authorized for key agreement usage, it may not
    // be used for any other verification relationship, so its full description is
    // embedded here rather than using only a reference
    {
      "id": "did:example:123#zC9ByQ8aJs8vrNXyDhPHHNNMSHPcaSgNpjjsBYpMMjsTdS",
      "type": "X25519KeyAgreementKey2019",
      "controller": "did:example:123",
      "publicKeyBase58": "9hFgmPVfmBZwRvFEyniQDBkz9LmV7gDEqytWyGZLmDXE"
    }
  ],
  ...
}

        

capabilityInvocation

The capabilityInvocation property is used to express a verification relationship which an entity can use to invoke capabilities as the DID subject or on behalf of the DID subject. A capability is an expression of an action that the DID subject is authorized to take. The verifier of a capability invocation attempt can check the validity of a capability by checking if the verification method used with the proof is contained in the capabilityInvocation property of the DID Document.

It is the responsibility of a verifier to ensure that the verification method used when presenting a capability is invoked and is associated with the capabilityInvocation property. An example of when this property is useful is when a DID subject chooses to invoke their capability to start a vehicle through the combined usage of a verification method and the StartCar capability. In this example, the vehicle would be the verifier and would need to verify that the verification method exists in the capabilityInvocation property.

A DID document MAY include an capabilityInvocation property. The capabilityInvocation property is an additional example of a verification relationship.

Example:

{
  "@context": "https://www.w3.org/ns/did/v1", "id":
  "did:example:123456789abcdefghi",
  ...
  "capabilityInvocation: [
    // this method can be used to invoke capabilities as did:...fghi
    "did:example:123456789abcdefghi#keys-1",
    // this method is *only* authorized for capability invocation usage, it may not
    // be used for any other verification relationship, so its full description is
    // embedded here rather than using only a reference
    {
    "id": "did:example:123456789abcdefghi#keys-2",
    "type": "Ed25519VerificationKey2018",
    "controller": "did:example:123456789abcdefghi",
    "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
    }
  ],
  ...
}

        

capabilityDelegation

The capabilityDelegation property is used to express a verification relationship which an entity can use to grant capabilities as the DID subject or on behalf of the DID subject to other capability invokers. The verifier of a capabilityDelegation attempt can check the validity of a capability to grant invocation of a capability by checking if the verification method used with the proof is contained in the capabilityDelegation section of the DID Document.

It is up to a verifier to validate that the verification method used when presenting a capability is valid and is associated with the capabilityDelegation property. An example of when this property is useful is when a DID Subject chooses to grant their capability to start a vehicle through the combined usage of a verification method and the StartCar capability to a capability invoker.

A DID document MAY include an capabilityDelegation property. The capabilityDelegation property is an additional example of a verification relationship.

Example:

{
  "@context": "https://www.w3.org/ns/did/v1", "id":
  "did:example:123456789abcdefghi",
  ...
  "capabilityDelegation": [
    // this method can be used to perform capabilty delegation as did:...fghi
    "did:example:123456789abcdefghi#keys-1",
    // this method is *only* authorized for granting capabilities it may not
    // be used for any other verification relationship, so its full description is
    // embedded here rather than using only a reference
    {
    "id": "did:example:123456789abcdefghi#keys-2",
    "type": "Ed25519VerificationKey2018",
    "controller": "did:example:123456789abcdefghi",
    "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
    }
  ],
  ...
}

        

Service Endpoints

Service endpoints are used in DID documents to express ways of communicating with the DID subject or associated entities. Services listed in the DID document can contain information about privacy preserving messaging services, or more public information, such as social media accounts, personal websites, and email addresses although this is discouraged. See for additional details. The metadata associated with services are often service-specific. For example, the metadata associated with an encrypted messaging service can express how to initiate the encrypted link before messaging begins.

Pointers to services are expressed using the service property. Each service has its own id and type properties, as well as a serviceEndpoint property with a URI or a set of other properties describing the service.

One of the primary purposes of a DID document is to enable discovery of service endpoints. A service endpoint can be any type of service the DID subject wants to advertise, including decentralized identity management services for further discovery, authentication, authorization, or interaction.

A DID document MAY include a service property.

service
If a DID document includes a service property, the value of the property SHOULD be an unordered set of service endpoints, where each service endpoint is described by a set of properties. Each service endpoint MUST have id, type, and serviceEndpoint properties, and MAY include additional properties.

The value of the id property MUST be a URI. The value of serviceEndpoint MUST NOT contain multiple entries with the same id. In this case, a DID document processor MUST produce an error.

The value of the serviceEndpoint property MUST be a valid URI conforming to [[RFC3986]] and normalized according to the rules in section 6 of [[RFC3986]] and to any normalization rules in its applicable URI scheme specification, OR a set of properties which describe the service endpoint further.

It is expected that the service endpoint protocol is published in an open standard specification.

{
  "service": [{
    "id": "did:example:123456789abcdefghi#openid",
    "type": "OpenIdConnectVersion1.0Service",
    "serviceEndpoint": "https://openid.example.com/"
  }, {
    "id": "did:example:123456789abcdefghi#vcr",
    "type": "CredentialRepositoryService",
    "serviceEndpoint": "https://repository.example.com/service/8377464"
  }, {
    "id": "did:example:123456789abcdefghi#xdi",
    "type": "XdiService",
    "serviceEndpoint": "https://xdi.example.com/8377464"
  }, {
    "id": "did:example:123456789abcdefghi#agent",
    "type": "AgentService",
    "serviceEndpoint": "https://agent.example.com/8377464"
  }, {
    "id": "did:example:123456789abcdefghi#hub",
    "type": "IdentityHub",
    "publicKey": "did:example:123456789abcdefghi#key-1",
    "serviceEndpoint": {
      "@context": "https://schema.identity.foundation/hub",
      "type": "UserHubEndpoint",
      "instances": ["did:example:456", "did:example:789"]
    }
  }, {
    "id": "did:example:123456789abcdefghi#messages",
    "type": "MessagingService",
    "serviceEndpoint": "https://example.com/messages/8377464"
  }, {
    "id": "did:example:123456789abcdefghi#inbox",
    "type": "SocialWebInboxService",
    "serviceEndpoint": "https://social.example.com/83hfh37dj",
    "description": "My public social inbox",
    "spamCost": {
      "amount": "0.50",
      "currency": "USD"
    }
  }, {
    "id": "did:example:123456789abcdefghi#authpush",
    "type": "DidAuthPushModeVersion1",
    "serviceEndpoint": "http://auth.example.com/did:example:123456789abcdefg"
  }]
}
      

For more information about security considerations regarding authentication service endpoints see Sections and .

Created

A DID document SHOULD include a created property.

created
If a DID document includes a created property, the value of the property MUST be a valid XML datetime value, as defined in section 3.3.7 of W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes [[XMLSCHEMA11-2]]. This datetime value MUST be normalized to UTC 00:00, as indicated by the trailing "Z".
{
  "created": "2002-10-10T17:00:00Z"
}
      

Updated

Standard metadata for identifier records includes a timestamp of the most recent change.

A DID document SHOULD include an updated property.

updated
If a DID document includes an updated property, the value of the property MUST follow the same formatting rules as the created property, as outlined in Section .
{
  "updated": "2016-10-17T02:41:00Z"
}
      

Core Representations

All concrete representations of a DID document MUST be serialized using a deterministic mapping that is able to be unambiguously parsed into the data model defined in this specification. All serialization methods MUST define rules for the bidirectional translation of a DID document both into and out of the representation in question. As a consequence, translation between any two representations MUST be done by parsing the source format into a DID document model (described in Sections and ) and then serializing the DID document model into the target representation. An implementation MUST NOT convert between representations without first parsing to a DID document model.

Although syntactic mappings are provided for JSON, JSON-LD, and CBOR here, applications and services MAY use any other data representation syntax that is capable of expressing the data model, such as XML or YAML.

Producers MUST indicate which representation of a document has been used via a media type in the document's metadata. Consumers MUST determine which representation a document is in via the content-type DID resolver metadata field. (See ). Consumers MUST NOT determine the representation of a document through its content alone.

This requirement depends on the return of DID document metadata that still needs to be defined by this specification. Once defined, that should be linked from here.

The production and consumption rules in this section apply to all implementations seeking to be fully compatible with independent implementations of the specification. Deployments of this specification MAY use a custom agreed-upon representation, including localized rules for handling properties not listed in the registry. See section for more information.

A link to a section on extensibility and conformance as it applies to data representations should be added here once that section has been written.

JSON

When producing and consuming DID documents that are in plain JSON (as indicated by a content-type of application/did+json in the resolver metadata), the following rules MUST be followed.

Production

A DID document MUST be a single JSON object conforming to [[!RFC8259]]. All top-level properties of the DID document MUST be represented by using the property name as the name of the member of the JSON object. The values of properties of the data model described in Section , including all extensions, MUST be encoded in JSON [[RFC8259]] by mapping property values to JSON types as follows:

  • Numeric values representable as IEEE754 MUST be represented as a Number type.
  • Boolean values MUST be represented as a Boolean literal.
  • Sequence value MUST be represented as an Array type.
  • Unordered sets of values MUST be represented as an Array type.
  • Sets of properties MUST be represented as an Object type.
  • Empty values MUST be represented as a null literal.
  • Other values MUST be represented as a String type.

An "empty" value is not specified by this document. It seems to imply a null value, but this is unclear.

All properties of the DID document MUST be included in the root object. Properties MAY define additional data sub structures subject to the value representation rules in the list above.

The member name @context MUST NOT be used as this property is reserved for JSON-LD producers.

Consumption

In this section and we use the term "property name" to refer to the string that represents the property itself, but this specification still needs to define a concrete term for such aspects of a property of a DID document. We also need a concrete term for "the document itself" as opposed to "the collection or properties of the document".

The top-level element MUST be a JSON object. Any other data type at the top level is an error and MUST be rejected. The top-level JSON object represents the DID document, and all members of this object are properties of the DID document. The object member name is the property name, and the member value is interpreted as follows:

  • Number types MUST interpreted as numeric values representable as IEEE754.
  • Boolean literals MUST be interpreted as a Boolean value.
  • An Array type MUST be interpreted as a Sequence or Unordered set, depending on the definition of the property for this value.
  • An Object type MUST be interpreted as a sets of properties.
  • A null literal MUST be interpreted as an Empty value.
  • String types MUST be interpreted as Strings, which may be further parsed depending on the definition of the property for this value into more specific data types such as URIs, date stamps, or other values.

An "empty" value is not specified by this document. It seems to imply a null value, but this is unclear.

The value of the @context object member MUST be ignored as this is reserved for JSON-LD consumers.

Unknown object member names MUST be ignored as unknown properties.

This specification needs to define clear and consistent rules for how to handle unknown data members on consumption, and this section needs to be updated with that decision.

JSON-LD

[[!JSON-LD]] is a JSON-based format used to serialize Linked Data.

When producing and consuming DID documents that are in JSON-LD (as indicated by a content-type of application/did+ld+json in the resolver metadata), the following rules MUST be followed.

Production

The DID document is serialized following the rules in the JSON processor, with one addition: DID documents MUST include the @context property.

@context
The value of the @context property MUST be one or more URIs, where the value of the first URI is https://www.w3.org/ns/did/v1. All members of the @context property MUST exist be in the DID properties extension registry.

This specification defines globally interoperable documents, and the requirement that the context value be in the verifiable data registry means that different JSON-LD processors can consume the document without having to dereference anything in the context field. However, a pair of producers and consumers can have local extension agreements. This needs to be clarified in a section on extensibility and linked here when available.

Consumption

The top-level element MUST be a JSON object. Any other data type at the top level is an error and MUST be rejected. This top-level JSON object is interpreted using JSON-LD processing under the rules of the defined @context fields.

@context
The value of the @context property MUST be one or more URIs, where the value of the first URI is https://www.w3.org/ns/did/v1. If more than one URI is provided, the URIs MUST be interpreted as an ordered set. It is RECOMMENDED that dereferencing each URI results in a document containing machine-readable information about the context.

Unknown object member names MUST be ignored as unknown properties.

This specification needs to define clear and consistent rules for how to handle unknown data members on consumption, and this section needs to be updated with that decision.

CBOR

Like Javascript Object Notation (JSON) [[RFC8259]], Concise Binary Object Representation (CBOR) [[RFC7049]] defines a set of formatting rules for the portable representation of structured data. CBOR is a more concise, machine-readable, language-independent data interchange format that is self-describing and has built-in semantics for interoperability. With specific constraints, CBOR can support all JSON data types (including JSON-LD) for translation between the DID document model (described in Data Model and DID Documents) and other core representations.

Concise Data Definition Language (CDDL) [[RFC8610]] is a notation used to express Concise Binary Object Representation (CBOR), and by extension JSON Data Structures. The following notation expresses the DID Document model in CBOR representation with specific constraints for deterministic mappings between other core representations.

DID-document = {
  ? @context : uri
  id : did
  ? publicKey : [* publicKey ]
  ? authentication :  [ *did // *publicKey // *tstr ]
  ? service : [ + service  ]
  ? controller : did / [ *did ]
  ? created : time
  ? updated : time
  proof :  any
}

publicKey = {
  id : did
  type : text
  controller : uri
}

did = tstr .pcre "^did\\:(?<method-name>[a-z0-9]{2,})\\:(?<method-specific-id>[A-Za-z0-9\\.\\-\\:\\_]+)"

did-url =  tstr .pcre "^did\\:(?<method-name>[a-z0-9]{2,})\\:(?<method-specific-id>[A-Za-z0-9\\.\\-\\:\\_]+)\\;(?<path>[A-Za-z0-9\\/)(?<query>\\?[a-z0-9\\=\\&])#(?<fragment>.+)"

service = {
  id : did-url
  type : text
  serviceEndpoint : uri
  ? description : text
  * tstr => any
}
      

Production

When producing DID Documents that are represented as CBOR, in addition to the suggestions in section 3.9 of the CBOR [[RFC7049]] specification for deterministic mappings, the following constraints of the DID Document model MUST be followed:

  • Map keys MUST be strings.
  • Integer encoding MUST be as short as possible.
  • The expression of lengths in CBOR major types 2 through 5 MUST be as short as possible.
  • All floating point values MUST be encoded as 64-bits, even for integral values.
    a7                                                # map(7)
    62                                                #   text(2)
       6964                                           #     "id"
    78 40                                             #   text(64)
       6469643a6578616d706c653a31324433               #     "did:example:12D3"
       4b6f6f574d4864727a6377706a626472               #     "KooWMHdrzcwpjbdr"
       5a733547477145524176636771583362               #     "Zs5GGqERAvcgqX3b"
       3564707550745061396f743639796577               #     "5dpuPtPa9ot69yew"
    65                                                #   text(5)
       70726f6f66                                     #     "proof"
    a4                                                #   map(4)
       64                                             #     text(4)
          74797065                                    #       "type"
       74                                             #     text(20)
          656432353531395369676e617475726532303138    #       "ed25519Signature2018"
       67                                             #     text(7)
          63726561746564                              #       "created"
       74                                             #     text(20)
          323032302d30352d30315430333a30303a30325a    #       "2020-05-01T03:00:02Z"
       67                                             #     text(7)
          63726561746f72                              #       "creator"
       78 8c                                          #     text(140)
          6469643a6578616d706c653a31324433            #       "did:example:12D3"
          4b6f6f574d4864727a6377706a626472            #       "KooWMHdrzcwpjbdr"
          5a733547477145524176636771583362            #       "Zs5GGqERAvcgqX3b"
          3564707550745061396f743639796577            #       "5dpuPtPa9ot69yew"
          3b206578616d706c653a6b65793d6964            #       "; example:key=id"
          3d626166797265696375627478357771            #       "=bafyreicubtx5wq"
          6f336e6f73633463617a726b63746668            #       "o3nosc4cazrkctfh"
          776436726577657a6770776f65347377            #       "wd6rewezgpwoe4sw"
          69726c733465626468733269                    #       "irls4ebdhs2i"
       6e                                             #     text(14)
          7369676e617475726556616c7565                #       "signatureValue"
       78 58                                          #     text(88)
          6f3972364c78676f474e38466f616565            #       "o9r6LxgoGN8Foaee"
          554136456444637631324776447a4645            #       "UA6EdDcv12GvDzFE"
          6d43676a577a76707572325953517941            #       "mCgjWzvpur2YSQyA"
          3857327230535357554b2b6e4835744d            #       "8W2r0SSWUK+nH5tM"
          717a61464c756e3677775a31456f7433            #       "qzaFLun6wwZ1Eot3"
          37616d4744673d3d                            #       "7amGDg=="
    67                                                #   text(7)
       63726561746564                                 #     "created"
    74                                                #   text(20)
       323031382d31322d30315430333a30303a30305a       #     "2018-12-01T03:00:00Z"
    67                                                #   text(7)
       75706461746564                                 #     "updated"
    74                                                #   text(20)
       323032302d30352d30315430333a30303a30305a       #     "2020-05-01T03:00:00Z"
    68                                                #   text(8)
       40636f6e74657874                               #     "@context"
    78 1c                                             #   text(28)
       68747470733a2f2f7777772e77332e6f               #     "https://www.w3.o"
       72672f6e732f6469642f7631                       #     "rg/ns/did/v1"
    69                                                #   text(9)
       7075626c69634b6579                             #     "publicKey"
    81                                                #   array(1)
       a5                                             #     map(5)
          62                                          #       text(2)
             6964                                     #         "id"
          78 85                                       #       text(133)
             6261667972656963756274783577716f         #         "bafyreicubtx5wqo"
             336e6f73633463617a726b6374666877         #         "3nosc4cazrkctfhw"
             6436726577657a6770776f6534737769         #         "d6rewezgpwoe4swi"
             726c7334656264687332693b6578616d         #         "rls4ebdhs2i;exam"
             706c653a6b65793d6964626166797265         #         "ple:key=idbafyre"
             6963756274783577716f336e6f736334         #         "icubtx5wqo3nosc4"
             63617a726b6374666877643672657765         #         "cazrkctfhwd6rewe"
             7a6770776f6534737769726c73346562         #         "zgpwoe4swirls4eb"
             6468733269                               #         "dhs2i"
          64                                          #       text(4)
             74797065                                 #         "type"
          6e                                          #       text(14)
             45644473615075626c69634b6579             #         "EdDsaPublicKey"
          65                                          #       text(5)
             6375727665                               #         "curve"
          67                                          #       text(7)
             65643235353139                           #         "ed25519"
          67                                          #       text(7)
             65787069726573                           #         "expires"
          74                                          #       text(20)
             323031392d31322d30315430333a30303a30305a #         "2019-12-01T03:00:00Z"
          6f                                          #       text(15)
             7075626c69634b6579426173653634           #         "publicKeyBase64"
          78 2c                                       #       text(44)
             716d7a3774704c4e4b4b4b646c376344         #         "qmz7tpLNKKKdl7cD"
             375062656a4469425670374f4e706d5a         #         "7PbejDiBVp7ONpmZ"
             62666d633763454b396d673d                 #         "bfmc7cEK9mg="
    6e                                                #   text(14)
       61757468656e7469636174696f6e                   #     "authentication"
    81                                                #   array(1)
       78 83                                          #     text(131)
          6469643a6578616d706c653a31324433            #       "did:example:12D3"
          4b6f6f574d4864727a6377706a626472            #       "KooWMHdrzcwpjbdr"
          5a733547477145524176636771583362            #       "Zs5GGqERAvcgqX3b"
          3564707550745061396f743639796577            #       "5dpuPtPa9ot69yew"
          3b6b65792d69643d6261667972656963            #       ";key-id=bafyreic"
          756274783577716f336e6f7363346361            #       "ubtx5wqo3nosc4ca"
          7a726b63746668776436726577657a67            #       "zrkctfhwd6rewezg"
          70776f6534737769726c733465626468            #       "pwoe4swirls4ebdh"
          733269                                      #       "s2i"
        

Consumption

When consuming DID Documents that are represented as CBOR, in addition to the suggestions in section 3.9 of the CBOR [[RFC7049]] specification for deterministic mappings the following constraints of the DID Document model MUST be followed:

  • The keys in every map must be sorted lowest value to highest. Sorting is performed on the bytes of the representation of the keys.
  • Indefinite-length items must be made into definite-length items.

CBOR Extensibility

In CBOR, one point of extensibility is with the use of CBOR tags. [[RFC7049]] defines a basic set of data types, as well as a tagging mechanism that enables extending the set of data types supported via the CBOR Tag Registry. This allows for tags to enhance the semantic description of the data that follows.

DagCBOR

DagCBOR is a further restricted subset of CBOR for representing the DID Document as a Directed Acyclic Graph model using canonical CBOR encoding as noted above with additional constraits. DagCBOR requires that there exist a single way of encoding any given object, and that encoded forms contain no superfluous data that may be ignored or lost in a round-trip decode/encode. When producing and consuming DID Documents representing in DagCBOR the following rules MUST be followed

  • Use no CBOR tags other than the CID tag (42)
{ "@context": "https://www.w3.org/ns/did/v1",
  "authentication": [
    "did:example:12D3KooWMHdrzcwpjbdrZs5GGqERAvcgqX3b5dpuPtPa9ot69yew;key-id=bafyreicubtx5wqo3nosc4cazrkctfhwd6rewezgpwoe4swirls4ebdhs2i"
  ],
  "created": "2018-12-01T03:00:00Z",
  "id": "did:example:12D3KooWMHdrzcwpjbdrZs5GGqERAvcgqX3b5dpuPtPa9ot69yew",
  "proof": {
    "created": "2020-05-01T03:00:02Z",
    "creator": "did:example:12D3KooWMHdrzcwpjbdrZs5GGqERAvcgqX3b5dpuPtPa9ot69yew; example:key=id=bafyreicubtx5wqo3nosc4cazrkctfhwd6rewezgpwoe4swirls4ebdhs2i",
    "signatureValue": "o9r6LxgoGN8FoaeeUA6EdDcv12GvDzFEmCgjWzvpur2YSQyA8W2r0SSWUK+nH5tMqzaFLun6wwZ1Eot37amGDg==",
    "type": "ed25519Signature2018"
  },
  "publicKey": [
    {
      "curve": "ed25519",
      "expires": "2019-12-01T03:00:00Z",
      "id": "bafyreicubtx5wqo3nosc4cazrkctfhwd6rewezgpwoe4swirls4ebdhs2i;example:key=idbafyreicubtx5wqo3nosc4cazrkctfhwd6rewezgpwoe4swirls4ebdhs2i",
      "publicKeyBase64": "qmz7tpLNKKKdl7cD7PbejDiBVp7ONpmZbfmc7cEK9mg=",
      "type": "EdDsaPublicKey"
    }
  ],
  "updated": "2020-05-01T03:00:00Z"
}
          

COSE signatures

A DID Document proof may be constructed using CBOR semantic tagging, such as tag 98 for CBOR Object Signing and Encryption (COSE) [[RFC8152]]

  D8 62                                        # tag(98)
  67                                           #   text(7)
     7061796c6f6164                            #     "payload"
  d8 2a                                        #   tag(42)
     58 25                                     #     bytes(37)
        00017112206c8fdc5c3d2302dda95034       #       "\x00\x01q\x12 l\x8f\xdc\\=#\x02\xdd\xa9P4"
        f9de57a8591918ecb7d7789387c547f7       #       "\xf9\xdeW\xa8Y\x19\x18\xec\xb7\xd7x\x93\x87\xc5G\xf7"
        a89d05e72f                             #       "\xa8\x9d\x05\xe7/"
  69                                           #   text(9)
     70726f746563746564                        #     "protected"
  a0                                           #   map(0)
  6a                                           #   text(10)
     7369676e617475726573                      #     "signatures"
  81                                           #   array(1)
     a3                                        #     map(3)
        69                                     #       text(9)
           70726f746563746564                  #         "protected"
        66                                     #       text(6)
           613130313236                        #         "a10126"
        69                                     #       text(9)
           7369676e6174757265                  #         "signature"
        78 80                                  #       text(128)
           65326165616664343064363964313964    #         "e2aeafd40d69d19d"
           66653665353230373763356437666634    #         "fe6e52077c5d7ff4"
           65343038323832636265666235643036    #         "e408282cbefb5d06"
           63626634313461663265313964393832    #         "cbf414af2e19d982"
           61633435616339386238353434633930    #         "ac45ac98b8544c90"
           38623435303764653165393062373137    #         "8b4507de1e90b717"
           63336433343831366665393236613262    #         "c3d34816fe926a2b"
           39386635336166643266613066333061    #         "98f53afd2fa0f30a"
        6b                                     #       text(11)
           756e70726f746563746564              #         "unprotected"
        a1                                     #       map(1)
           63                                  #         text(3)
              6b6964                           #           "kid"
           78 85                               #         text(133)
              6469643a697069643a313244334b6f6f #           "did:ipid:12D3Koo"
              574d4864727a6377706a6264725a7335 #           "WMHdrzcwpjbdrZs5"
              47477145524176636771583362356470 #           "GGqERAvcgqX3b5dp"
              7550745061396f7436397965773b6970 #           "uPtPa9ot69yew;ip"
              69643a6b65792d69643d626166797265 #           "id:key-id=bafyre"
              6963756274783577716f336e6f736334 #           "icubtx5wqo3nosc4"
              63617a726b6374666877643672657765 #           "cazrkctfhwd6rewe"
              7a6770776f6534737769726c73346562 #           "zgpwoe4swirls4eb"
              6468733269                       #           "dhs2i"
  6b                                           #   text(11)
     756e70726f746563746564                    #     "unprotected"
  a0                                           #   tag(0)
          

Methods

DID methods provide the means to implement this specification on different verifiable data registries. New DID methods are defined in their own specifications, so that interoperability between different implementations of the same DID method is ensured. This section specifies the requirements on any DID method, which are met by the DID method's associated specification.

For adding properties to a DID document which are specific to a particular DID method, see .

Method Schemes

A DID method specification MUST define exactly one method-specific DID scheme, identified by exactly one method name (see the method-name rule in Section ).

The authors of a new DID method specification SHOULD use a method name that is unique among all DID method names known to them at the time of publication.

The method name SHOULD be five characters or less.

Because there is no central authority for allocating or approving DID method names, there is no way to know for certain if a specific DID method name is unique. To help with this challenge, a non-authoritative list of known DID method names and their associated specifications is maintained in the DID Methods Registry, which is part of [[?DID-SPEC-REGISTRIES]].

Authors of new DID method specifications are encouraged to add their method names to the DID Method Registry so that other implementors and members of the community have a place to see an overview of existing DID methods.

The DID method specification MUST specify how to generate the method-specific-id component of a DID.

The method-specific-id value MUST be able to be generated without the use of a centralized registry service.

The method-specific-id value SHOULD be globally unique by itself. Any DID generated by the method MUST be globally unique.

If needed, a method-specific DID scheme MAY define multiple method-specific-id formats. It is RECOMMENDED that a method-specific DID scheme define as few method-specific-id formats as possible.

The method-specific-id format MAY include colons. The use of colons MUST comply syntactically with the method-specific-id ABNF rule.

The meaning of colons in the method-specific-id is entirely method-specific. Implementers are advised to avoid assuming any meanings or behaviors associated with a colon that are generically applicable to all DID methods.

Method Operations

This section sets out the requirements for DID method specifications with regards to operations that can be performed on a DID document.

Determining the authority of a party to carry out the operations is method-specific. For example, a DID method MAY:

Create

The DID method specification MUST specify how a client creates a DID and its associated DID document on the verifiable data registry, including all cryptographic operations necessary to establish proof of control.

Read/Verify

The DID method specification MUST specify how a client uses a DID to request a DID document from the verifiable data registry, including how the client can verify the authenticity of the response.

Update

The DID method specification MUST specify how a client can update a DID document on the verifiable data registry, including all cryptographic operations necessary to establish proof of control, or state that updates are not possible.

An update to a DID is any change, after creation, in the data used to produce a DID document. DID Method implementers are responsible for defining what constitutes an update, and what properties of the DID document are supported by a given DID method. For example, an update operation which replaces key material without changing it could be a valid update that does not result in changes to the DID document.

Deactivate

The DID method specification MUST specify how a client can deactivate a DID on the verifiable data registry, including all cryptographic operations necessary to establish proof of deactivation, or state that deactivation is not possible.

Security Requirements

DID method specifications MUST include their own Security Considerations sections. This section MUST consider all the requirements mentioned in section 5 of [[RFC3552]] (page 27) for the DID operations defined in the specification.

At least the following forms of attack MUST be considered: eavesdropping, replay, message insertion, deletion, modification, and man-in-the-middle. Potential denial of service attacks MUST be identified as well.

This section MUST discuss, per Section 5 of [[RFC3552]], residual risks (such as the risks from compromise in a related protocol, incorrect implementation, or cipher) after threat mitigation was deployed.

This section MUST provide integrity protection and update authentication for all operations required by Section .

If the technology involves authentication, particularly user-host authentication, the security of the authentication method MUST be clearly specified.

DID methods MUST discuss the policy mechanism by which DIDs are proven to be uniquely assigned. A DID fits the functional definition of a URN, as defined in [[RFC8141]]. That is, a DID is a persistent identifier that is assigned once to a resource and never reassigned to a different resource. This is particularly important in a security context because a DID might be used to identify a specific party subject to a specific set of authorization rights.

Method-specific endpoint authentication MUST be discussed. Where DID methods make use of DLTs with varying network topology, sometimes offered as light node or thin client implementations to reduce required computing resources, the security assumptions of the topology available to implementations of the DID method MUST be discussed.

If the protocol incorporates cryptographic protection mechanisms, the DID method specification MUST clearly indicate which portions of the data are protected and what the protections are, and SHOULD give an indication to what sorts of attacks the cryptographic protection is susceptible. For example, integrity only, confidentiality, endpoint authentication, and so on.

Data which is to be held secret (keying material, random seeds, and so on) SHOULD be clearly labeled.

Where DID methods make use of peer-to-peer computing resources, such as with all known DLTs, the expected burdens of those resources SHOULD be discussed in relation to denial of service.

DID methods that introduce new authentication service endpoint types (see Section ) SHOULD consider the security requirements of the supported authentication protocol.

Privacy Requirements

DID method specifications MUST include their own Privacy Considerations sections, if only to point to .

The DID method specification's Privacy Considerations section MUST discuss any subsection of section 5 of [[RFC6973]] that could apply in a method-specific manner. The subsections to consider are: surveillance, stored data compromise, unsolicited traffic, misattribution, correlation, identification, secondary use, disclosure, exclusion.

Resolution

This section defines the inputs and outputs of DID resolution and DID URL dereferencing. These functions are defined in an abstract way. Their exact implementation is out of scope for this specification, but some considerations for implementors are discussed in [[?DID-RESOLUTION]].

All conformant DID resolvers MUST implement the DID resolution functions for at least one DID method and MUST be able to return a DID document in at least one conformant representation.

DID Resolution

The DID resolution functions resolve a DID into a DID document by using the "Read" operation of the applicable DID method. (See .) The details of how this process is accomplished are outside the scope of this specification, but all conformant implementations MUST implement two functions which have the following abstract forms:

resolve ( did, did-resolution-input-metadata )
     -> ( did-resolution-metadata, did-document, did-document-metadata )

resolveStream ( did, did-resolution-input-metadata )
     -> ( did-resolution-metadata, did-document-stream, did-document-metadata )

The input variables of these functions MUST be as follows:

did
A conformant DID as a single string. This is the DID to resolve. This input is REQUIRED.
did-resolution-input-metadata
A metadata structure consisting of input options to the resolve and resolveStream functions in addition to the did itself. Properties defined by this specification are in . This input is REQUIRED, but the structure MAY be empty.

The output variables of these functions MUST be as follows:

did-resolution-metadata
A metadata structure consisting of values relating to the results of the DID resolution process. This structure is REQUIRED and MUST NOT be empty. This metadata typically changes between invocations of the resolve and resolveStream functions as it represents data about the resolution process itself. Properties defined by this specification are in . If the resolution is successful, and if the resolveStream function was called, this structure MUST contain a content-type property containing the mime-type of the did-document-stream in this result. If the resolution is not successful, this structure MUST contain an error property describing the error.
did-document
If the resolution is successful, and if the resolve function was called, this MUST be a DID document conforming to the abstract data model. If the resolution is unsuccessful, this value MUST be empty.
did-document-stream
If the resolution is successful, and if the resolveStream function was called, this MUST be a byte stream of the resolved DID document in one of the conformant representations. The byte stream MAY then be parsed by the caller of the resolveStream function into a DID document abstract data model, which can in turn be validated and processed. If the resolution is unsuccessful, this value MUST be an empty stream.
did-document-metadata
If the resolution is successful, this MUST be a metadata structure. This structure contains metadata about the DID document contained in the did-document or did-document-stream. This metadata typically does not change between invocations of the resolve function unless the DID document changes, as it represents data about the DID document. If the resolution is unsuccessful, this output MUST be an empty metadata structure. Properties defined by this specification are in .

DID resolver implementations MUST NOT alter the signature of these functions in any way. DID resolver implementations MAY map the resolve and resolveStream functions to a method-specific internal function to perform the actual DID resolution process. DID resolver implementations MAY implement and expose additional functions with different signatures in addition to the resolve function specified here.

DID Resolution Input Metadata Properties

The possible properties within this structure and their possible values are defined by [[DID-SPEC-REGISTRIES]]. This specification defines the following common properties.

accept
The MIME type of the caller's preferred representation of the DID document. The DID resolver implementation SHOULD use this value to determine the representation contained in the returned did-document-stream if such a representation is supported and available. This property is OPTIONAL. It is only used if the resolveStream function is called and MUST be ignored if the resolve function is called.

DID Resolution Metadata Properties

The possible properties within this structure and their possible values are defined by [[DID-SPEC-REGISTRIES]]. This specification defines the following common properties.

content-type
The MIME type of the returned did-document-stream. This property is REQUIRED if resolution is successful and if the resolveStream function was called. It MUST NOT be present if the resolve function was called. The value of this property MUST be the MIME type of one of the conformant representations. The caller of the resolveStream function MUST use this value when determining how to parse and process the did-document-stream returned by this function into a DID document abstract data model.
error
The error code from the resolution process. This property is REQUIRED when there is an error in the resolution process. The value of this property is a single keyword string. The possible property values of this field are defined by [[DID-SPEC-REGISTRIES]]. This specification defines the following error values:
invalid-did
The DID supplied to the DID resolution function does not conform to valid syntax. (See .)
unauthorized
The caller is not authorized to resolve this DID with this DID resolver.
not-found
The DID resolver was unable to return the DID document resulting from this resolution request.

DID Document Metadata Properties

The possible properties within this structure and their possible values are defined by [[DID-SPEC-REGISTRIES]]. This specification defines the following common properties.

DID URL Dereferencing

Metadata Structure

Security Considerations

During the Working Draft stage, this section focuses on security topics that should be important in early implementations. The editors are seeking feedback on threats and threat mitigations that should be reflected in this section or elsewhere in the spec. DIDs are designed to operate under the general Internet threat model used by many IETF standards. We assume uncompromised endpoints, but anticipate that messages could be read or corrupted on the network. Protecting against an attack when a system is compromised requires external key-signing hardware (see Section ).

Choosing DID Resolvers

The DID Method Registry (see [[?DID-SPEC-REGISTRIES]] is an informative list of DID method names and their corresponding DID method specifications. Implementors need to bear in mind that there is no central authority to mandate which DID method specification is to be used with any specific DID method name, but can use the DID Method Registry to make an informed decision when choosing which DID resolver implementations to use.

Binding of Identity

The following sections describe binding identities to DIDs and DID documents.

Proving Control of a DID and DID Document

Signatures and verifiable timestamps allow DID documents to be cryptographically verifiable.

By itself, a verified signature on a self-signed DID document does not prove control of a DID. It only proves that the:

  • DID document was not tampered with since it was timestamped.
  • DID controller(s) controlled the private key used for the signature at the time the timestamp was created.

Proving control of a DID, that is, the binding between the DID and the DID document that describes it, requires a two step process:

  1. Resolving the DID to a DID document according to its DID method specification.
  2. Verifying that the id property of the resulting DID document matches the DID that was resolved.

It should be noted that this process proves control of a DID and DID document regardless of whether the DID document is signed.

Signatures on DID documents are optional. DID method specifications SHOULD explain and specify their implementation if applicable.

Proving Control of a Public Key

There are two methods for proving control of the private key corresponding to a public key description in the DID document: static and dynamic.

The static method is to sign the DID document with the private key. This proves control of the private key at a time no later than the DID document was registered. If the DID document is not signed, control of a public key described in the DID document can still be proven dynamically as follows:

  1. Send a challenge message containing a public key description from the DID document and a nonce to an appropriate service endpoint described in the DID document.
  2. Verify the signature of the response message against the public key description.

Authentication and Verifiable Claims

A DID and DID document do not inherently carry any PII (personally-identifiable information). The process of binding a DID to something in the real world, such as a person or a company, for example with credentials with the same subject as that DID, is out of scope for this specification. For more information, see the [[VC-DATA-MODEL]] instead.

Authentication Service Endpoints

If a DID document publishes a service endpoint intended for authentication or authorization of the DID subject (see Section ), it is the responsibility of the service endpoint provider, subject, or relying party to comply with the requirements of the authentication protocols supported at that service endpoint.

Non-Repudiation

Non-repudiation of DIDs and DID document updates is supported under the assumption that the subject:

Non-repudiation is further supported if timestamps are included (see Sections and ) and the target DLT system supports timestamps.

Notification of DID Document Changes

One mitigation against unauthorized changes to a DID document is monitoring and actively notifying the DID subject when there are changes. This is analogous to helping prevent account takeover on conventional username/password accounts by sending password reset notifications to the email addresses on file.

In the case of a DID, there is no intermediary registrar or account provider to generate such notifications. However, if the verifiable data registry on which the DID is registered directly supports change notifications, a subscription service can be offered to DID controllers. Notifications could be sent directly to the relevant service endpoints listed in an existing DID.

If a DID controller chooses to rely on a third-party monitoring service (other than the verifiable data registry itself), this introduces another vector of attack.

Key and Signature Expiration

In a decentralized identifier architecture, there are no centralized authorities to enforce key or signature expiration policies. Therefore DID resolvers and other client applications need to validate that keys were not expired at the time they were used. Because some use cases might have legitimate reasons why already-expired keys can be extended, make sure a key expiration does not prevent any further use of the key, and implementations of a resolver ought to be compatible with such extension behavior.

Key Revocation and Recovery

Section specifies the DID operations to be supported by a DID method specification, including deactivation of a DID document by replacing it with an updated DID document. It is also up to the DID method to define how revocation of cryptographic keys might occur. Additionally, DID method specifications are also expected to enable support for a quorum of trusted parties to enable key recovery. Some of the facilities to do so are suggested in Section . Not all DID method specifications will recognize control from DIDs registered using other DID methods and they might restrict third-party control to DIDs that use the same method. Access control and key recovery in a DID method specification can also include a time lock feature to protect against key compromise by maintaining a second track of control for recovery. Further specification of this type of control is a matter for future work.

The Role of Human-Friendly Identifiers

DIDs achieve global uniqueness without the need for a central registration authority. This comes, however, at the cost of human memorability. The algorithms capable of generating globally unique identifiers automatically produce random strings of characters that have no human meaning. This demonstrates the axiom about identifiers described in Zooko's Triangle: "human-meaningful, decentralized, secure — pick any two".

There are of course many use cases where it is desirable to discover a DID when starting from a human-friendly identifier. For example, a natural language name, a domain name, or a conventional address for a DID controller, such as a mobile telephone number, email address, Twitter handle, or blog URL. However, the problem of mapping human-friendly identifiers to DIDs (and doing so in a way that can be verified and trusted) is outside the scope of this specification.

Solutions to this problem (and there are many) should be defined in separate specifications that reference this specification. It is strongly recommended that such specifications carefully consider the:

A draft specification for discovering a DID from domain names and email addresses using DNS lookups is available at [[?DNS-DID]].

Immutability

Many cybersecurity abuses hinge on exploiting gaps between reality and the assumptions of rational, good-faith actors. Like any ecosystem, the DID ecosystem has some potential for this to occur. Because this specification is focused on a data model instead of a protocol, it offers no opinion about many aspects of how that model is put to use. However, individual DID methods might want to consider constraints that would eliminate behaviors or semantics they do not need. The more locked down a DID method is, while providing the same set of features, the less it can be manipulated by malicious actors.

As an example, consider the flexibility that the data model offers with respect to updating. A single edit to a DID document can change anything and everything except the root id property of the document. And any individual JSON object in the data model can change all of its properties except its id. But is it actually desirable for a service endpoint to change its type after it is defined? Or for a key to change its value? Or would it be better to require a new id when certain fundamental properties of an object change? Malicious takeovers of a web site often aim for an outcome where the site keeps its identifier (the host name), but gets subtle, dangerous changes underneath. If certain properties of the site were required by the specification to be immutable (for example, the ASN associated with its IP address), such attacks might be much harder and more expensive to carry out, and anomaly detection would be easier.

The notion that immutability provides some cybersecurity benefits is particularly relevant because of caching. For DID methods tied to a global source of truth, a direct, just-in-time lookup of the latest version of a DID document is always possible. However, it seems likely that layers of cache might eventually sit between a client and that source of truth. If they do, believing the attributes of an object in the DID document to have a given state, when they are actually subtly different, might invite exploits. This is particularly true if some lookups are of a full DID document, and others are of partial data, where the larger context is assumed.

Encrypted Data in DID Documents

DID documents are typically publicly available. Encryption algorithms have been known to fail due to advances in cryptography and computing power. Implementers are advised to assume that any encrypted data placed in a DID document might eventually be made available in clear text to the same audience to which the encrypted data is available.

Encrypting all or parts of DID documents is not an appropriate means to protect data in the long term. Similarly, placing encrypted data in DID documents is not an appropriate means to include personally identifiable information.

Given the caveats above, if encrypted data is included in a DID document, implementers are advised to not encrypt with the public keys of entities that do not wish to be correlated with the DID.

Privacy Considerations

It is critically important to apply the principles of Privacy by Design to all aspects of the decentralized identifier architecture, because DIDs and DID documents are, by design, administered directly by the DID controller(s). There is no registrar, hosting company, or other intermediate service provider to recommend or apply additional privacy safeguards. The authors of this specification have applied all seven Privacy by Design principles throughout its development. For example, privacy in this specification is preventative not remedial, and privacy is an embedded default. Furthermore, the decentralized identifier architecture by itself embodies principle #7, "Respect for user privacy — keep it user-centric."

This section lists additional privacy considerations that implementers, delegates, and DID subjects should keep in mind.

Keep Personally-Identifiable Information (PII) Private

If a DID method specification is written for a public verifiable data registry where all DIDs and DID documents are publicly available, it is critical that DID documents contain no personal data. All personal data should be kept behind service endpoints under the control of the DID subject. Additional due diligence should be taken around the use of URLs in service endpoints as well to prevent leakage of unintentional personal data or correlation within a URL of a service endpoint. For example, a URL that contains a username is likely dangerous to include in a DID Document because the username is likely to be human-meaningful in a way that can unintentionally reveal information that the DID subject did not consent to sharing. With this privacy architecture, personal data can be exchanged on a private, peer-to-peer basis using communications channels identified and secured by public key descriptions in DID documents. This also enables DID subjects and relying parties to implement the GDPR right to be forgotten, because no personal data is written to an immutable distributed ledger.

DID Correlation Risks and Pseudonymous DIDs

Like any type of globally unique identifier, DIDs might be used for correlation. DID controllers can mitigate this privacy risk by using pairwise unique DIDs, that is, sharing a different private DID for every relationship. In effect, each DID acts as a pseudonym. A pseudonymous DID need only be shared with more than one party when the DID subject explicitly authorizes correlation between those parties. If pseudonymous DIDs are the default, then the only need for a public DID (a DID published openly or shared with a large number of parties) is when the DID subject explicitly desires public identification.

DID Document Correlation Risks

The anti-correlation protections of pseudonymous DIDs are easily defeated if the data in the corresponding DID documents can be correlated. For example, using same public key descriptions or bespoke service endpoints in multiple DID documents can provide as much correlation information as using the same DID. Therefore the DID document for a pseudonymous DID also needs to use pairwise unique public keys. It might seem natural to also use pairwise unique service endpoints in the DID document for a pseudonymous DID. However, unique endpoints allow all traffic between two DIDs to be isolated perfectly into unique buckets, where timing correlation and similar analysis is easy. Therefore, a better strategy for endpoint privacy might be to share an endpoint among thousands or millions of DIDs controlled by many different subjects.

Herd Privacy

When a DID subject is indistinguishable from others in the herd, privacy is available. When the act of engaging privately with another party is by itself a recognizable flag, privacy is greatly diminished. DIDs and DID methods need to work to improve herd privacy, particularly for those who legitimately need it most. Choose technologies and human interfaces that default to preserving anonymity and pseudonymity. To reduce digital fingerprints, share common settings across client implementations, keep negotiated options to a minimum on wire protocols, use encrypted transport layers, and pad messages to standard lengths.

Current Issues

The list of issues below are under active discussion and are likely to result in changes to this specification.

Where will the DID contexts(s) live?
Leverage RFC7518 to specify cryptographic algorithms
Replace RsaSignature2017 by a standard JWA signature
Explain RsaSignature2018
Standardize the key revocation list
publicKeyJwk, publicKeyHex, publicKeyBase64, publicKeyBase58 missing from context.
Cheap DIDs and the option to migrate DIDs between ledgers using standard DID Deprecation Registries
Details on the use of method-specific DID parameters
Add support for ethereumAddress public key type in @context
Clarification of other verification methods in authentication section missing
Registry handling
Does DID Document metadata belong in the Document?
Privacy Considerations - Specifically call out GDPR
tracking revocation of public keys
Syntactially differentiate data about the DID versus application data
Add CBOR a valid type of DID document syntax similar to JSON and on par with JSON-LD
Create DID explainer
Document Structure
Horizontal Review: Internationalization self test
Horizontal Review: Accessibility self test
Specification needs to be compliant with WCAG 2.0
Horizontal Review: offer review opportunity to TAG
When is a DID subject not a DID controller (if ever)?
Should the DID parameters be normative in the spec?
Include discussion of eIDAS levels-of-assurance
Decoupling DID Core spec from LD-Proof / LDS specs
Uses of terms defined in the specification should be links to their definitions
What are entityship and start-of-authority (SOA) problems?
Replace registries administered community groups with registries established by this specification
Public key "id" and "type" members duplicate JWK "kid" and "kty" members
Add public key examples using JWKs
Underspecified semantics of "updated" property
Unsubstantiated statement about protecting against attacks when compromised
Underspecified statement on combining timestamps with signatures
Supported ciphers in a DID document
What is being discussed in issue 4 (clarification of TERMX via use-cases, spec pointers, and PR)
Unclear which verification methods are authorized for did document operations
Add sections on DID Resolution
Clarification on what DIDs might identify
JSON-LD Contexts in Registry
Define DID Document Metadata
Define terminology for properties and values
How to treat unknown properties
Add section on extensibility and conformance
IETF did+ld+json media type registration
publicKeyHex format unused by spec currently
Should did-core restrict the use of JWK?
Need term for relying party
How to mitigate the single source of failure wrt/ "Trust into the Universal Resolver"?
Added DID resolution and dereferencing contracts.
List of early implementations conforming to spec?
DIDs and JOSE: publicKey.id and publicKey.publicKeyJwk.kid
Clear explanation on how can A DID have more than one controller
Definition of the term "client" in regard to SSI principles
Should DID support self-signed certificates?
Put key points up front
What degree should proof purposes be defined for specific application layer usages?
transfer of controllership and it's intersection with the subject of an identifier
did parameter equivilance
Remove all unspecified properties/functionality from the spec
invert mapping between proof purposes and verification methods?
Ambiguity around necessity of populated top-level DID Document 'id' property
Remove uses of publicKeyHex
Specifications needed for supported key representations publicKeyJwk, publcKeyPem, and publicKeyBase58
Added CBOR section
Verification method block should be a first citizen like public keys
Should DID Methods expose Proof Purposes for DID Operations?
PING Horizontal Review
Horizontal Review Tracking
Remove `proof`
Create a seperate top level block for defining proof purposes
Define simple type-less resolution function
Define resolution function with data types
Define resolution function with data types and property values
Define resolution function with data types, property values, and simple metadata structures
Define resolution function with data types, property values, and full metadata structures
Define resolution function with data types, property values, and full metadata structures, without transformation

IANA Considerations

This section will be submitted to the Internet Engineering Steering Group (IESG) for review, approval, and registration with IANA when this specification becomes a W3C Proposed Recommendation.

application/did+json

Type name:
application
Subtype name:
did+json
Required parameters:
None
Optional parameters:
None
Encoding considerations:
See RFC 8259, section 11.
Security considerations:
See RFC 8259, section 12 [[RFC8259]].
Interoperability considerations:
Not Applicable
Published specification:
http://www.w3.org/TR/did-core/
Applications that use this media type:
Any application that requires an identifier that is decentralized, persistent, cryptographically verifiable, and resolvable. Applications typically consist of cryptographic identity systems, decentralized networks of devices, and websites that issue or verify W3C Verifiable Credentials.
Additional information:
Magic number(s):
Not Applicable
File extension(s):
.did
Macintosh file type code(s):
TEXT
Person & email address to contact for further information:
Ivan Herman <ivan@w3.org>
Intended usage:
Common
Restrictions on usage:
None
Author(s):
Drummond Reed, Manu Sporny, Markus Sabadello, Dave Longley, Christopher Allen
Change controller:
W3C

Fragment identifiers used with application/did+json are treated according to the rules defined in DID Core v1.0, Fragment [[DID-CORE]].

application/did+ld+json

Type name:
application
Subtype name:
did+ld+json
Required parameters:
None
Optional parameters:
None
Encoding considerations:
See RFC 8259, section 11.
Security considerations:
See JSON-LD 1.1, Security Considerations [[JSON-LD11]].
Interoperability considerations:
Not Applicable
Published specification:
http://www.w3.org/TR/did-core/
Applications that use this media type:
Any application that requires an identifier that is decentralized, persistent, cryptographically verifiable, and resolvable. Applications typically consist of cryptographic identity systems, decentralized networks of devices, and websites that issue or verify W3C Verifiable Credentials.
Additional information:
Magic number(s):
Not Applicable
File extension(s):
.did
Macintosh file type code(s):
TEXT
Person & email address to contact for further information:
Ivan Herman <ivan@w3.org>
Intended usage:
Common
Restrictions on usage:
None
Author(s):
Drummond Reed, Manu Sporny, Markus Sabadello, Dave Longley, Christopher Allen
Change controller:
W3C

Fragment identifiers used with application/did+ld+json are treated according to the rules associated with the JSON-LD 1.1: application/ld+json media type [[JSON-LD11]].

application/did+cbor

Type name:
application
Subtype name:
did+cbor
Required parameters:
None
Optional parameters:
None
Encoding considerations:
See RFC 7049, section 4.2.
Security considerations:
See RFC 7049, section 10 [[RFC7049]].
Interoperability considerations:
Not Applicable
Published specification:
http://www.w3.org/TR/did-core/
Applications that use this media type:
Any application that requires an identifier that is decentralized, persistent, cryptographically verifiable, and resolvable. Applications typically consist of cryptographic identity systems, decentralized networks of devices, and websites that issue or verify W3C Verifiable Credentials.
Additional information:
Magic number(s):
Not Applicable
File extension(s):
.did
Macintosh file type code(s):
TEXT
Person & email address to contact for further information:
Ivan Herman <ivan@w3.org>
Intended usage:
Common
Restrictions on usage:
None
Author(s):
Drummond Reed, Manu Sporny, Markus Sabadello, Dave Longley, Christopher Allen, Jonathan Holt
Change controller:
W3C

Fragment identifiers used with application/did+cbor are treated according to the rules defined in DID Core v1.0, Fragment [[DID-CORE]].

application/did+dag+cbor

Type name:
application
Subtype name:
did+dag+cbor
Required parameters:
None
Optional parameters:
None
Encoding considerations:
See RFC 7049, section 4.2.
Security considerations:
See RFC 7049, section 10 [[RFC7049]].
Interoperability considerations:
Not Applicable
Published specification:
http://www.w3.org/TR/did-core/
Applications that use this media type:
Any application that requires an identifier that is decentralized, persistent, cryptographically verifiable, and resolvable. Applications typically consist of cryptographic identity systems, decentralized networks of devices, and websites that issue or verify W3C Verifiable Credentials.
Additional information:
Magic number(s):
Not Applicable
File extension(s):
.did
Macintosh file type code(s):
TEXT
Person & email address to contact for further information:
Ivan Herman <ivan@w3.org>
Intended usage:
Common
Restrictions on usage:
None
Author(s):
Drummond Reed, Manu Sporny, Markus Sabadello, Dave Longley, Christopher Allen, Jonathan Holt
Change controller:
W3C

Fragment identifiers used with application/did+cbor are treated according to the rules defined in DID Core v1.0, Fragment [[DID-CORE]].