§ Trust DID Web - did:tdw
- v0.3
Specification Status: HISTORICAL – THIS IS NOT THE CURRENT VERSION OF THE SPECIFICATION
Specification Version: 0.3 (see Changelog)
Latest Version:
- Specification: https://identity.foundation/trustdidweb/
- Repository: 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
, sodid: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 thedid.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 at1
and incrementing by one per DID version), a literal dash-
, and theentryHash
, 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 thedid: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. TheversionTime
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 asupdateKeys
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 thenextKeyHashes
list in the parameters. - All other
did:tdw
processing configuration settings as defined by in theparameters
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 proofchallenge
. 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 theupdateKeys
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 recentwitnesses
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 resolveddid: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 thedid: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 themethod
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 thedid: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 entryentryHash
. - 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 themethod
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 thedid: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 witnessesid
: the DID of the witnessweight
: 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>:
todid:web:
, where<scid>
is the actualdid:tdw
SCID. - Add to the DIDDoc
alsoKnownAs
array, the fulldid:tdw
DID. If thealsoKnownAs
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, resolvingdid:tdw:{SCID}.example.com/governance/issuers.json
returns the filehttps://{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 therelativeRef
.- For
did:tdw
, that service is implicitly defined, with theserviceEndpoint
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:
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 theupdateKeys
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 theentryHash
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.
- MULTIFORMATS
- Multiformats. Juan Benet; Manu Sporny; 2024-02-21. Status: Internet Draft.
- 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.
- RFC6125
- Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS). P. Saint-Andre; J. Hodges; 2011-03. Status: Proposed Standard.
- 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.
- RFC9525
- Service Identity in TLS. P. Saint-Andre; R. Salz; 2023-11. Status: Proposed Standard.
§ did:tdw
Version Changelog
The following lists the substantive changes in each version of the specification.
- Version 0.3
- Removes the
cryptosuite
parameter, moving it to implied based on themethod
parameter. - Change base32 encoding with base58btc, as it offers a better expansion rate.
- Remove the step to extract part of the base58btc result during the generation of the SCID.
- Use multihash in the SCID to differentiate the different hash function outputs.
- Removes the
- Version 0.2
- Changes the location of the SCID in the DID to always be the first
component after the DID Method prefix –
did:tdw:<scid>:...
. - Adds the parameter
portable
to enable the capability to move adid:tdw
during the creation of the DID. - Removes the first two Log Entry items
entryHash
andversionId
and replacing them with the newversionId
as the first item in each log. The new versionId takes the form<version number>-<entryHash>
, where<version number>
is the incrementing integer of version of the entry: 1, 2, 3, etc. - The
<did>/whois
media type is changed toapplication/vp
and the file is changed towhois.vp
to match the IANA registration of a Verifiable.
- Changes the location of the SCID in the DID to always be the first
component after the DID Method prefix –