§ Trust DID Web - did:tdw
+Specification Status: DRAFT
+Specification Version: 0.3 (see Changelog)
+Latest Draft: +https://github.com/decentralized-identity/trustdidweb
+-
+
- Editors: +
- Stephen Curran +
- John Jordan, BC Gov +
- Andrew Whitehead +
- Brian Richter +
- Michel Sahli +
- Martina Kolpondinos +
- Dmitri Zagdulin +
- Participate: +
- GitHub repo +
- File a bug +
- Commit history +
- Implementations: +
- TypeScript +
- Python +
- Go +
+
§ Abstract
+Trust DID Web (did:tdw
) is an enhancement to the did:web
DID method,
+providing complementary web-based features that address did:web
’s
+limitations. did:tdw
features include:
-
+
- Ongoing publishing of all DID Document (DIDDoc) versions for a DID instead of,
+or alongside a current
did:web
DID/DIDDoc.
+ - The same DID-to-HTTPS transformation as
did:web
.
+ - Supports the same High Assurance DIDs with DNS mechanism. +
- The ability to resolve the full history of the DID using a verifiable chain of +updates to the DIDDoc from genesis to deactivation. +
- A self-certifying identifier (SCID) for the DID. The SCID, globally unique and +embedded in the DID, is derived from the initial DID log entry. It ensures the integrity +of the DID’s history mitigating the risk of attackers creating a new object with +the same identifier. +
- An optional mechanism for enabling DID portability via the SCID, allowing +the DID’s web location to be moved and the DID string to be updated, both while retaining +a connection to the predecessor DID(s) and preserving the DID’s verifiable history. +
- DIDDoc updates contain a proof signed by the DID Controllers authorized to +update the DID. +
- An optional mechanism for publishing “pre-rotation” keys to prevent the loss of +control of a DID in cases where an active private key is compromised. +
- An optional mechanism for having collaborating witnesses +that approve of updates to the DID by a DID Controller before publication. +
- DID URL path handling that defaults (but can be overridden) to automatically
+resolving
<did>/path/to/file
by using a comparable DID-to-HTTPS translation +as for the DIDDoc.
+ - A DID URL path
<did>/whois
that defaults to automatically returning (if +published by the DID controller) a Verifiable Presentation containing +Verifiable Credentials with the DID as thecredentialSubject
, +signed by the DID.
+
Combined, the additional features enable greater trust and security without
+compromising the simplicity of did:web
.
The incorporation of the DID Core compatible “/whois” path, drawing inspiration
+from the traditional WHOIS protocol [RFC3912], offers an easy-to-use,
+decentralized, trust registry. The did:tdw
method aims to establish a more
+trusted and secure web environment by providing robust verification processes
+and enabling transparency and authenticity in the management of decentralized
+digital identities.
§ Definitions
+-
+
- base58btc +
- Applies [[spec:draft-msporny-base58-03]] to convert
+data to a
base58
encoding. Used indid:tdw
for encoding hashes for SCIDs and entry hashes.
+ - Data Integrity +
- W3C Data +Integrity +is a specification of mechanisms for ensuring the authenticity and integrity of +structured digital documents using cryptography, such as digital signatures and +other digital mathematical proofs. +
- Decentralized Identifier +
- Decentralized Identifiers (DIDs) [DID-CORE] are a type of identifier that enable +verifiable, decentralized digital identities. A DID refers to any subject (e.g., +a person, organization, thing, data model, abstract entity, etc.) as determined +by the controller of the DID. +
- DIDDoc +
- A DID Document as defined by the [DID-CORE] – the document returned when a DID is resolved. +
- DID:key +
DID:key
…
+- DID Log +
- A DID Log is a list of Entries one being added for each update of an entry item, +including new versions of the DIDDoc or changed information necessary to generate or validate the DID. +
- DID Log Entry +
- A DID Log Entry is a JSON array of five items which define the authorized +transformation of a DIDDoc from one version to the next. The initial entry +establishes the DID and version 1 of the DIDDoc. All entries are stored +in the DID Log. +
- DID Method +
- DID methods are the mechanism by which a particular type of DID and its
+associated DID document are created, resolved, updated, and deactivated. DID
+methods are defined using separate DID method specifications. This document is
+the DID Method Specification for
DID:tdw
.
+ - DID Portability +
did:tdw
portability encompasses the ability to change the DID string for the +DID while retaining the SCID and the history of the DID. This is useful +when forced to change (such as when an organization is acquired by another, +resulting in a change of domain names) and when changing DID hosting service +providers.
+- did:web +
did:web
as described in the W3C specification +is a DID method that leverages the Domain Name System (DNS) to perform the DID operations. +It is valued for its simplicity and ease of deployment compared to DID methods that are +based on distributed ledgers or blockchain technology, but also comes with increased +challenges related to trust and security.did:web
provides a starting point fordid:tdw
, +which complementsdid:web
with specific features to address the challenges +while still providing ease of deployment.
+- eddsa-jcs-2022 +
- A cryptosuite defined for producing a Data Integrity proof for an +unsecured input data document and verifying the Data Integrity proof of +the secured document. More information on further operations and applications of +the cryptosuite can be found in the specification, here: +eddsa-jcs-2022 +
- Entry Hash +
- A
DID:tdw
entry hash is a hash generated using a formally defined process +over the input data to a log entry, excluding the Data Integrity proof +item. The input data includes content from the predecessor to the version of the +DID, ensuring that all the versions are “chained” together in a microledger. The +generated entry hash is subsequently included in theversionId
element of the log entry and MUST be +verified by a resolver.
+ - ISO8601 +
- A date/time expressed using the ISO8601 +Standard. +
- JSON Canonicalization Scheme +
- [RFC8785] defines a method for canonicalizing a JSON +structure such that is suitable for verifiable hashing or signing. +
- JSON Lines +
- A file of JSON Lines, as described on the site
+https://jsonlines.org/. In short,
JSONL
is lines of JSON with +whitespace removed and separated by a newline that is convenient for handling +streaming JSON data or log files.
+ - JSON Patch +
- [RFC6902] is a web standard format for describing how to change a JSON
+document from one state to another. A DID Controller MAY use it in
DID:tdw
+to define how a DIDDoc is changed from one version to the next.
+ - Pre-Rotation +
- A technique for a controller of a cryptographic key to commit to the public +key it will rotate to next, without exposing that actual public key. It protects +from an attacker that gains knowledge of the current private key from being +able to rotate to a new key known only to the attacker. +
- Linked-VP +
- A [DID-CORE]
service
entry that specifies where a verifiable about the DID subject can be found. The Decentralized Identity +Foundation hosts the Linked VP +Specification.
+ - multihash +
- Per the [[spec:draft-multiformats-multihash-07]], multihash is a specification +for differentiating instances of hashes. Software creating a hash prefixes +(according to the specification) data to the hash indicating the algorithm used +and the length of the hash, so that software receiving the hash knows how to +verify it. Although multihash supports many hash algorithms, for +interoperability, DID Controllers MUST only use the hash algorithms defined +in this specification as permitted. +
- multi-sig +
- A cryptographic signature that to be valid MUST contain a defined threshold +(for example, 4 of 7) individual signatures to be considered valid. The +multi-signature key reference points to a verification method that defines what +keys may contribute to the signature, and under what conditions the +multi-signature is considered valid. +
- parameters +
DID:tdw
parameters are a defined set of configurations that control how the +issuer has generated the DID, and how the resolver should process the DID Log. The use of parameters allows for the controlled evolution ofDID:tdw
+log handling, such as evolving the permitted hash algorithms.
+- self-certifying identifier +
- An object identifier derived from initial data such that an attacker could not
+create a new object with the same identifier. The input for a
DID:tdw
SCID is +the initial DIDDoc with the placeholder{SCID}
wherever the SCID is to be +placed.
+ - Verifiable Credential +
- A verifiable credential can represent all of the same information that a physical credential represents, adding technologies such as digital signatures, to make the credentials more tamper-evident and so more trustworthy than their physical counterparts. The Verifiable Credential Data Model is a W3C Standard. +
- Verifiable Presentation +
- A verifiable presentation data model is part W3C’s Verifiable Credential Data
+Model that contains a set of verifiable credentials about a
credentialSubject
, and a signature across the +verifiable credentials generated by that subject. In this specification, the use +case of primary interest is where the DID is thecredentialSubject
and the DID +signs the verifiable presentation.
+ - witness +
- Witnesses are participants in the process of creating and verifying a version
+of a
DID:tdw
DIDDoc. Notably, a witness receives from the DID Controller a DID entry ready for publication, verifies it according to this specification, +and approves it according to its ecosystem governance (whatever that might be). If the verification and +approval process results are positive, witnesses returns to the DID Controller a Data Integrity proof +attesting to that positive result.
+ - W3C VCDM +
- A Verifiable Credential that uses the Data Model defined by the W3C [[spec: W3C-VC]] specification. +
§ Overview
+The emergence of Decentralized Identifiers (DIDs) and with them the +evolution of DID Methods continues to be a dynamic area of +development in the quest for trusted, secure and private digital identity +management where the users are in control of their own data.
+The did:web
method, for example, leverages the Domain Name System (DNS) to
+perform the DID operations. This approach is praised for its simplicity and
+ease of deployment, including DID-to-HTTPS transformation and addressing
+some aspects of trust by allowing for DIDs to be associated with a domain’s
+reputation or published on platforms such as GitHub. However, it is not
+without its challenges–
+from trust layers inherited from the web and the absence of a verifiable
+history for the DID.
Tackling these concerns, the proposed did:tdw
(Trust DID Web)
+method aims to enhance did:web
by introducing additional features such
+as a self-certifying identifier (SCID), update key(s)
+and a verifiable history, akin to what is available with ledger-based DIDs,
+without relying on a ledger.
This approach not only maintains backward compatibility but also offers an
+additional layer of assurance for those requiring more robust verification
+processes. By publishing the resulting DID as both did:web
and did:tdw
, it
+caters to a broader range of trust requirements, from those who are comfortable
+with the existing did:web
infrastructure to those seeking greater security
+assurances provided by did:tdw
. This innovative step represents a significant
+stride towards a more trusted and secure web, where the integrity of
+cryptographic key publishing is paramount.
The key differences between did:web
and did:tdw
revolve around the core
+issues of decentralization and security. did:web
is recognized for its
+simplicity and cost-effectiveness, allowing for easy establishment of a
+credential ecosystem. However, it is not inherently decentralized as it relies
+on DNS domain names, which require centralized registries. Furthermore, it lacks a
+cryptographically verifiable, tamper-resistant, and persistently stored DID
+document. In contrast, did:tdw
(Trust DID Web) is proposed as an enhancement
+to did:web
, aiming to address these limitations by adding a verifiable history
+to the DID without the need for a ledger. This method seeks to provide a more
+decentralized approach by ensuring that the security of the embedded
+SCID does not depend on DNS. Additionally, did:tdw
is
+capable of resolving a cryptographically verifiable trust registry and status
+lists, using DID-Linked Resources, which did:web
lacks. These features are
+designed to build a trusted web, offering a higher level of assurance for
+cryptographic key publishing and management.
For backwards compatibility, and for verifiers that “trust” did:web
, a
+did:tdw
can be trivially modified and published in parallel to a did:web
+DID. For resolvers that want more assurance, did:tdw
provides a way to “trust
+did:web” (or to enable a “trusted web” if you say it fast) enabled by the
+features listed in the Abstract.
The following is a tl;dr
summary of how did:tdw
works:
-
+
did:tdw
uses the same DID-to-HTTPS transformation asdid:web
, so +did:tdw
’sdid.jsonl
(JSON Lines) file is found in the same +location asdid:web
’sdid.json
file, and supports an easy transition +fromdid:web
to gain the added benefits ofdid:tdw
.
+- The
did.jsonl
is a list of JSON DID log entries, one per line, +whitespace removed (per JSON Lines). Each entry contains the +information needed to derive a version of the DIDDoc from its preceding +version. Thedid.jsonl
is also referred to as the DID Log.
+ - Each DID log entry includes a JSON array of five items:
+
-
+
- The
versionId
of the entry, a value that combines the version number +(starting at1
and incrementing by one per version), a literal dash +-
, and a hash of the entry. The entry hash calculation links each entry +to its predecessor in a ledger-like chain.
+ - The
versionTime
(as stated by the DID Controller) of the entry.
+ - A set of
parameters
that impact the processing of the current and +future log entries. +-
+
- Example parameters are the version of the
did:tdw
specification and +hash algorithm being used as well as the SCID and update key(s).
+
+ - Example parameters are the version of the
- The new version of the DIDDoc as either a
value
(the full document) or +apatch
derived using JSON Patch to update the new version from +the previous entry.
+ - A Data Integrity (DI) proof across the entry, signed by a DID authorized to update the DIDDoc, using the
versionId
as the +challenge.
+
+ - The
- In generating the first version of the DIDDoc, the DID Controller calculates
+the SCID for the DID from the entire first log entry (which
+includes the DIDDoc) by adding the string {SCID} everywhere the actual SCID
+is to be placed. The DID Controller then replaces these placeholders
+with the just calculated SCID, including it as a
parameter
in the first log, and inserting it where needed in the initial (and all subsequent) +DIDDocs. The SCID enables an optional portability capability, allowing a DID’s +web location to be moved to a new location while retaining the DID and version +history of the DID.
+ - A DID Controller generates and publishes the new/updated DID Log file by making it +available at the appropriate location on the web, based on the identifier of the +DID. +
- Given a
did:tdw
DID, a resolver converts the DID to an HTTPS URL, +retrieves, and processes the DID Logdid.jsonl
, generating and verifying +each log entry as per the requirements outlined in this specification. +-
+
- In the process, the resolver collects all the DIDDoc versions and public +keys used by the DID currently, or in the past. This enables +resolving both current and past versions of the DID. +
+ did:tdw
DID URLs with paths and/whois
are resolved to documents +published by the DID Controller that are by default in the web location relative to the +did.jsonl
file. See the note below about the +powerful capability enabled by the/whois
DID URL path.
+- Optionally, a DID Controller can easily generate and publish a
did:web
DIDDoc +from the latestdid:tdw
DIDDoc in parallel with thedid:tdw
DID Log.
+
A resolver settling for just the `did:web` version of the DID does not get the
+verifiability of the `did:tdw` log.
+
+An example of a did:tdw
evolving through a series of versions can be seen in
+the did:tdw Examples of this specification.
This draft specification was developed in parallel with the development of two
+proof of concept implementations. The specification/implementation interplay
+helped immensely in defining a practical, intuitive, straightforward, DID
+method. The existing proof of concept implementations of the did:tdw
DID
+Method are listed in the Implementors Guide. The current
+implementations range from around 1500 to 2000 lines of code.
§ The /whois
Use Case
+This DID Method introduces what we hope will be a widely embraced convention for
+all DID Methods – the /whois
path. This feature harkens back to the WHOIS
+protocol that was created in the 1970s to provide a directory about people and
+entities in the early days of ARPANET. In the 80’s, whois
evolved into
+[RFC920] that has expanded into the global
+whois feature we know today as
+[RFC3912]. Submit a whois
request about a domain name, and get
+back the information published about that domain.
We propose that the /whois
path for a DID enable a comparable, decentralized,
+version of the WHOIS
protocol for DIDs. Notably, when <did>/whois
is
+resolved (using a standard DID service
that follows the Linked-VP
+specification), a Verifiable Presentation (VP) may be returned (if
+published by the DID Controller) containing Verifiable Credentials with
+the DID as the credentialSubject
, and the VP signed by the DID. Given a DID,
+one can gather verifiable data about the DID Controller by resolving
+<did>/whois
and processing the returned VP. That’s powerful – an efficient,
+highly decentralized, trust registry. For did:tdw
, the approach is very simple
+– transform the DID to its HTTPS equivalent, and execute a GET <https>/whois
.
+Need to know who issued the VCs in the VP? Get the issuer DIDs from those VCs,
+and resolve <issuer did>/whois
for each. This is comparable to walking a CA
+(Certificate Authority) hierarchy, but self-managed by the DID Controllers –
+and the issuers that attest to them.
The following is a use case for the /whois
capability. Consider an example of
+the did:tdw
controller being a mining company that has exported a shipment and
+created a “Product Passport” Verifiable Credential with information about the
+shipment. A country importing the shipment (the Importer) might want to know
+more about the issuer of the VC, and hence, the details of the shipment. They
+resolve the <did>/whois
of the entity and get back a Verifiable Presentation
+about that DID. It might contain:
-
+
- A verifiable credential issued by the Legal Entity Registrar for the
+jurisdiction in which the mining company is headquartered.
+
-
+
- Since the Importer knows about the Legal Entity Registrar, they can automate +this lookup to get more information about the company from the VC – its +legal name, when it was registered, contact information, etc. +
+ - A verifiable credential for a “Mining Permit” issued by the mining authority
+for the jurisdiction in which the company operates.
+
-
+
- Perhaps the Importer does not know about the mining authority for that
+jurisdiction. The Importer can repeat the
/whois
resolution process for +the issuer of that credential. The Importer might (for example), resolve +and verify thedid:tdw
DID for the Authority, and then resolve the +/whois
DID URL to find a verifiable credential issued by the government of +the jurisdiction. The Importer recognizes and trusts that government’s +authority, and so can decide to recognize and trust the mining permit +authority.
+
+ - Perhaps the Importer does not know about the mining authority for that
+jurisdiction. The Importer can repeat the
- A verifiable credential about the auditing of the mining practices of the
+mining company. Again, the Importer doesn’t know about the issuer of the audit
+VC, so they resolve the
/whois
for the DID of the issuer, get its VP and +find that it is accredited to audit mining companies by the London Metal +Exchange according to one of its mining standards. +As the Importer knows about both the London Metal Exchange and the standard, +it can make a trust decision about the original Product Passport Verifiable +Credential.
+
Such checks can all be done with a handful of HTTPS requests and the processing +of the DIDs and verifiable presentations. If the system cannot automatically +make a trust decision, lots of information has been quickly collected that can +be passed to a person to make such a decision.
+The result is an efficient, verifiable, credential-based, decentralized, +multi-domain trust registry, empowering individuals and organizations to verify +the authenticity and legitimacy of DIDs. The convention promotes a decentralized +trust model where trust is established through cryptographic verification rather +than reliance on centralized authorities. By enabling anyone to access and +validate the information associated with a DID, the “/whois” path contributes to +the overall security and integrity of decentralized networks.
+§ did:tdw DID Method Specification
+§ Target System
+The target system of the Trust DID Web (TDW) DID method is the host (or domain) +name when the domain specified by the DID is resolved through the Domain Name +System (DNS) and verified by processing a log of DID versions.
+§ Method Name
+The namestring that identifies this DID method is: tdw
. A DID that uses this
+method MUST begin with the following prefix: did:tdw
. Per the DID
+specification, this string MUST be in lowercase. The remainder of the DID, after
+the prefix, is the method-specific identifier,
+specified below.
§ Method-Specific Identifier
+The did:tdw
method-specific identifier contains both the self-certifying identifier (SCID) for the DID, and a fully qualified domain
+name (with an optional path) that is secured by a TLS/SSL certificate. Given the
+DID, a transformation to an HTTPS URL can be
+performed such that the DID Log for the did:tdw
DID is retrieved (via
+an HTTP GET
) and processed to produce the DIDDoc for the DID. As per the
+Augmented Backus-Naur Form (ABNF) notation below, the SCID MUST be the first element of
+the method-specific identifier.
Formal rules describing valid domain name syntax are described in
+[RFC1035], [RFC1123], and [RFC2181]. Each did:tdw
DID’s
+globally unique SCID is generated
+during the creation of the DID based on its initial content and placed into
+the DID identifier for publication and use.
The domain name element of the method-specific identifier MUST match the +common name used in the SSL/TLS certificate, and it MUST NOT include IP +addresses. A port MAY be included and the colon MUST be percent encoded to +prevent a conflict with paths. Directories and subdirectories MAY optionally be +included, delimited by colons rather than slashes.
+As specified in the following Augmented Backus-Naur Form (ABNF) notation
+[RFC2234] the SCID MUST be present in the DID string. See
+examples below. The domain-segment
and path-segment
elements refer to
+[RFC3986]’s ABNF for a Generic URL (page 49). Attempting to replicate
+here the full ABNF of those elements from that RFC would inevitably be wrong.
tdw-did = "did:tdw:" scid ":" domain-segment 1+( "." domain-segment ) *( ":" path-segment )
+domain-segment = ; A part of a domain name as defined in RFC3986, such as "example" and "com" in "example.com"
+path-segment= ; A part of a URL path as defined in RFC3986, such as "path", "to", "folder" in "path/to/folder"
+
+The ABNF for a did:tdw
is almost identical to that of did:web
, with changes only to
+the DID Method (tdw
instead of web
), and the addition of the <scid>:
+element in did:tdw
that is not in did:web
. As specified in the DID-to-HTTPS
+Transformation section of this specification,
+did:tdw
and did:web
DIDs that have the same fully qualified domain and path
+transform to the same HTTPS URL, with the exception of the final file –
+did.json
for did:web
and did.jsonl
for did:tdw
.
§ The DID to HTTPS Transformation
+The did:tdw
method-specific identifier is
+defined to enable a transformation of the DID to an HTTPS URL for publishing
+and retrieving the DID Log. This section defines the transformation
+from DID to HTTPS URL, including a number of examples.
Given a did:tdw
, the HTTPS URL for the DID Log is generated by
+carrying out the following steps. The steps are carried out by the DID to determine where to publish the DID Log, and by all resolvers to
+retrieve the DID Log.
-
+
- Remove the literal
did:tdw:
prefix from the DID, leaving the method specific +identifier.
+ - Remove the SCID by removing the text up to and including the first colon
+(
<scid>:
) from the method-specific identifier and continue processing.
+ - Replace
:
with/
in the method-specific identifier to obtain the fully +qualified domain name and optional path.
+ - If there is no optional path, append
/.well-known
to the URL. +-
+
- When this algorithm is used for resolving a DID path (such as
+
<did>/whois
or<did>/path/to/file as defined in the section [DID URL Handling](#did-url-resolution)), the
/.well-known` MUST NOT be +included in the HTTPS URL.
+
+ - When this algorithm is used for resolving a DID path (such as
+
- If the domain contains a port, percent decode the colon. +
- Generate an HTTPS URL to the expected location of the DIDDoc by prepending
+
https://
.
+ - Append
/did.jsonl
to complete the URL. +-
+
- When this algorithm is used for resolving a DID path (such as
+
<did>/whois
or `/path/to/file as defined in the section DID URL +Handling), append the DID URL path instead.
+
+ - When this algorithm is used for resolving a DID path (such as
+
The following are some examples of various DID-to-HTTPS transformations based +on the processing steps specified above.
+did:tdw
DIDs and the corresponding web locations of their did:tdw
log file.
+In the examples,{SCID}
is a placeholder for where the generated SCID would be
+placed in the actual DIDs and HTTPS URLs. Note that when the {SCID}
follows
+the literal did:tdw:
as a separate element, the {SCID}
is not part of the
+HTTPS URL.
+
domain/did:web
-compatible
did:tdw:{SCID}:example.com
-->
https://example.com/.well-known/did.jsonl
subdomain
+did:tdw:{SCID}:issuer.example.com
-->
https://issuer.example.com/.well-known/did.jsonl
path
+did:tdw:{SCID}:example.com:dids:issuer
-->
https://example.com/dids/issuer/did.jsonl
path w/ port
+did:tdw:{SCID}:example.com%3A3000:dids:issuer
-->
https://example.com:3000/dids/issuer/did.jsonl
The location of the did:tdw
did.jsonl
DID Log file is the same as
+where the comparable did:web
did.json
file is published. A DID MAY choose to publish both DIDs and so, both files. The process
+to do so is described in the publishing a parallel did:web
+DID section of this specification.
§ The DID Log File
+The DID log file contains a list of entries, one for each version of the DID. A +version of the DID is an update to the contents of the resolved DIDDoc for the +DID, and/or a change to the parameters that control the generation and +verification of the DID.
+Each entry is a JSON array consisting of the following 5 items.
+[ versionId, versionTime, parameters, DIDDoc State, Data Integrity Proof ]
-
+
- The entry
versionId
is a value that combines the version number (starting at +1
and incrementing by one per DID version), a literal dash-
, and the +entryHash
, a hash calculated across the log entry content. The input to the +hash is chosen so as to link each entry to its predecessor in a ledger-like +chain. The input to the hash is specified in the Entry Hash Generation and +Verification section of this +specification.
+ - The
versionTime
(as stated by the DID Controller) of the entry, in ISO8601 format.
+ - A JSON object
parameters
that define configurations/options used in the +processing of current and future log entries.parameters
are defined in the +did:tdw
DID Method Parameters section of +this specification.
+ - The
DIDDoc State
for this version of the DID as eithervalue
, the full +DIDDoc, orpatch
, such that the new DIDDoc is derived using +JSON Patch from the previous entry.
+ - A
Data Integrity Proof
across the entry, signed by a DID authorized to update the DIDDoc, using theversionId
as the +challenge.
+
After creation, each entry has (per the JSON Lines specification) all
+extra whitespace removed, a \n
character appended, and the result added to
+the DID Log file for publication.
A more comprehensive description of how to create a DID log entry and update it +into a JSON Line is given in steps 4 - 6 of the next section.
+Examples of DID Logs and DID log entries can be found in the +did:tdw` Examples section of this specification.
+§ DID Method Operations
+§ Create (Register)
+Creating a did:tdw
DID is done by carrying out the following steps.
-
+
-
+
Define the DID string +The start of the DID MUST be the literal string “
+did:tdw:{SCID}:
”, where the{SCID}
is +a placeholder that will be replaced by the calculated SCID later in the process (see step +5). This first part of the DID string is followed by a fully qualified domain name +(with an optional path) that is secured by a TLS/SSL certificate and +reflects the web location at which the DID Log (did.jsonl
) will be publishedThe DID MUST be a valid
+did:tdw
DID as per the ABNF of adid:tdw
DID defined +in the Method-Specific Identifier section of this specification.-
+
- Note: the SCID for a
did:tdw
DID is not by default in the HTTPS URL for the DID. +A DID Controller that wants to include the SCID in the HTTPS URL MAY +add additional placeholder{SCID}
strings into the domain name or path +components of the method-specific identifier when creating the DID. The +additional instance(s) of the SCID have no impact on the handling of the +DID, and are treated like any other part of the domain and/or path.
+
+ - Note: the SCID for a
-
+
Generate the authorization key pair(s) +Authorized keys are authorized to control (create, update, deactivate) the DID. +This includes generating any other key pairs that will be placed into the initial +DIDDoc for the DID.
+-
+
- If the DID is to use pre-rotation, additional key generation will +be necessary to generate the required “next” authorization keys and their +corresponding pre-rotation hashes. +
- For each authorization key pair, generate a multikey based on the
+key pair’s public key. The multikey representations of the public
+keys are placed in the
updateKeys
item in parameters.
+ - The public key(s) of the authorization key pair(s) MAY be used in the +DIDDoc as well, but that is not required. +
+ -
+
Create the initial DIDDoc for the DID +The DIDDoc MUST contain the top level
+id
item which MUST be the DID string from +step 1, including the placement of the{SICD}
placeholder for the SCID. Other +DIDDoc verifications SHOULD be performed.All other absolute self-reference’s to the DID in the DIDDoc must use the form defined +in step 1, with the identified placeholder for the SCID (e.g.,
+ +did:tdw:{SCID}:example.com#key-1
, +did:tdw:{SCID}:example.com:dids:issuer#key-1
, etc.). The DIDDoc can contain any other content as deemed necessary by the DID Controller.
+ -
+
Generate a preliminary DID Log Entry (input JSON array) +The DID log entry is an input JSON array that when completed contains the following items: +
+[ versionId, versionTime, parameters, DIDDoc State, Data Integrity Proof ]
. When creating +(registering) the DID the first entry starts with the follows items for processing: +[ "{SCID}", "<current time>", "parameters": [ <parameters>], { "value": "<DIDDoc with Placeholders>" } ]
-
+
- Add a preliminary
versionId
value +The first item in the input JSON array MUST be the placeholder string{SCID}
.
+ - Add the
versionTime
value +The second item in the input JSON array MUST be a valid ISO8601 date/time string, +and that the represented time MUST be before or equal to the current time.
+ - Define the parameters +The third item in the input JSON array MUST be the parameters +JSON object. The parameters are used to configure the DID generation and verification +processes. All parameters MUST be valid and all required values in the first version +of the DID MUST be present. +
The DID Generation and Verification Parameters +section of this specification defines the permitted parameters. That +section defines what items MUST be included in this first log entry for the DID. +Collect and use the specified parameters in the remainder of the DID creation steps.
+ +
+ - Add a preliminary
-
+
Update the preliminary DID Log Entry to the initial DID Log Entry +Use the preliminary DID log entry to perform the consecutive steps:
+-
+
- Calculate the SCID +The input JSON array MUST be used to calculate the SCID for the DID as defined in +the SCID Generation and Verification section of this +specification. +
- Replace the placeholder
{SCID}
+Replace throughout the input JSON array the placeholder “{SCID}
” for the SCID with +the calculated SCID from the previous step.
+ - Calculate the Entry Hash
+The JSON array updated in the previous step MUST be used to calculate the Entry Hash
+(
entryHash
) for the log entry, as defined in the +Entry Hash Generation and Verification section of +this specification.
+ - Replace the preliminary
versionId
value +The value of theversionId
(first) item of the JSON array MUST be updated with the +literal string1-
(for version number 1) followed by theentryHash
value produced in the previous step.
+ - Generate the Data Integrity proof
+A Data Integrity proof on the initial DIDDoc MUST be generated
+using an authorized key from a DID in the required
updateKeys
item in the parameters, +and theversionId
as the proofchallenge
.
+
If the DID Controller has opted to use witnesses for the DID, the required approvals +from the DID’s witnesses MUST be collected and added to the +Data Integrity proof item. See the DID Witnesses section of this specification.
+-
+
- Add the Data Integrity proof +The fifth item in the input JSON array MUST be added to the JSON array. The result is in the +initial DID log entry for the DID. +
+ -
+
Generate the first JSON Line +The DID log entry MUST be updated to be a JSON Lines +entry by removing extraneous white space and appending a carriage return, +and stored as the contents of the file
+did.jsonl
.
+ -
+
Publish the DID Log +The complete DID Log file MUST be published at the appropriate Web location defined by +the
+did:tdw
DID identifier (see step 1)-
+
- This is a logical operation – how a deployment serves the
did.jsonl
+content is not constrained.
+ - Use the DID-to-HTTPS Transformation +steps to transform the DID into the Web location of the DID Log +file. +
+ - This is a logical operation – how a deployment serves the
A controller MAY generate an equivalent did:web
DIDDoc and publish it as
+defined in the
+Publishing a Parallel did:web
DID section
+of this specification. The did:web
DIDDoc could be used for backwards
+compatibility as a transition is made from did:web
to did:tdw
. Verifiers
+using the did:web
lose the verifiable properties and history of the did:tdw
+for the convenience of the simple retrieval of the did:web
DIDDoc.
§ Read (Resolve)
+The following steps MUST be executed to resolve the DIDDoc for a did:tdw
DID:
-
+
- The DID-to-HTTPS Transformation steps +MUST be used to transform the DID into an HTTPS URL for the DID file. +
- Perform an HTTPS
GET
request to the URL using an agent that can successfully +negotiate a secure HTTPS connection, which enforces the security requirements +as described in +Security and privacy considerations.
+ - When performing the DNS resolution during the HTTPS GET request, the client +SHOULD utilize [RFC8484] in order to prevent tracking of the identity +being resolved. +
- The DID Log file MUST be processed as described below. +
To process the retrieved DID Log file, the resolver MUST carry out +the following steps on each of the log entries in the order they appear in the +file, applying the parameters set from the current and previous +entries. As noted in the DID Log File section, log entries +are each a JSON array with five items:
+-
+
versionId
+versionTime
+parameters
+DIDDoc State
– either the fullvalue
or a JSON Patchpatch
+to be applied to the prior version of the DIDDoc.
+- A Data Integrity proof array for the version of the DIDDoc corresponding to that +entry. +
For each entry:
+-
+
- Update the currently active parameters with the parameters from
+the entry (if any). Continue processing using the now active set of
+parameters.
+
-
+
- While all parameters in the first Log Entry take effect +immediately, some kinds of parameters defined in later entries only take +effect after that entry has been published. For example, rotating the +authorized keys to update a DID takes effect only after the entry in +which they are defined has been published. +
+ - The Data Integrity proof in the entry MUST be valid and signed by
+an authorized key as defined in the Authorized Keys
+section of this specification.
+
-
+
- If the DID Controller has opted to use witnesses and the +last entry of the log is being processed, the witness Data proofs MUST be valid and MUST be signed by a threshold +of witnesses. For details, see the DID +Witnesses section of this specification. +
+ - Verify the
versionId
for the entry. Recall the theversionId
is the +concatenation of the version number, a dash (-
), and theentryHash
. +-
+
- The version number MUST be
1
for the the first log entry and MUST be +incremented by one for each subsequent log entry.
+ - A dash
-
MUST follow the version number.
+ - The
entryHash
MUST follow the dash, and MUST be verified using +the process defined in the Entry Hash Generation and +Verification section of this +specification.
+
+ - The version number MUST be
- The
versionTime
MUST be a valid ISO8601 date/time string. The +versionTime
for each log entry MUST be greater than the +previous entry’s time. TheversionTime
of the last entry MUST be +earlier than the current time.
+ - Parse and apply the
did:tdw
DID Method configurationparameters
. Note +that in versions after the first, someparameters
apply to immediately and +impact the process of the current DID version, while others, such as +updateKeys
andwitnesses
apply after the current version has been +published. Theparameters
MUST adhere to thedid:tdw
DID Method +Parameters section of this specification.
+ - When processing the first DID log entry, verify the SCID +(defined in the parameters) according to the +SCID Generation and Verification section +of this specification. +
- Extract the contents of the DIDDoc for each entry by using the JSON value
+of the
value
item, or by using JSON Patch to apply the JSON +value of thepatch
entry item to the previous version of the DIDDoc.
+ - If Key Pre-Rotation is being used, the hash of all
updateKeys
entries +in theparameters
item MUST match a hash in +the active array ofnextKeyHashes
parameter, as defined in the +Pre-Rotation[Key Pre-Rotation Hash Generation and Verification](#pre-rotation-key-hash-generation-and-verification) +section of this specification.
+ - If any verifications fail, discard the DID as invalid with an error message. +
- As each log entry is processed and verified, collect the following information
+about each version:
+
-
+
- The DIDDoc. +
- The
versionId
of the DIDDoc.
+ - The
versionTime
of the DIDDoc.
+ - The latest list of active multikey formatted public keys
+authorized to update the DID, from the
updateKeys
lists in the +parameters.
+ - If pre-rotation is being used, the hashes of authorized DIDs that may
+be used in later
updateKeys
lists. The pre-rotation hashes are in the +nextKeyHashes
list in the parameters.
+ - All other
did:tdw
processing configuration settings as defined by in the +parameters
object.
+
+
On completing the processing and successful verification of all entries in the
+DID Log, respond to the DID resolution request, including the
+application of DID query parameters such as ?versionId=
and ?versionTime=
with
+the appropriate DIDDoc version and content.
The following error codes and descriptions may be returned when resolving a DID.
+Document the full list of error codes that can be generated in resolving a DID.
+-
+
- Code 404: The
did:tdw
DID Log filedid.jsonl
was not found.
+
§ Reading did:tdw DID URLs
+A did:tdw
resolver MAY implement the resolution of the /whois
and a DID
+URL Path using the whois LinkedVP Service and
+DID URL Path Resolution Service as defined in
+this specification by processing the DID Log and then dereferencing the
+DID URL based on the contents of the DIDDoc. The client of a resolver that does
+not implement those capabilities must use the resolver to resolve the
+appropriate DIDDoc, and then process the resulting DID URLs themselves. Since
+the default DID-to-HTTPS URL transformation is trivial, did:tdw
+DID Controllers are strongly encouraged to use the default behavior
+for DID URL Path resolution.
§ Update (Rotate)
+To update a DID, a new, verifiable DID Log Entry must be generated,
+witnessed (if necessary), appended to the existing DID Log (did.jsonl
),
+and published to the web location defined by the DID. The process to generate a
+verifiable DID Log Entry follows a similar process to the
+Create process, as follows:
-
+
- Make the desired changes to the DIDDoc. While the contents of a new DIDDoc
+version are (mostly) up to the DID controller, there are some limitations:
+
-
+
- If the DID is configured to support portability, the root
id
+item in the DIDDoc MAY be changed when the DID Controller wants to (or +is forced to) publish the DID at a different Internet location and wants +to retain the SCID and history of the DID. For details, see the +DID Portability section of this specification.
+
+ - If the DID is configured to support portability, the root
- Define a JSON array of parameters that affect the evolution of the
+DID. The
parameters
MUST be from those listed in thedid:tdw
DID +Method Parameters section of this +specification. Any parameters defined in the array override the +previously active value, while any parameters not included imply the +existing values remain in effect. If no changes to the parameters +are needed, an empty JSON object{}
MUST be used. +-
+
- While all parameters in the first Log Entry take effect +immediately, some types of parameters defined in later entries only take +effect after the entry has been published. For example, rotating the keys +authorized to update a DID or changing the witnesses for a DID take effect +only after the entry in which they are defined has been published. +
+ - Generate a preliminary DID Log Entry JSON array with the following JSON items:
+
-
+
- The
versionId
MUST beversionId
value from the previous DID Log Entry.
+ - The
versionTime
value MUST be an ISO8601 format time. The time +MUST be greater than the time of the previous log entry, and MUST be less +than or equal to the current time.
+ - The parameters passed in as a JSON object. +
- Generate a JSON Patch to evolve the previous DIDDoc version to
+the new DIDDoc version, and put the resulting patch in the item as
+
{"patch": <DIDDoc Patch>}
. For details of the process, see the +Generating and Applying a JSON Patch +section of this specification. +-
+
- An implementation MAY skip the JSON Patch process and
+simply put the full new version of the DIDDoc in the item
+
{"value": <DIDDoc>}
as is done in the initial entry in the log.
+
+ - An implementation MAY skip the JSON Patch process and
+simply put the full new version of the DIDDoc in the item
+
+ - The
- Calculate the new
versionId
of the new DID Log Entry, including +incrementing the version number integer and using the process described in +the Entry Hash Generation and Verification +section of this specification.
+ - Replace the value of the
versionId
item in the preliminary DID Log with the value produced in the previous step.
+ - Generate a Data Integrity proof on the new DIDDoc of the entry
+using an authorized key, and the
versionId
as the proof +challenge
. The definition of “authorized” is formalized in the +Authorized Keys section of this specification.
+ - If the DID Controller has opted to use witnesses for the +DID, collect the required approvals from the DID’s witnesses, adding +their proofs to the data integrity proof. See the DID +Witnesses section of this specification. +
- The proof array MUST be added as the fifth and last JSON item in the log entry. +
- The entry MUST be made a JSON Line by removing extra whitespace, adding a
\n
+to the entry.
+ - The new log entry MUST be appended to the existing contents of
+the DID Log file
did.jsonl
.
+ - The updated DID Log file MUST be published the appropriate
+location defined by the
did:tdw
identifier. +-
+
- This is a logical operation – how a deployment serves the
did.jsonl
+content is not constrained.
+
+ - This is a logical operation – how a deployment serves the
A controller MAY generate an equivalent, updated did:web
DIDDoc and
+publish it as defined in the
+Publishing a Parallel did:web
DID
+section of this specification.
§ Deactivate (Revoke)
+To deactivate the DID, the DID Controller SHOULD add to the DID log entry parameters the item "deactivated": true
. A DID MAY update the DIDDoc further to indicate the deactivation of
+the DID, such as including an empty updateKeys
list ("updateKeys": []
) in
+the parameters, preventing further versions of the DID.
A resolver encountering in the DID log entry parameters the
+item "deactivated": true
MUST return in the DIDDoc Metadata the JSON item
+"deactivated": true
, as per the [[spec:DID-RESOLUTION]] specification.
§ DID Method Processes
+The DID Method Operations reference several processes +that are executed during DIDDoc generation and DID resolution verification. Each +of those processes is specified in the following sections.
+§ did:tdw
DID Method Parameters
+Entries in the did:tdw
DID Log file contain, in the 3rd item, a JSON
+object that defines the DID processing parameters being used by the DID when publishing that and subsequent DID log entries. A DID Resolver
+will use the same parameters when processing the DID Log to resolve the
+DID. The parameters object MUST include only the items defined in this
+specification.
An example of the JSON prettified parameters item in the first DID Log entry for a DID:
+{
+ "prerotation": true,
+ "portable": false,
+ "updateKeys": [
+ "z82LkqR25TU88tztBEiFydNf4fUPn8oWBANckcmuqgonz9TAbK9a7WGQ5dm7jyqyRMpaRAe"
+ ],
+ "nextKeyHashes": [
+ "enkkrohe5ccxyc7zghic6qux5inyzthg2tqka4b57kvtorysc3aa"
+ ],
+ "method": "did:tdw:0.3",
+ "scid": "{SCID}"
+}
+
+The allowed parameter items and (where applicable) enumerated values for those +items are defined below.
+-
+
method
: Defines thedid:tdw
specification version to use when processing a +given DID’s log file. As new versions of this specifications are +defined, additional parameters and enumerated values will be added to this. This +allows a long lasting DID to evolve the settings being used by the DID over time, +such as changing the hash algorithm used, or the Data Integrity cryptosuite. +-
+
- This item MUST appear in the first DID log entry. +
- This item MAY appear in later DID log entries to indicate that +the processing rules for that and later entries have been changed to a +different specification version. +
- Acceptable values for this specification are:
+
-
+
did:tdw:0.3
: Requires that the rules defined in this specification be used +in processing the log. Implied by the value are the following: +-
+
- The permitted hash algorithms used by the DID Controller MUST be
SHA-256
as defined in [RFC6234].
+ - The permitted Data Integrity cryptosuites used by the DID Controller MUST be
eddsa-jcs-2022
as referenced in eddsa-jcs-2022.
+
+- The permitted hash algorithms used by the DID Controller MUST be
+
+scid
: The value of the SCID for this DID. +-
+
- This item MUST appear in the first DID log entry. +
+updateKeys
: A list of one or more multikey formatted public keys +associated with the private keys that are authorized to sign the log entries +that update the DID from one version to the next. An instance of the list in +an entry replaces the previously active list. If an entry does not have the +updateKeys
item, the currently active list continues to apply. See the +Authorized Keys section of this specification for +additional details. +-
+
- This item MUST appear in the first DID log entry. +
- A key from the
updateKeys
item in the first DID log entry +MUST be used to authorize the initial log entry. In all other +DID log entries, anupdateKeys
item becomes active after the +publication of its entry – meaning its log entry MUST be +signed by a key the most recentupdateKeys
list from a prior DID log entry.
+
+portable
: A boolean (true
/false
) indicating if the DID is portable and +thus can be renamed to change the Web location of the DID. +-
+
- The value can ONLY be set to
true
in the first log entry, the initial version of the DID.
+ - If not explicitly set in the first log entry, it is set to
false
.
+ - Once the value has been set to
false
, it cannot be set back totrue
.
+ - See the section of this specification on DID Portability
+for more details about renaming a
did:tdw
DID.
+
+- The value can ONLY be set to
prerotation
: A boolean value indicating that subsequent authentication keys +added to the DIDDoc (after this version) MUST have their hash included in +anextKeyHashes
parameter item. +-
+
- The value is initialized to
false
until the item is included in a +DID log entry.
+ - Once the value is set to
true
in a DID log entry it MUST NOT +be set tofalse
in a subsequent entry.
+
+- The value is initialized to
nextKeyHashes
: An array of strings that are hashes of multikey +formatted public keys that MAY be added to theupdateKeys
list in the +log entry of a future version of the DID. +-
+
- The process for generating the hashes and additional details for using pre-rotation are defined in the +Pre-Rotation Key Hash Generation and Verification +section of this specification. +
- If the parameter
prerotation
has been set totrue
, all multikey +formatted public keys added in a newupdateKeys
list MUST have their +hashes listed in the currently activenextKeyHashes
list.
+ - A DID Controller MAY put extra strings in the
nextKeyHashes
+item that are not subsequently used in anupdateKeys
entry.
+ - When
prerotation
is active and theupdateKeys
parameter is included in a +parameters item, anextKeyHashes
item with a new set of hashes +MUST be included in the same parameters item. Any unused +hashes in the priornextKeyHashes
are ignored.
+
+witness
: A JSON object containing the parameters for declaring the witnesses +for the DID, and the parameters for the process of updating a DID via a +collaboration with witnesses prior to publication. For details of +this item data and its usage in the approvals process, see the +DID Witnesses section of this specification. +-
+
- A
witness
item in the first DID log entry is used to define the +witnesses and necessary threshold for that initial log entry. In all other +DID log entries, awitness
item becomes active after the publication +of its entry – meaning its log entry MUST be witnessed by the most recent +witnesses
from a prior DID log entry.
+
+- A
deactivated
: A JSON boolean that SHOULD be set totrue
when the DID is to +be deactivated. See the deactivate (revoke) section of +this specification for more details.
+ttl
: A number, the number of seconds that a cache entry for a resolved +did:tdw
DID SHOULD last, as recommended by the DID Controller. A +resolver can use this value in deciding whether to retrieve a new version of +the DID’sdid.jsonl
file. If not specified, resolvers MAY set a default +based on the business needs of the resolver clients. +-
+
- Caching a
did:tdw
can be valuable in places where the business rules +require resolving a number of DID URLs for the same DID. For example, a +client might want call the resolver to the current DIDDoc, and then make +repeated calls to get all of the previous versions of the DIDDoc. By caching +the DIDDoc state, the resolver would not have to retrieve and process the +DID Log on each call.
+ - A Web Server handling one or more
did.jsonl
files MAY be configured to +use a comparable HTTP TTL per [RFC9111].
+
+- Caching a
§ SCID Generation and Verification
+The self-certifying identifier or SCID
is a required parameter in the
+first DID log entry and is the hash of the DID’s inception event.
§ Generate SCID
+To generate the required SCID for a did:tdw
DID, the DID Controller
+MUST execute the following function:
base58btc(multihash(JCS(preliminary log entry with placeholders), <hash algorithm>))
Where:
+-
+
-
+
The
+preliminary [[ref: log entry]] with placeholders
consists of the following +pre-publication JSON array of what will become the first log entry. The +placeholder is the literal string “{SCID}
”.-
+
- The
versionId
entry, which MUST be{SCID}
.
+ - The
versionTime
entry, which MUST be a string that is the current time in +ISO8601 format, e.g.,"2024-04-05T07:32:58Z"
+ - The complete
parameters
for the initial log entry as defined by the +DID Controller, with the placeholder wherever the SCID will +eventually be placed.
+ - The
{"value": <DIDDoc>}
element with placeholders wherever the SCID will +eventually be placed in the DIDDoc.
+
+ - The
-
+
+JCS
is an implementation of the JSON Canonicalization Scheme +[RFC8785]. It outputs a canonicalized representation of its JSON +input.
+ -
+
+multihash
is an implementation of the multihash specification. Its +output is a hash of the input using the associated<hash algorithm>
, +prefixed with a hash algorithm identifier and the hash size.
+ -
+
+<hash algorithm>
is the hash algorithm used by the DID Controller. +The hash algorithm MUST be one listed in the +parameters defined by the version of the +did:tdw
specification being used by the DID Controller.
+ -
+
+base58btc
is an implementation of the base58btc function. +Its output is the base58 encoded string of its input.
+
§ Verify SCID
+To verify the SCID of a did:tdw
DID being resolved, the resolver
+MUST execute the following process:
-
+
- Extract the first DID log entry and use it for the rest of the steps +in this process. +
- Extract the
scid
item value from the parameters in the DID log entry.
+ - Determine the hash algorithm used by the DID Controller from the multihash
scid
value. +-
+
- The hash algorithm MUST be one listed in the
+parameters defined by the version of the
+
did:tdw
specification being used by the DID Controller based on the +method
parameters item.
+
+ - The hash algorithm MUST be one listed in the
+parameters defined by the version of the
+
- Remove the data integrity proof item from the first DID log entry. +
- Replace the
versionId
item’s value with the literal"{SCID}"
.
+ - Treat the resulting log entry as a string and do a text replacement of the
scid
+value from Step 2 with the literal string{SCID}
.
+ - Use the result and the hash algorithm (from Step 3) as input to the function +defined in the Generate SCID section (above). +
- The output string MUST match the
scid
extracted +in Step 2. If not, terminate the resolution process with an error.
+
§ Entry Hash Generation and Verification
+The entryHash
follows the version number and dash character -
in the
+versionId
item in each DID log entry. Each entryHash
is calculated
+across its log entry, excluding the Data Integrity proof. The
+versionId
used in the input to the hash is a predecessor value to the current
+log entry, ensuring that the entries are cryptographically “chained”
+together in a microledger. For the first log entry, the predecessor
+versionId
is the SCID (itself a hash), while for all other entries it is the
+versionId
item from the previous log entry.
§ Generate Entry Hash
+To generate the required hash for a did:tdw
log entry, the DID Controller
+MUST execute the process base58btc(multihash(JCS(entry), <hash algorithm>))
given a
+preliminary log entry as the string entry
, where:
-
+
JCS
is an implementation of the JSON Canonicalization Scheme +([RFC8785]). Its output is a canonicalized representation of its +input.
+multihash
is an implementation of the multihash specification. Its +output is a hash of the input using the associated<hash algorithm>
, +prefixed with a hash algorithm identifier and the hash size.
+<hash algorithm>
is the hash algorithm used by the DID Controller. +The hash algorithm MUST be one listed in the +parameters defined by the version of the +did:tdw
specification being used by the DID Controller.
+base58btc
is an implementation of the base58btc function. +Its output is the base58 encoded string of its input.
+
The following is an example of a preliminary log entry that is processed to
+produce an entry hash. As this is a first entry in a DID Log, the input
+entryHash
(first item) is the SCID of the DID.
["Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu", "2024-07-29T17:00:27Z", {"prerotation": true, "updateKeys": ["z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc"], "nextKeyHashes": ["QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv"], "method": "did:tdw:0.3", "scid": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu"}, {"value": {"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1"], "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example"}}]
+
+Resulting entry hash: QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ
§ Verify The Entry Hash
+To verify the entryHash
for a given did:tdw
DID log entry, a DID
+Resolver MUST execute the following process:
-
+
- Extract the
versionId
(first item) in the DID log entry, and +remove from it the version number and dash prefix, leaving the log entry +entryHash
.
+ - Determine the hash algorithm used by the DID Controller from the multihash
entryHash
value. +-
+
- The hash algorithm MUST be one listed in the
+parameters defined by the version of the
+
did:tdw
specification being used by the DID Controller based on the +method
parameters item set in the current or most recent prior log entry.
+
+ - The hash algorithm MUST be one listed in the
+parameters defined by the version of the
+
- Remove the Data Integrity proof (5th item) from the log entry. +
- Set the first item of the entry to the
versionId
(first item) of the +previous log entry. If this is the first entry in the log, set the value to +the<scid>
, the SCID of the DID.
+ - Calculate the hash string as
base58btc(multihash(JCS(entry), <hash algorithm>))
, where: +-
+
entry
is the data from the previous step.
+JCS
is an implementation of the JSON Canonicalization Scheme +([RFC8785]). Its output is a canonicalized representation of its +input.
+multihash
is an implementation of the multihash specification. +Its output is a hash of the input using the associated<hash algorithm>
, +prefixed with a hash algorithm identifier and the hash size.
+<hash algorithm>
is the hash algorithm from Step 2.
+base58btc
is an implementation of the base58btc function. +Its output is the base58 encoded string of its input.
+
+ - Verify that the calculated value matches the extracted
entryHash
value from +Step 1. If not, terminate the resolution process with an error.
+
§ Authorized Keys
+Each entry in the DID Log MUST include a Data Integrity
+proof signed by a key authorized to control (create, update, deactivate) the
+DID. The authorized verification keys for did:tdw
are the multikey-formatted
+public keys in the active updateKeys
list from the parameters
item of
+the log entries. Any of the authorized verification keys may be referenced
+in the Data Integrity proof.
For the first log entry the active updateKeys
list is the one in
+that first log entry. For all subsequent entries, the active list
+is the most recent updateKeys
before the log entry to be verified. Thus,
+the general case is that each log entry is signed by the keys from the
+previous log entry. Once a log entry containing an updateKeys
list is
+published, that updateKeys
becomes the active list, and the previous
+updateKeys
are ignored.
A resolver of the DID MUST verify the signature and that the key used for
+signing each DID Log entry is one from the list of active updateKeys
.
+If not, terminate the resolution process with an error.
The did:tdw
Implementation Guide contains further discussion on the management
+of keys authorized to update the DID.
§ Generating and Applying a JSON Patch
+Each time a new did:tdw
version is created, the DID Controller
+MAY generate a JSON Patch to concisely define the changes in the
+DIDDoc from the previous version. A DID log entry that uses JSON Patch
+has a JSON object with a patch
property, with the value the JSON Patch as its DIDDoc State
(fourth) item. A DID Controller MAY set the
+DIDDoc State
item of a DID log entry to be the JSON item value
, with its
+value the complete DIDDoc. Typically (but not required), a DID Controller
+will use value
for the first DID log entry and patch
for all
+subsequent entries.
To create the value for a patch
item for a DID log entry, the DID Controller MUST:
-
+
- Have the fully resolved previous version of the DIDDoc. +
- Have the updated new version of the DIDDoc to be added. +
- Execute an implementation of JSON Patch that takes the two DIDDocs +as inputs (previous before, new after) and outputs the resulting JSON Patch +from before to after. +
- Set the
DIDDoc State
(fourth) item of the DID log entry to{"patch": "<patch>"}
, +where<patch>
is the output of the previous step.
+
When processing a DID log entry with a patch
as the fourth item, a
+resolver MUST:
-
+
- Have the fully resolved previous version of the DIDDoc. +
- Extract the value of the
DIDDoc State
(fourth) item of the DID log entrypatch
value. +-
+
- If the
DIDDoc State
item isvalue
, its value is the DIDDoc, and the +next step is not needed.
+
+ - If the
- Execute an implementation of JSON Patch that takes the previous
+DIDDoc and the extracted
patch
value as inputs, and outputs the +resulting new version of the DIDDoc.
+
The output is the DIDDoc for that version of the DID.
+§ DID Portability
+As noted in the Update (rotate) section of the specification,
+a did:tdw
DID can be renamed by changing the id
DID string in the
+DIDDoc to one that resolves to a different HTTPS URL if the following conditions are met.
-
+
- The DID Log of the renamed DID MUST contain all of the log from the creation of the DID. +
- The log entry in which the DID is renamed MUST be a valid DID entry +building on the prior DID log entries, per this specification. +
- The parameter
portable
MUST be set totrue
, as defined in the +DID Method Parameters section.
+ - The SCID MUST be the same in the original and renamed DID. +
- The DIDDoc MUST contain the prior DID string as an
alsoKnownAs
entry.
+
§ Pre-Rotation Key Hash Generation and Verification
+Pre-rotation requires a DID Controller to commit to the authorization +keys that will later be used (“rotated to”) for updating the DIDDoc. The purpose +of committing to future keys is that if the currently authorized keys are +compromised by an attacker, the attacker should not be able to take control of +the DID by using the compromised keys to rotate to new keys the attacker +controls. Assuming the attacker has not also compromised the committed key +pairs, they cannot rotate the authorization keys without detection. See the +non-normative section about Pre-Rotation[Using Pre-Rotation Keys](#using-pre-rotation-keys) +in the Implementer’s Guide for additional guidance.
+As described in the parameters
+section of this specification, a DID Controller MAY define that
+prerotation
is active for the DID (value true
). When pre-rotation is active,
+all verification multikeys in the updateKeys
parameters item in other
+than the initial version of the DIDDoc MUST have their hash in the currently
+active nextKeyHashes` arrays from a previous DID log entry. If
+not, terminate the resolution process with an error.
To create a hash to be included in the nextKeyHashes
array, the DID MUST execute the following process for each possible future
+authorization key.
-
+
- Generate a new key pair. +
- Generate a multikeys representation of the public key of the new key +pair. +
- Calculate the hash string as
base58btc(multihash(multikey))
, where: +-
+
multikey
is the multikey representation of the public key from Step 2.
+multihash
is an implementation of the multihash specification. +Its output is a hash of the input using the associated<hash algorithm>
, +prefixed with a hash algorithm identifier and the hash size.
+<hash algorithm>
is the hash algorithm used by the DID Controller. +The hash algorithm MUST be one listed in the +parameters defined by the version of the +did:tdw
specification being used by the DID Controller.
+base58btc
is an implementation of the base58btc function. +Its output is the base58 encoded string of its input.
+
+ - Insert the calculated hash into the
nextKeyHashes
array being built up within +the parameters item.
+ - The generated key pair SHOULD be safely stored so that it can be used in
+a later DID version to become a DID authorization key. At that time, the
+multikey representation of the public key will be inserted into the
+
updateKeys
item in the parameters. After that log entry is +published, the private key can be used to sign DID update authorizations +proofs.
+
A DID Controller MAY add extra hashes (for keys or just random
+strings) into a nextKeyHashes
array.
When processing other than the first DID log entry where the
+prerotation
parameter is active, a did:tdw
resolver MUST:
-
+
- For each multikey in the
updateKeys
item in theparameters
of +the log entry, calculate the hash and hash algorithm for the mulithash multikey.
+ - The hash algorithm MUST be one listed in the
+parameters defined by the version of the
+
did:tdw
specification being used by the DID Controller.
+ - The resultant hash MUST in the most recently set
nextKeyHashes
prior to +the log entry being processed. If not, terminate the resolution +process with an error.
+ - A new
nextKeyHashes
list MUST be in theparameters
of the log currently being processed. If not, terminate the resolution process with +an error.
+
§ DID Witnesses
+The witness process for a DID provides a way for other collaborators to +work with the DID Controller to “witness” the publication of a new version of +the DID. Including witnesses can prevent malicious updates to the DID by both +the DID Controller and external parties. This specification defines +the mechanism for using witnesses but leaves the governance and policy +questions about when and how to use the mechanism to implementers.
+Witnesses can prevent a DID Controller from updating/removing DID versions of a +DID without detection. Witnesses are also a further mitigation against malicious +actors compromising both a DID Controller's authorization key(s) to update the +DID, and the DID Controller's web site where the DID log is published. +With both compromises, a malicious actor could take control over the DID by +rewriting the DID Log using the keys they have comprised. By adding +witnesses that monitor and approve each version update, a malicious +actor cannot rewrite the previous history without also compromising a sufficient +number of witnesses.
+An overview of the witness mechanism is as follows:
+-
+
- The DID Controller specifies (in the
parameters
of a log) a list of witnesses, DIDs that together with the DID will contribute to “approving” all subsequent versions of the +DID. +-
+
- Ideally, the DID Controller does that in the inception event for the +DID. +
- Over time, the list of witnesses may evolve, with each change being +approved by the declared list of witnesses from before such a +change. +
+ - The DID Controller prepares a DID Log Entry and shares it with +the witnesses. + + +
- Each witness verifies the DID Log Entry, as defined by this +specification. If not, the witnesses MUST NOT approve the log entry. + + +
- Each witness determines (based on the governance of the ecosystem) +if they approve of the DID version update. + + +
- If the verification is successful and the approval granted, the witness sends a Data Integrity proof to the DID Controller similar
+to that generated by the DID Controller, with the DIDDoc as the signed object,
+the entry log’s
versionId
as the challenge, but signed by the witnesses key.
+ - When a weighted threshold of proofs are received, the DID Controller
+inserts the witnesses's proofs into the array of proofs that are the last item in
+the DID Log Entry and publishes the updated version of the DID.
+
-
+
- In publishing a new version of the DID Log, the DID SHOULD remove the witness Data Integrity proofs from
+earlier entries to reduce the size of the log. Only the set of approval
+proofs on the last log entry are needed because of the chaining of the
+proofs via the use of the
entryHash
challenge.
+ - Removing the prior entry witness proofs does not affect the verifiability of
+the DID because the
entryHash
calculation does not include the proofs item.
+ - The specification leaves to implementers how the proofs are conveyed to +the DID Controller. +
+ - In publishing a new version of the DID Log, the DID SHOULD remove the witness Data Integrity proofs from
+earlier entries to reduce the size of the log. Only the set of approval
+proofs on the last log entry are needed because of the chaining of the
+proofs via the use of the
::: to do
+To Do: Update to use a Data Integrity Proof Set, where the authorized key identifies +the proof, and the witnesses proofs reference the identifier.
+:::
+As with the handling of the updateKeys
, DID Log Entry changes require
+proofs from the the witnesses active prior to the publication of a
+new version. If a new version changes the list of witnesses, that
+change must be approved by the prior witnesses. For the first entry
+in the DID Log, the witnesses listed in that entry must
+approve the version, since there are no “prior” witnesses.
The data object for the witness
parameters item is as follows.
+The threshold design borrows from the verifiable conditions
+specification.
"witness" : {
+ "threshold": n,
+ "selfWeight": n,
+ "witnesses" : [
+ {
+ "id": "<DID of witness>",
+ "weight": n
+ }
+ ]
+}
+
+where:
+-
+
threshold
: an integer that must be attained or surpassed by the sum of the witnesses and +DID Controller's weights for a DID log entry to be considered approved.
+selfWeight
: an integer that is the weight given the DID Controller's +verified proof, in determining if the threshold has been surpassed.
+witnesses
: an array of witnesses +-
+
id
: the DID of the witness
+weight
: the weight of this witness's approval
+
+
The use of the threshold and weighted approvals (versus needing approvals from
+all witnesses) is to prevent faulty witnesses from blocking the publishing of
+a new version of the DID. To determine if the threshold has been passed, sum the
+weight
integer of the received approvals, plus the selfWeight
of the DID, and if it equal to or more than threshold
, the update can be
+published. The calculation MUST also be executed by resolvers processing a
+DID Log. For example, if there are three witnesses, each with a weight
of 1,
+the DID Controller with a selfWeight
of 2, and a threshold
of 4, the
+threshold will be met by two witnesses approving the change, plus the DID.
See the Implementer’s Guide section on Witnesses for more +discussion on the witness capability and using it in production scenarios.
+§ Publishing a Parallel did:web
DID
+Each time a did:tdw
version is created, the DID Controller MAY
+generate a corresponding did:web
to publish along with the did:tdw
. To do
+so, the DID Controller MUST:
-
+
- Start with the resolved version of the DIDDoc from
did:tdw
.
+ - Execute a text replacement across the DIDDoc of
did:tdw:<SCID>:
to +did:web:
, where<scid>
is the actualdid:tdw
SCID.
+ - Add to the DIDDoc
alsoKnownAs
array, the fulldid:tdw
DID. If the +alsoKnownAs
array does not exist in the DIDDoc, it MUST be added.
+ - Publish the resulting DIDDoc as the file
did.json
at the web location +determined by the specifieddid:web
DID-to-HTTPS transformation.
+
The benefit of doing this is that resolvers that have not been updated to
+support did:tdw
can continue to resolve the DID Controller's DIDs.
+did:web
resolvers that are aware of did:tdw
features can use that knowledge,
+and the existence of the alsoKnownAs
did:tdw
data in the DIDDoc to get the
+verifiable history of the DID.
The risk of publishing the did:web
in parallel with the did:tdw
is that the
+added security and convenience of using did:tdw
are lost.
§ DID URL Resolution
+The did:tdw
DID Method embraces the power and usefulness of DID URLs, along
+with the semantic simplicity of using them with a web-based DID method.
+Specifically, a did:tdw
implementation MUST:
-
+
- Resolve the
/whois
DID URL path using a [[spec:LINKED-VP]] service, whether +or not it exists in thedid:tdw
DIDDoc, returning a Verifiable, if published by the DID Controller, found at the same +path as thedid.jsonl
file, using the/whois.vp
filename component, and +the `application/vp’ media type, as per the IANA Verifiable Presentation +Assignment. +-
+
- For example,
did:tdw:{SCID}.example.com/whois
returns the verifiable fromhttps://{SCID}.example.com/.well-known/whois.vp
.
+
+ - For example,
- Resolve any
did:tdw
DID URL using a [DID-CORE]relativeRef
DID +parameter, whether or not a supporting service exists in thedid:tdw
DIDDoc, +returning the file found at web location corresponding to the DID-to-HTTPS +transformation. +-
+
- For example, resolving
did:tdw:example.com:{SCID}/governance/issuers.json
returns +the filehttps://example.com/{SCID}/governance/issuer.json
+ - When the
{SCID}
is placed as a subdomain, the file is found relative to +that subdomain, and not in the.well-known
folder where thedid.jsonl
+file is found. For example, resolving +did:tdw:{SCID}.example.com/governance/issuers.json
returns the file +https://{SCID}.example.com/governance/issuer.json
.
+
+ - For example, resolving
In both cases, a DID Controller MAY define services in the DIDDoc
+that override the default services that MUST be resolved by the did:tdw
+DID Method.
The sections below formalize the services that exist by default in did:tdw
and
+how a DID Controller can override them.
§ whois LinkedVP Service
+The #whois
service enables those that receive a did:tdw
DID to retrieve and
+a Verifiable Presentation (and embedded Verifiable) the DID Controller has decided to publish about itself.
+The intention is that anyone wanting to learn more about a particular did:tdw
+DID can resolve the <did>/whois
DID URL to retrieve a Verifiable published by the DID Controller that contains Verifiable Credentials with the DID as the subject. The DID Controller
+includes in the Verifiable Presentation any Verifiable Credentials that it
+thinks might be helpful for resolvers in making a trust decision about the DID.
It is up to the DID Controller to decide to publish a whois
+verifiable presentation, and which verifiable credentials to put into the
+verifiable presentation. It is up to a DID resolver to decide what attestations
+from third parties are useful in making a trust decision about the DID.
did:tdw
DIDs automatically supports a /whois
service endpoint with the
+following definition based on the [[spec:LINKED-VP]] specification, with the
+serviceEndpoint
defining a similar did:tdw
DID-to-HTTPS DID Log
+transformation with did.jsonl
changed to whois.vp
. Differing from the
+DID-to-HTTPS transformation is that the
+.well-known/
component of the did.jsonl
transformation is dropped from the
+whois.vp
resolution.
{
+ "@context": "https://identity.foundation/linked-vp/contexts/v1",
+ "id": "#whois",
+ "type": "LinkedVerifiablePresentation",
+ "serviceEndpoint": "<did-to-https-translation>/whois.vp"
+}
+
+The returned whois.vp
MUST contain a W3C VCDM verifiable signed by the DID and containing verifiable credentials
+that MUST have the DID as the credentialSubject
.
A DID Controller MAY explicitly add to their DIDDoc a did:tdw
+service with the "id": "#whois"
. Such an entry MUST override the implicit
+service
above. If the DID Controller wants to publish the whois
+verifiable presentation in a different format than the W3C format, they MUST explicitly add to their DIDDoc a service with the
+"id": "#whois"
to specify the name and implied format of the verifiable.
To resolve the DID URL <did:tdw DID>/whois
, the resolver MUST:
-
+
- Resolve the given
did:tdw
DID by retrieving, processing, and verifying the +DID log for thedid:tdw
as defined in this specification.
+ - Find the DIDDoc
service
with theid
#whois
, if any, or use the implicit +service (above).
+ - Resolve the
serviceEndpoint
URL, if possible, and return the document +found. +-
+
- If the
serviceEndpoint
URL can’t be resolved by the resolver (such as if +the URL protocol is not supported by the resolver), the errorError XXX: YYY
MUST be returned.
+ - If the file at the defined
serviceEndpoint
is not found,Error 404: Not Found
MUST be returned.
+
+ - If the
§ DID URL Path Resolution Service
+The automatic resolution of did:tdw
DID URL paths follows the
+[DID-CORE] relativeRef
specification, as follows:
-
+
- a DID path, such as example 2 in section 3.2 DID URL
+Syntax gives the example:
+
did:example:123456/resume.pdf
+ - In turn, that can be treated as the following, as shown in example 8 in the
+same section:
did:example:123456?service=files&relativeRef=/resume.pdf
+ - The
#files
service defined below then defines theserviceEndpoint
for the +relativeRef
. +-
+
- For
did:tdw
, that service is implicitly defined, with the +serviceEndpoint
matching thedid:tdw
DID-to-HTTPS +transformation anddid.jsonl
replaced +by the DID URL Path. If.well-known/
is part of the HTTPS URL, it is +removed from the URL before resolving the URL.
+
+ - For
Thus, the implicit service for DID did:tdw:example.com:dids:<scid>
is:
{
+ "id": "#files",
+ "type": "relativeRef",
+ "serviceEndpoint": "https://example.com/dids/<scid>"
+}
+
+A DID Controller MAY explicitly add to their DIDDoc a service with
+the "id": "#files"
. Such an entry MUST override the implicit service
+defined above.
To resolve the DID URL <did:tdw DID>/path/to/file
, the resolver MUST:
-
+
- Resolve the given
did:tdw
DID by retrieving, processing, and verifying the +DID log for thedid:tdw
as defined in this specification.
+ - Find the DIDDoc
service
with theid
#files
, if any, or use the implicit +service (above).
+ - Resolve the
serviceEndpoint
URL with the DID URL Path appended, if +possible, and return the document found at that location. +-
+
- If the
serviceEndpoint
URL can’t be resolved by the resolver (such as if +the URL protocol is not supported by the resolver), the errorError XXX: YYY
MUST be returned.
+ - If the file at the path appended to the defined
serviceEndpoint
is not +found, the errorError 404: Not Found
MUST be returned.
+
+ - If the
§ Security and Privacy Considerations
+§ DNS Considerations
+§ DNS Security Considerations
+Implementers must secure DNS resolution to protect against attacks like Man in +the Middle, following the detailed guidance in the did:web +specification. +The use of DNSSEC [RFC4033], [RFC4034], [RFC4035] is +essential to prevent spoofing and ensure authenticity of DNS records.
+§ DNS Privacy Considerations
+Resolving a did:tdw
identifier can expose users to tracking by DNS providers
+and web servers. To mitigate this risk, it’s recommended to use privacy-enhancing
+technologies such as VPNs, TOR, or trusted universal resolver services, in line
+with strategies outlined in the did:web
+specification
+including emerging RFCs such as Oblivious DNS over
+HTTPS
+for DNS privacy.
§ In-transit Security
+For in-transit security, the guidance provided in the did:web +specification +regarding the encryption of traffic between the server and client should be +followed.
+§ International Domain Names
+[DID-CORE] identifier syntax does not allow Unicode in method name nor +method specific identifiers.
+Implementers should be cautious when implementing support for DID URLs that rely +on domain names or path components that contain Unicode characters.
+See also:
+ +§ Implementors Guide
+§ Implementations
+Proof of concept implementations of did:tdw
software for DID Controllers and resolvers can be found here:
-
+
- Typescript +
- Python +
- Go +
Both currently (as of 2024.04.11) support all of the features of the core did:tdw
including Key Pre-Rotation. Not yet supported is the the concept of witnesses.
§ Using Pre-Rotation Keys
+In an effort to prevent the loss of control over a decentralized identifier +(DID) due to a compromised private key, pre-rotation keys are +introduced. These commitments, made by the DID Controller, are +declarations about the keys that will be published in future versions of the DID +document, without revealing the keys themselves.
+The primary goal of pre-rotation keys is to ensure that even if an attacker +gains access to the current active key, they will not be able to take control of +the DID. This safeguard is achieved because the attacker could not simply rotate to +a key they generate and control. Rather, they would need to have also +compromised the unpublished (and presumably securely stored) pre-rotation key in +order to rotate the DID keys.
+The cost of having pre-rotation protection is a much more complicated process to update +the keys of a DID. The following are some considerations we have come across in +considering how to use the pre-rotation feature. The feature definitely adds a +layer of key management complexity in return for the benefit.
+§ Key Rotation with Pre-Rotation
+In using pre-rotation, a DID Controller should generate an “active” key +for the DIDDoc where it can be used for “production” purposes (signing, +decrypting), and generates the “next key” in an isolated location from +production. This prevents both the “active” and “next key” from being compromised in the +same attack. For example, an intruder gets into your infrastructure and is able to extract all of your +private keys both DID control keys would be lost. Thus, we expect the feature to be used as follows:
+-
+
- The DID Controller creating the DID would request from an isolated +service the hash of the “next key” as defined in this specification. For +example, an entity might have the “active” DID/key hosted by one Cloud +Provider, and the “next key” by another, on the theory that an attacker might +get into one environment or another but not both. +
- When a key rotation is to be done, two entries are put in the log, using the following steps by the DID Controller:
+
-
+
- Get the full key reference entry from the isolated service for the pre-rotation “nextKey”. +
- Locally generate a pre-rotation key hash for a new key that will soon become the “active” key. +
- Add a DID log entry that includes the items from the previous two steps, and signs the proof using an authorized key (that presumably it controls, though not required). +
- Although the DID log could be published now, it is probably best to hold off and publish it after adding a second, as described by the rest of the steps. +
- Get a new pre-rotation hash from the isolated service. +
- Get the full key-rotation key reference for the pre-rotation hash created for the last DID log entry. +
- Add a DID Log entry that includes the items from the previous two step +
- If the key rotated in the previous DID log entry was a/the
+authorized key to make updates to the DID, call the isolated service to produce
+the Data Integrity proof over the entry using the key the isolated
+service controls.
+
-
+
- This step is not needed if the active service has a key authorized to sign the DIDDoc update. +
+ - Publish the new DID log containing the two new entries. +
+
§ Post Quantum Attacks
+One of the potential benefits of this approach to pre-rotation is that it is
+“post-quantum safe”. The idea is that in a post-quantum world, the availability
+of the published key and signatures may enable the calculation of the
+corresponding private key. Since the pre-rotation value is a hash of the
+nextKey
and not the public key itself, a post-quantum attack would not
+compromise that key, and so a further rotation by the attacker would not be
+possible. If there was a (suspected) need to transition to using a quantum-safe
+key, the same process listed above would be used, but key reference and the
+pre-rotation hash added into the second DID log entry would presumably
+both be for quantum-safe keys.
§ Challenges in Using Pre-Rotation
+This draft specification states that once pre-rotation is enabled (via DID log entry parameter), it MUST apply to all of the keys in the +DIDDoc. However, we’re not sure if that is needed, or if the pre-rotation should +only apply to keys that are authorized to update the DID.
+Key management is hard enough without having to maintain isolated key generation +environments for creating keys for different purposes. Enabling connectivity between +the key generation environments to enable automated key rotation while maintaining the +key recovery environment as “isolated” is technically challenging.
+§ Using DID Portability
+As noted in the DID Portability section of the
+specification, a did:tdw
DID can be renamed (ported) by changing the id
DID string in
+the DIDDoc to one that resolves to a different HTTPS URL, as long as the
+specified conditions are met.
While the impact of the feature is in fact the creation of a new DID, we think +there is significant value in some use cases for supporting the specified +capability. Ideally, the HTTPS URL for the “old” DID is changed to a redirect to +the new DID, allowing for a seamless, verifiable evolution of the DID.
+An interesting example use case is a DID that replaces an email address hosted +by a particular service. The extra capabilities of having the identifier being a +DID vs. an email address is compelling enough, allowing it to be used for a +range of services beyond email. The portability benefit comes when the owner of +the DID decides to move to a new service, taking their DID with them. The +verifiable history carried over to the renamed DID hosted by the new service +provides assurance to those who interacted with the old DID (through chats, +emails, postings, etc.) that they are still engaging with the same entity, +despite the DID renaming. Compare that with what happens today when you switch +from one email provider to another, and you have to reach out to all your +contacts to assure them that you changed providers.
+While portability is powerful, it must be used with care and only in use
+cases where the capability is specifically required. When used, both the
+pre-rotation and witnesses features of did:tdw
SHOULD also be enabled.
§ Mergers, Acquisitions and Name Changes
+Organizations change over time and such changes often involve names changes. +Name changes in turn trigger domain name changes, as organizations match their +Web location with their names. Mergers, acquisitions, and simple name changes, +all can cause an organization’s “known” domain name to change, including the +relinquishment of control over their previous domain name. When such changes +occur, it is very unlikely that just because the organization’s DIDs use the old +domain name will prevent the changes. Thus the DIDs need to “adapt” to the new +domain – the domain name portion of the DID has to change. Ideally, the old +location and domain can be retained and a web redirect used to resolve the old +DID to the new, but even if that cannot be done, the ability to use the same +SCID and retain the full history can be preserved.
+§ DID Hosting Service Providers
+Consider being able to replace the current identifiers we are given (email
+addresses, phone numbers) with did:tdw
DIDs. Comparable hosting platforms
+might publish our DIDs for us (ideally, with us in custody of our own private
+keys…). Those DIDs, with the inherent public keys can be used for many
+purposes – encrypted email (hello PGP!), messaging, secure file sharing, and
+more.
From time to time in that imagined future, we may want to move our DIDs +from one hosting service to another, just as we move from one email or mobile +provider to another. With DIDs that can move and retain the history, we can make +such moves smoothly. Contacts will see the change, but also see that the history +of the DID remains.
+§ Challenges in Moving a DID
+While we see great value (and even a hard requirement) for being able to move a +DID’s web location, it does create challenges in aligning with the +[DID-CORE] specification. These challenges are listed below.
+Moving a did:tdw
is actually the (partial or complete) deactivation of the old
+DID and the creation of a new DID. The use of the SCID and the way it
+is generated is designed to prevent an attacker from being able to create a DID
+they control but with the same SCID as existing DID. Thus, “finding” a did:tdw
+with the same SCID implies the DIDs are the same. That can be verified by
+processing the DID Log.
By retaining the incrementing of the versionId
after a move, the “new” DID
+does not start at versionId
of 1
. Further, resolving <new-did>?versionId=1
+is going to return a DIDDoc with the top-level id
equal to the <old-did>
.
+This is useful from a business perspective, but unexpected from a
+[DID-CORE] perspective.
§ Using High Assurance DIDs with DNS
+The High Assurance DIDs with DNS mechanism that can be used with did:web
+applies equally well with did:tdw
. A DID Controller publishing a
+did:tdw
could use the mechanisms defined in the High Assurance DIDs with DNS
+specification despite did:tdw
DIDs not (yet) being explicitly called out in
+the High Assurance DIDs with DNS specification. In particular, as did:tdw
+uses the same DID-to-HTTP transformation, publishing the expected DNS Domain
+records, and adding the required verification method and Data Integrity
+proof to their DIDDoc is done as defined in the High Assurance DIDs
+with DNS specification. Likewise, a resolver can include code to check to see if
+the DID Controller published the High Assurance DIDs with DNS
+specification DNS records and use those to further verify the DID.
Alternatively, since did:tdw
is not mentioned in the High Assurance DIDs with
+DNS specification, a did:tdw
DID Controller could use the “not did:web
”
+technique described in that specification and include a dnsValidationDomain
+entry in the DIDDoc to explicitly denote where to find the DNS records to use in
+binding the DID to the DNS domain. This technique could also be used with
+did:tdw
(and did:web
for that matter) if the DID is published on a platform
+(such as GitHub) and the controller wants to bind it to its DNS domain.
§ Future Possibilities
+In the future, as did:tdw
becomes more accepted, we would like to see
+did:tdw
explicitly added to the High Assurance DIDs with DNS specification
+beside did:web
.
Since did:tdw
and the High Assurance DIDs with DNS specification both have
+the goal of adding methods for additional verifications of the DID, the support
+for did:tdw
in the High Assurance DIDs with DNS could be more specific to
+the DID Method. For example, the key in the DNS record could be a required
+did:tdw
witness, with its Data Integrity proof being a part of the
+DID log entry rather than in the DIDDoc itself.
§ Witnesses
+The term “witness” is often used in the decentralized trust space to refer to +participants in an ecosystem that oversee the evolution of an identifier +according to some ecosystem-specific governance framework. The goal is for a +witness to collect, verify and approve data about the identifier and +share it with others that trust the witness so they don’t need to do +that work themselves. The extra participants are intended to identify both +malicious attackers of the identifier, and malicious use of the identifier by +the DID Controller.
+Witnesses play an explicit function in did:tdw
. When used by a DID, witnesses (themselves identified by DIDs) are sent
+pending DID log entries prepared by the DID Controller. The
+witnesses verify the log entry using their copy of the
+“current state” of the DID, and then “approve” the update, according to the
+governance they use to define what “approval” means. For example, a witness might interact with another party (perhaps even a person) to confirm
+that the DID Controller created the log entry. Once the witness has both verified and approved the change, they express that approval
+by creating a Data Integrity proof that is chained to the data proof created by the DID Controller, and send the proof
+back to the DID Controller. Once the number of data integrity
+proofs received by the DID Controller from the witnesses has
+exceeded a threshold, the DID Controller adds those proofs to their own
+data integrity proof in the log entry. Next, the DID adds the log entry to the DID log and publishes
+the updated DIDDoc. A DID Controller relying on witnesses
+cannot independently publish an update to their DID – they must get and publish
+the witness approval proofs.
The application of witnesses is very much dependent on the governance
+of the ecosystem. Such governance is outside the scope of the did:tdw
+specification, and up to those deploying did:tdw
DIDs. Hence, a DID that controls a series of DIDs and uses those DIDs as witnesses adds no additional trust or security to a DID if no properly defined
+governance is in place. In particular, in order for witnesses to add
+security and trust to a DID requires the members of an ecosystem to agree to the
+defined governance. A witness could be an “endorser” of a set of DIDs
+that are part of an ecosystem, with the act of witnessing the updates conveying
+through their approval that the DIDs are a legitimate participant in the
+ecosystem. Witnesses can also be used as a form of “two-factor
+authentication” of a change, such as having a public key published as a DNS
+record used as a witness for the DID. Such an addition means that an
+attacker would need to compromise both the web-publishing infrastructure of the
+DID Controller (where they publish the DID’s did.jsonl
file) as well as its
+DNS entry.
did:tdw
witnesses have been specified to be simple to implement and use. Their
+power and effectiveness will come in how they are deployed within specific,
+governed ecosystems.
§ did:tdw
Example
+The following shows the evolution of a did:tdw
from inception through several
+versions, showing the DID, DIDDoc, DID Log, and some of the
+intermediate data structures.
The examples are aligned with version 0.3 of the did:tdw
specification.
In some of the following examples the data for the DID log entries is displayed
+as prettified JSON for readability. In the log itself, the JSON has all
+whitespace removed, and each line ends with a CR
, per the JSON Lines convention.
§ DID Creation Data
+These examples show the important structures used in the Create (Register) operation for a did:tdw
DID.
§ Input to the SCID Generation Process with Placeholders
+The following JSON is an example of the input that the DID Controller +constructs and passes into the +SCID Generation Process. In this example, the DIDDoc is +particularly boring, containing the absolute minimum for a valid DIDDoc.
+This example includes both the initial “authorized keys” to sign the Data Integrity proof
+(updateKeys
) and the pre-rotation commitment to the next authorization keys (nextKeyHashes
). Both
+are in the parameters
item in the log entry.
[
+ "{SCID}",
+ "2024-07-29T17:00:27Z",
+ {
+ "prerotation": true,
+ "updateKeys": [
+ "z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc"
+ ],
+ "nextKeyHashes": [
+ "QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv"
+ ],
+ "method": "did:tdw:0.3",
+ "scid": "{SCID}"
+ },
+ {
+ "value": {
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1"
+ ],
+ "id": "did:tdw:{SCID}:domain.example"
+ }
+ }
+]
+
+§ Output of the SCID Generation Process
+After the SCID is generated, the literal {SCID}
placeholders are
+replaced by the generated SCID value (below). This JSON is the input to
+the entryHash
generation process –
+with the SCID as the first item of the array. Once the process has run,
+the version number of this first version of the DID (1
), a dash -
and the
+resulting output hash replace the SCID as the first item in the array
+– the versionId
.
[
+ "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu",
+ "2024-07-29T17:00:27Z",
+ {
+ "prerotation": true,
+ "updateKeys": [
+ "z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc"
+ ],
+ "nextKeyHashes": [
+ "QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv"
+ ],
+ "method": "did:tdw:0.3",
+ "scid": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu"
+ },
+ {
+ "value": {
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1"
+ ],
+ "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example"
+ }
+ }
+]
+
+§ Data Integrity Proof Generation and First Log Entry
+The last step in the creation of the first log entry is the generation
+of the data integrity proof. One of the keys in the updateKeys
parameter MUST be used (in the form of a did:key
) to generate the
+signature in the proof, with the versionId
value (item 1 of the did log) used as the challenge
item. The generated proof is added to the JSON as the fifth item, and the entire array becomes the first entry in the
+DID Log.
The following is the JSON prettified version of the entry log file that is published
+as the did.jsonl
file. When published, all extraneous whitespace is removed, as
+shown in the block below the pretty-printed version.
[
+ "1-QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ",
+ "2024-07-29T17:00:27Z",
+ {
+ "prerotation": true,
+ "updateKeys": [
+ "z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc"
+ ],
+ "nextKeyHashes": [
+ "QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv"
+ ],
+ "method": "did:tdw:0.3",
+ "scid": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu"
+ },
+ {
+ "value": {
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1"
+ ],
+ "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example"
+ }
+ },
+ [
+ {
+ "type": "DataIntegrityProof",
+ "cryptosuite": "eddsa-jcs-2022",
+ "verificationMethod": "did:key:z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc#z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc",
+ "created": "2024-07-29T17:00:27Z",
+ "proofPurpose": "authentication",
+ "challenge": "1-QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ",
+ "proofValue": "zDk24L4vbVrFm5CPQjRD9KoGFNcV6C3ub1ducPQEvDQ39U68GiofAndGbdG9azV6r78gHr1wKnKNPbMz87xtjZtcq9iwN5hjLptM9Lax4UeMWm9Xz7PP4crToj7sZnvyb3x4"
+ }
+ ]
+]
+
+The same content “un-prettified”, as it is found in the did.jsonl
file:
["1-QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ", "2024-07-29T17:00:27Z", {"prerotation": true, "updateKeys": ["z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc"], "nextKeyHashes": ["QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv"], "method": "did:tdw:0.3", "scid": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu"}, {"value": {"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1"], "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example"}}, [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc#z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc", "created": "2024-07-29T17:00:27Z", "proofPurpose": "authentication", "challenge": "1-QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ", "proofValue": "zDk24L4vbVrFm5CPQjRD9KoGFNcV6C3ub1ducPQEvDQ39U68GiofAndGbdG9azV6r78gHr1wKnKNPbMz87xtjZtcq9iwN5hjLptM9Lax4UeMWm9Xz7PP4crToj7sZnvyb3x4"}]]
+
+§ did:web
Version of DIDDoc
+As noted in the publishing a parallel did:web
+DID section of this specification a did:tdw
can be published
+by replacing did:tdw
with did:web
in the DIDDoc, adding an alsoKnownAs
entry for the did:tdw
+and publishing the resulting DIDDoc at did.json
, logically beside the did.jsonl
file.
Here is what the did:web
DIDDoc looks like for the did:tdw
above.
{
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1"
+ ],
+ "id": "did:web:domain.example",
+ "alsoKnownAs": ["did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example"]
+}
+
+§ Version 2 of the DIDDoc
+Time passes, and the DID Controller of the did:tdw
DID decides to
+update its DID to a new version, version 2. In this case, the only change
+the DID Controller makes is transition the authorization key to
+the pre-rotation key.
§ Version 2 Entry Hashing Input
+To generate a new version of the DID, the DID Controller needs to
+provide the existing DID log file, the updated parameters
, and the new DIDDoc.
+The following processing is done to create the new DID log entry:
-
+
- The
versionId
from the previous (first) log entry is made the first item in the new log entry.
+ - The
versionTime
is generated as the current time, and made the newversionTime
(second) item.
+ - The
parameters
entry passed in is processed. In this case, since the +updateKeys
array is updated, and pre-rotation is active, the a +verification is done to ensure that the hash of theupdateKeys
are found in +thenextKeyHashes
item from version 1 of the DID. As required by thedid:tdw
+specification, a newnextKeyHashes
is included in theparameters
.
+ - The new (but unchanged) DIDDoc is included in its entirety, as the value of
value
, set as the third item in the array. +-
+
- The implementation could have used JSON Patch to generate value of the
patch
item.
+
+ - The implementation could have used JSON Patch to generate value of the
- The resulting array is passed into the
entryHash
generation +process which outputs the +entryHash
for this log entry. Once again, the first item +(versionId
) in the log entry is replaced by the version number (the +previous version number plus1
), a dash (-
), and the newentryHash
.
+ - The data integrity proof is generated added to the log entry +as the sixth item, and the entire entry is added to the existing DID. +
The DID log file can now be published, optionally with an updated version of the corresponding did:web
DID.
The following is the JSON pretty-print log entry for the second version of an example did:tdw
. Things to note in this example:
-
+
- The data integrity proof
verificationMethod
is thedid:key
from the first log entry, and thechallenge
is theversionId
from this log entry.
+ - A new
updateKeys
item in theparameters
has been added, a commit to a future key that will control updates to the DID.
+
[
+ "2-QmY2v1VzkeMxF7MSfrLfZswQ74Y6FfrMR1LmuvPJQJwhi6",
+ "2024-07-29T17:00:28Z",
+ {
+ "updateKeys": [
+ "z82Lkvgj5NKYhoFh4hWzax9WicQaVDphN8MMzR3JZhontVfHaoGd9JbC4QRpDvmjQH3BLeQ"
+ ],
+ "nextKeyHashes": [
+ "QmcCbGzGNr2EFduauzCoh3Hwt1GkRW4Gnkk5nxbr3625de"
+ ]
+ },
+ {
+ "value": {
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1"
+ ],
+ "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example"
+ }
+ },
+ [
+ {
+ "type": "DataIntegrityProof",
+ "cryptosuite": "eddsa-jcs-2022",
+ "verificationMethod": "did:key:z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc#z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc",
+ "created": "2024-07-29T17:00:28Z",
+ "proofPurpose": "authentication",
+ "challenge": "2-QmY2v1VzkeMxF7MSfrLfZswQ74Y6FfrMR1LmuvPJQJwhi6",
+ "proofValue": "z2VDUyVapPpb6rC4YbLZRLcWS2zg9o53JU97QjNQYH7JvGs5Ccnf2b647Gw96G5N8rvEKc77uQTGqYvLJ6zrqNwGnqNLraTPD2AL2rR2eUiRKnM5KhbwWumDy5eqmTumm1FWp"
+ }
+ ]
+]
+
+§ Log File For Version 2
+The new version 2 did.jsonl
file contains two entries, one for each version
+of the DIDDoc.
["1-QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ", "2024-07-29T17:00:27Z", {"prerotation": true, "updateKeys": ["z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc"], "nextKeyHashes": ["QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv"], "method": "did:tdw:0.3", "scid": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu"}, {"value": {"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1"], "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example"}}, [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc#z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc", "created": "2024-07-29T17:00:27Z", "proofPurpose": "authentication", "challenge": "1-QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ", "proofValue": "zDk24L4vbVrFm5CPQjRD9KoGFNcV6C3ub1ducPQEvDQ39U68GiofAndGbdG9azV6r78gHr1wKnKNPbMz87xtjZtcq9iwN5hjLptM9Lax4UeMWm9Xz7PP4crToj7sZnvyb3x4"}]]
+["2-QmY2v1VzkeMxF7MSfrLfZswQ74Y6FfrMR1LmuvPJQJwhi6", "2024-07-29T17:00:28Z", {"updateKeys": ["z82Lkvgj5NKYhoFh4hWzax9WicQaVDphN8MMzR3JZhontVfHaoGd9JbC4QRpDvmjQH3BLeQ"], "nextKeyHashes": ["QmcCbGzGNr2EFduauzCoh3Hwt1GkRW4Gnkk5nxbr3625de"]}, {"value": {"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1"], "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example"}}, [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc#z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc", "created": "2024-07-29T17:00:28Z", "proofPurpose": "authentication", "challenge": "2-QmY2v1VzkeMxF7MSfrLfZswQ74Y6FfrMR1LmuvPJQJwhi6", "proofValue": "z2VDUyVapPpb6rC4YbLZRLcWS2zg9o53JU97QjNQYH7JvGs5Ccnf2b647Gw96G5N8rvEKc77uQTGqYvLJ6zrqNwGnqNLraTPD2AL2rR2eUiRKnM5KhbwWumDy5eqmTumm1FWp"}]]
+
+§ Log File For Version 3
+The same process is repeated for version 3 of the DID. In this case:
+-
+
- The DIDDoc is changed, and a patch generated.
+
-
+
- an
authentication
method is added.
+ - two services are added. +
+ - an
- No changes are made to the authorized keys to update the DID. As a result, the
parameters
entry is empty ({}
), and the parameters in effect from previous versions of the DID remain in effect.
+
Here is the pretty-printed log entry:
+[
+ "3-QmNwk72WkEjUMQxqkxYoKWNx8Y1pDiGUZCn9PpeLtfPtyk",
+ "2024-07-29T17:00:28Z",
+ {},
+ {
+ "patch": [
+ {
+ "op": "add",
+ "path": "/authentication",
+ "value": [
+ "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example#z6Mkq57k27wL26zrxpvGVdEsCKe5kfpJhzy7GciVUfmosTdv"
+ ]
+ },
+ {
+ "op": "add",
+ "path": "/assertionMethod",
+ "value": [
+ "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example#z6Mkq57k27wL26zrxpvGVdEsCKe5kfpJhzy7GciVUfmosTdv"
+ ]
+ },
+ {
+ "op": "add",
+ "path": "/service",
+ "value": [
+ {
+ "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example#domain",
+ "type": "LinkedDomains",
+ "serviceEndpoint": "https://domain.example"
+ },
+ {
+ "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example#whois",
+ "type": "LinkedVerifiablePresentation",
+ "serviceEndpoint": "https://domain.example/.well-known/whois.vc"
+ }
+ ]
+ },
+ {
+ "op": "add",
+ "path": "/@context/2",
+ "value": "https://identity.foundation/.well-known/did-configuration/v1"
+ },
+ {
+ "op": "add",
+ "path": "/@context/3",
+ "value": "https://identity.foundation/linked-vp/contexts/v1"
+ }
+ ]
+ },
+ [
+ {
+ "type": "DataIntegrityProof",
+ "cryptosuite": "eddsa-jcs-2022",
+ "verificationMethod": "did:key:z82Lkvgj5NKYhoFh4hWzax9WicQaVDphN8MMzR3JZhontVfHaoGd9JbC4QRpDvmjQH3BLeQ#z82Lkvgj5NKYhoFh4hWzax9WicQaVDphN8MMzR3JZhontVfHaoGd9JbC4QRpDvmjQH3BLeQ",
+ "created": "2024-07-29T17:00:28Z",
+ "proofPurpose": "authentication",
+ "challenge": "3-QmNwk72WkEjUMQxqkxYoKWNx8Y1pDiGUZCn9PpeLtfPtyk",
+ "proofValue": "z2TBssHyJj7dB4LDGjHWm3EfHhBiu534w4ucRF95XG3KzLg4m5kjtYbupGmf4txjqQRPko8Qd8PGeHgykWdutHXxJUmvvpGuiJxNBRpfwfKxnsbrT7jWeT6GqaFYqqkDcCG35"
+ }
+ ]
+]
+
+Here is the log entry for just version 3 of the DID.
+["3-QmNwk72WkEjUMQxqkxYoKWNx8Y1pDiGUZCn9PpeLtfPtyk", "2024-07-29T17:00:28Z", {}, {"patch": [{"op": "add", "path": "/authentication", "value": ["did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example#z6Mkq57k27wL26zrxpvGVdEsCKe5kfpJhzy7GciVUfmosTdv"]}, {"op": "add", "path": "/assertionMethod", "value": ["did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example#z6Mkq57k27wL26zrxpvGVdEsCKe5kfpJhzy7GciVUfmosTdv"]}, {"op": "add", "path": "/service", "value": [{"id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example#domain", "type": "LinkedDomains", "serviceEndpoint": "https://domain.example"}, {"id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example#whois", "type": "LinkedVerifiablePresentation", "serviceEndpoint": "https://domain.example/.well-known/whois.vc"}]}, {"op": "add", "path": "/@context/2", "value": "https://identity.foundation/.well-known/did-configuration/v1"}, {"op": "add", "path": "/@context/3", "value": "https://identity.foundation/linked-vp/contexts/v1"}]}, [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z82Lkvgj5NKYhoFh4hWzax9WicQaVDphN8MMzR3JZhontVfHaoGd9JbC4QRpDvmjQH3BLeQ#z82Lkvgj5NKYhoFh4hWzax9WicQaVDphN8MMzR3JZhontVfHaoGd9JbC4QRpDvmjQH3BLeQ", "created": "2024-07-29T17:00:28Z", "proofPurpose": "authentication", "challenge": "3-QmNwk72WkEjUMQxqkxYoKWNx8Y1pDiGUZCn9PpeLtfPtyk", "proofValue": "z2TBssHyJj7dB4LDGjHWm3EfHhBiu534w4ucRF95XG3KzLg4m5kjtYbupGmf4txjqQRPko8Qd8PGeHgykWdutHXxJUmvvpGuiJxNBRpfwfKxnsbrT7jWeT6GqaFYqqkDcCG35"}]]
+
+And so on…
+§ References
++
-
+
- DID-CORE +
- + Decentralized Identifiers (DIDs) v1.0. + Manu Sporny; Amy Guy; Markus Sabadello; Drummond Reed; 2022-07-19. Status: REC. + + +
- RFC1035 +
- + Domain names - implementation and specification. + P. Mockapetris; 1987-11. Status: Internet Standard. + + +
- RFC1123 +
- + Requirements for Internet Hosts - Application and Support. + R. Braden, Ed.; 1989-10. Status: Internet Standard. + + +
- RFC2181 +
- + Clarifications to the DNS Specification. + R. Elz; R. Bush; 1997-07. Status: Proposed Standard. + + +
- RFC2234 +
- + Augmented BNF for Syntax Specifications: ABNF. + D. Crocker, Ed.; P. Overell; 1997-11. Status: Proposed Standard. + + +
- RFC3912 +
- + WHOIS Protocol Specification. + L. Daigle; 2004-09. Status: Draft Standard. + + +
- RFC3986 +
- + Uniform Resource Identifier (URI): Generic Syntax. + T. Berners-Lee; R. Fielding; L. Masinter; 2005-01. Status: Internet Standard. + + +
- RFC4033 +
- + DNS Security Introduction and Requirements. + R. Arends; R. Austein; M. Larson; D. Massey; S. Rose; 2005-03. Status: Proposed Standard. + + +
- RFC4034 +
- + Resource Records for the DNS Security Extensions. + R. Arends; R. Austein; M. Larson; D. Massey; S. Rose; 2005-03. Status: Proposed Standard. + + +
- RFC4035 +
- + Protocol Modifications for the DNS Security Extensions. + R. Arends; R. Austein; M. Larson; D. Massey; S. Rose; 2005-03. Status: Proposed Standard. + + +
- RFC5895 +
- + Mapping Characters for Internationalized Domain Names in Applications (IDNA) 2008. + P. Resnick; P. Hoffman; 2010-09. Status: Informational. + + +
- RFC6234 +
- + US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF). + D. Eastlake 3rd; T. Hansen; 2011-05. Status: Informational. + + +
- RFC6902 +
- + JavaScript Object Notation (JSON) Patch. + P. Bryan, Ed.; M. Nottingham, Ed.; 2013-04. Status: Proposed Standard. + + +
- RFC8484 +
- + DNS Queries over HTTPS (DoH). + P. Hoffman; P. McManus; 2018-10. Status: Proposed Standard. + + +
- RFC8785 +
- + JSON Canonicalization Scheme (JCS). + A. Rundgren; B. Jordan; S. Erdtman; 2020-06. Status: Informational. + + +