§ Trust DID Web - did:tdw
+Specification Status: DRAFT
+Latest Draft: +https://github.com/bcgov/trustdidweb
+-
+
- Editors: +
- Stephen Curran +
- John Jordan, BC Gov +
- Andrew Whitehead +
- Brian Richter +
- Participate: +
- GitHub repo +
- File a bug +
- Commit history +
+
§ Abstract
+The did:tdw
(Trust DID Web) method is an enhancement to the
+did:web
protocol, providing a complementary web-based DID method that addresses limitations
+of did:web
. Its features include:
-
+
- Ongoing publishing of all DID Document (DIDDoc) versions for a DID instead of,
+or alongside a
did:web
DID/DIDDoc.
+ - The same DID-to-HTTPS transformation as
did:web
.
+ - 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 that is globally +unique and derived from the initial DIDDoc which enables DID portability, such +as moving the DIDs web location (and so the DID string itself) while retaining +the DID’s history. +
- DIDDoc updates that include a proof signed by the DID Controller(s) authorized to +update the DID. +
- An optional mechanism for publishing “pre-rotation” keys to prevent loss of +control of the DID in cases where an active private key is compromised. +
- DID URL path handling that defaults (but can be overridden) to automatically
+resolve
<did>/path/to/file
by the same DID-to-HTTPS translation.
+ - A DID URL path
<did>/whois
that defaults to automatically return (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
+-
+
- DID Log +
- A log of JSON arrays each of which provides the information necessary to +generate and validate a version of the DIDDoc from the previous version. +
- 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.
+ - 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.
+ - 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 +entries. The use of parameters allows for the controlled evolution ofdid:tdw
+log handling, such as evolving the permitted hash algorithms.
+- ISO8601 +
- A date/time expressed using the ISO8601 +Standard. +
- DID Controller +
- Per the [DID-CORE], a DID controller is an entity that is authorized to +make changes to a DID document. +
- Entry Hash +
- A
did:tdw
entry hash is a hash generated using a formally defined process over +the data of a log entry. The generated entry hash is subsequently put into the +log entry and MUST be verified by a resolver.
+ - 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. +
- JSON Patch +
- [RFC6902] is a web
+standard format for describing how to change a JSON document from one state to
+another. It is used in
did:tdw
to define how a DIDDoc is changed from one +version to the next.
+ - Key Pre-Rotation +
- A technique for a controller of a cryptographic key to commit to the next public +key that it will use for a purpose, without exposing the public key. It protects +from an attacker that gains knowledger of the current private key from being +able to rotate to a new key the controller does not know. +
- DID Log Entry +
- A DID Log Entry is a JSON array of items that 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. +
- base32_lower +
- Applies [RFC4648] to convert
+data to a
base32
encoding, and then lower cases the result. Data encoded as +base32 consists of a string of characters containing only the letters A-Z and +digits 2-7.
+ - Linked-VP +
- A [DID-CORE]
service
entry that specifies where a verifiable presentation about the +DID subject can be found. The Decentralized Identity Foundation hosts the Linked VP Specification.
+ - 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 +set of VCs 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.
+ - JSON Canonicalization Scheme +
- The [RFC8785] canonicalizes a JSON +structure such that is suitable for verifiable hashing or signing. +
- 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. +
- 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
.
+ - Verifiable Conditions +
- The (proposed) verifiableConditions +Specification defines a way +to express complex conditions and additional metadata about verification +methods. It can be used to combine verification methods to form conjugated +conditions such as logical operations (like &&), thresholds, weighted +thresholds, relationships, or delegation to external verification methods. +
- 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. +
§ Overview
+The evolution of Decentralized Identifiers (DID) continues to
+be a dynamic area of development in the quest for secure and private digital
+identity management. The did:web
method, praised for its simplicity and ease
+of deployment, allows 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. Addressing these concerns, the proposed did:tdw
(Trust DID Web)
+method aims to enhance did:web
by introducing a verifiable history feature,
+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, and 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
+self-certifying identifier 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 tranformation asdid:web
, so +did:tdw
’sdid.jsonl
(JSON Lines) file is found in the same +location asdid:web
’sdid.json
file.
+- The
did.jsonl
is a list of JSON DID log entries, one per line, +whitespace removed (per JSON Lines), each of which contains the +information needed to derive a version of the DIDDoc from its preceding +version.
+ - Each entry includes six JSON entries:
+
-
+
- A hash of the entry. +
- The
versionId
of the DIDDoc, starting from 1 and incrementing.
+ - 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.
+
+ - 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 +Controller authorized to update the DIDDoc. +
+ - In generating the first version of the DIDDoc, the DID Controller calculates
+the SCID for the DID, includes it as a
parameter
in the first log +entry, and inserts it where needed in the initial (and all subsequent) +DIDDocs.
+ - A DID Controller generates and publishes the updated 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 log filedid.jsonl
, generating and verifying +each log entry as per the requirements outlined in this specification. +-
+
- In the process, the resolvers may collect all the DIDDoc versions and public +keys (by reference) used by the DID currently, or in the past. This enables +resolving both current and past DID URLs. +
+ did:tdw
DID URLs with paths and/whois
are resolved to documents +published by the DID Controller that are by default in the web location relative to the +did.jsonl
file. See the note below about the +powerful capability enabled by the/whois
DID URL path.
+- Optionally, a DID Controller can generate and publish a
did:web
DIDDoc +from the latestdid:tdw
DIDDoc by changing theid
to thedid:web
DID, +and adding analsoKnownAs
for thedid:tdw
(indicating to a resolver that +they can verify the DIDDoc, if wanted).
+
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
+Typescript implementation is less than 1000 lines of Typescript 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).
+§ 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 method specific identifier is a fully qualified domain name that is secured +by a TLS/SSL certificate with an optional path to the DID Log. The +identifier MUST contain a self-certifying identifier (SCID) as +either part of the subdomain component of the domain name, or as a component of +the optional path. The content of the SCID is +generated in creating the DID. The formal +rules describing valid domain name syntax are described in [RFC1035], +[RFC1123], and [RFC2181].
+The domain name component 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.
+The SCID, a globally unique identifier, is generated as part of the +creation of the DID and placed into the DID identifier.
+As specified in the following Augmented Backus-Naur Form (ABNF) notation
+[RFC2234] the SCID MUST be present in the DID string, but
+may be placed in the (optional) subdomain component of the domain, or as a
+segment in the (optional) URL path. 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:" *( domain-segment “.” ) scid 2*( “.” domain-segment ) *( ":" path-segment )
+tdw-did = "did:tdw:" 2*( domain-segment “.” ) *( ":" path-segment ) (":" scid ) *( ":" 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"
+scid = 28+( lower-base32 )
+lower-base32 = [2-7a-z]
+
+did:tdw
DIDs and the corresponding web locations for their did:tdw
log file.
+{SCID}
is a placeholder for where the generated SCID will be placed in the
+examples.
+
subdomain
+did:tdw:{SCID}.example.com
-->
https://{SCID}.example.com/.well-known/did.jsonl
path
+did:tdw:example.com:dids:{SCID}
-->
https://example.com/dids/{SCID}/did.jsonl
path w/ port
+did:tdw:example.com%3A3000:dids:{SCID}
-->
https://example.com:3000/dids/{SCID}/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.
§ DID Method Operations
+§ Create (Register)
+Creating a did:tdw
DID is done by carrying out the following steps.
-
+
- Define the DID string, and hence, the web location at which the DID Log
+(
did.jsonl
) will be published. Identify (using the placeholder{SCID}
) +where the required SCID will be placed in the DID string (ie. +did:tdw:example.com:{SCID}
).
+ - Create the initial DIDDoc (
did.json
) file for the DID, with whatever +content is required. Wherever there is self-reference to the DID in the +DIDDoc, use the absolute form defined in step 1, with the identified +placeholder for the SCID (ie.did:tdw:example.com:{SCID}#key-1
). +-
+
- As per Authorized Keys, the DIDDoc MUST contain at
+least one
authentication
orverificationMethod
key type.
+
+ - As per Authorized Keys, the DIDDoc MUST contain at
+least one
- Define a JSON array of valid parameters that affect the generation +of the DID. The DID Generation and Validation +Parameters section of this specification +defines the permitted parameters. +
- Pass the DID string, initial DIDDoc, and parameters to a
did:tdw
+“Create” implementation that MUST: +-
+
- Calculate the SCID for the DID as defined in the SCID Generation +and Validation section of this +specification. +
- Replace in the DIDDoc the placeholder for the SCID
{SCID}
with +the calculatedSCID
.
+ - Generate a DID Entry as a JSON array with the following five JSON items:
+
-
+
- The SCID as the
entryHash
value: +"4c99uuenu8gk6n3bgf09fuf350gx"
+ - An integer,
1
, that is the versionId for this first version of the +DIDDoc:1
+ - A string that is the current time in ISO8601 format:
+
"2024-04-04T07:32:58Z"
+ - The parameters passed in as a JSON dict:
+
{"method":"did:tdw:1","scid":"4c99uuenu8gk6n3bgf09fuf350gx"}
+ - The contents of the initial DIDDoc, in the form:
{"value": <DIDDoc>}
+
+ - The SCID as the
- Calculate the Entry Hash (
entryHash
) of the DID Entry as +defined in the Entry Hash Generation and +Validation section of this +specification.
+ - Update the
entryHash
with the value produced in the previous step.
+ - Generate a Data Integrity proof on the initial DIDDoc using an
+authorized key from the DID, and the
entryHash
as the proofchallenge
. +The definition of “authorized” in this case is specified in the +Authorized Keys section of this specification. The +proof becomes the sixth and last JSON item in the DID log entry.
+ - Put the resulting entry, with extraneous white space removed as the
+contents of a file
did.jsonl
and publish the file at the appropriate +location defined by thedid:tdw
value. +-
+
- 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 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:
-
+
- Replace
:
with/
in the method specific identifier to obtain the fully +qualified domain name and optional path.
+ - If the domain contains a port percent decode the colon. +
- Generate an HTTPS URL to the expected location of the DIDDoc by prepending
+
https://
.
+ - If no path has been specified in the URL, append
/.well-known
.
+ - Append
/did.jsonl
to complete the URL.
+ - Perform an HTTP 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 HTTP GET request, the client +SHOULD utilize [RFC8484] in order to prevent tracking of the identity +being resolved. +
- Process the DID Log file as described below. +
To process the retrieved DID Log file, the resolver MUST carry out +the following steps:
+-
+
- Process the Log entries in the order they appear in the file, applying the
+parameters set on current and previous entries. As noted in the
+Create (Register), each log entry consists of a JSON
+array of 6 items:
+
-
+
entryHash
+versionId
+versionTime
+parameters
+- DIDDoc content – either the full
value
or a JSON Patchpatch
+to be applied to the prior version of the DIDDoc.
+ - A Data Integrity proof for the current version of the DIDDoc of +the 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. +
- Verify the Data Integrity proof in the entry, and ensure it is signed by +an authorized key as defined in the Authorized Keys +section of this specification. +
- Verify the
entryHash
for the entry using the process defined in the +Entry Hash Generation and +Verification section of this +specification.
+ - Verify that the first log entry’s
versionId
is1
, and that theversionId
is incremented by one for each subsequent log entry.
+ - Verify that the
versionTime
for each log entry is greater than the previous entry, and that theversionTime
values are all earlier than the current time.
+ - For the initial version of the DIDDoc (
1
) verify that the SCID +(defined in the parameters) is being used in the DID, and +verifies according to the SCID Generation and +Verification section of this +specification.
+ - Generate the version of the DIDDoc for the 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, verify that any added keys in +the DIDDoc have a valid pre-rotation entry as defined in the Key +Pre-Rotation Hash Generation and +Verification section of +this specification. +
- Once each log entry has been processed, collect the following information
+about each version:
+
-
+
- DIDDocument +
versionId
+versionTime
+
+
+
On completing the processing of all entries in the DID Log, respond to
+the DID resolution request, including the application of query parameters such
+as ?versionId=
and ?versionTime=
with the appropriate DIDDoc version.
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 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,
+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 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:
+
-
+
- The
id
of the DIDDoc MAY be changed when the DID Controller wants to +(or must) publish the DID at a different location and wants to retain the +SCID and history of the DID. For details, see the section Moving +a DID’s Web Location.
+ - If Key Pre-Rotation is being used in the DID, only keys with a
+valid
nextKeys
entry in a previous DIDDoc can be added, as defined in +the Using Pre-Rotation Keys section of this +specification.
+
+ - The
- Define a JSON array of valid parameters that affect the evolution of
+the DID. The
did:tdw
DID Method Parameters +section of this specification defines the permitted parameters.
+ - Pass the current DID Log, the updated DIDDoc, and the parameters to a
did:tdw
update implementation which MUST: +-
+
- Generate a DID Entry as a JSON array with the following JSON items:
+
-
+
- The
entryHash
from the previous DID Log Entry as the +entryHash
value.
+ - An integer that is one more than the
versionId
of the previous DID Log Entry.
+ - A string that is the current time in ISO8601 format:
+
"2024-04-05T07:32:58Z"
+ - The parameters passed in as a JSON dict:
{}
+-
+
- parameters from previous versions continue to apply and do
+not need to be repeated in each version. As a result, the
+
parameters
item will often be an empty dict.
+
+ - parameters from previous versions continue to apply and do
+not need to be repeated in each version. As a result, the
+
- Generate a JSON Patch to evolve the previous DIDDoc version to
+the new DIDDoc version, and put the resulting patch in the item
+
{"patch": <DIDDoc Patch>}
. For details 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 Entry Hash (
entryHash
) of the DID Entry as +defined in the Entry Hash Generation and +Validation section of this +specification.
+ - Update the
entryHash
with the value produced in the previous step.
+ - Generate a Data Integrity proof on the new DIDDoc of the entry
+using an authorized key from the DID, and the
entryHash
as the proof +challenge
. The definition of “authorized” is formalized in the +Authorized Keys section of this specification. The +proof becomes the last JSON item in the entry.
+ - Append the resulting entry to the existing contents of the DID file
did.jsonl
on a new line.
+
+ - Generate a DID Entry as a JSON array with the following JSON items:
+
- Update the DID Log file at 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 removing the authentication
key type entries, preventing
+further updates to the DID/DIDDoc.
A resolver encountering in the DID log entry parameters the
+item "deactivated": true
should return in the DIDDoc Metadata the JSON item
+"deactivated": true
, as per the [DID-CORE] 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, as the 4th item, a JSON
+object that define the DID processing parameters being used by the DID when publishing that and subsequent DID Entries. A DID Resolver
+will use the same parameters when processing the DID Log to resolve the
+DID. The parameters object MUST only include items defined in this
+specification.
An example of the parameters item in the first DID Log entry for a DID:
+{"method":"did:tdw:1","scid":"4c99uuenu8gk6n3bgf09fuf350gx"}
The permitted parameter items and (where applicable) enumerated values for those +items are defined below.
+-
+
method
: Defines the version of the DID Log processing specification +to use when processing a given DID’s log file. As new versions of the +processing specifications are defined, additional values will be added to the +list of acceptable values. +-
+
- 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 version. +
- Acceptable values for this specification are:
+
-
+
did:tdw:1
: Requires that the rules defined in this specification be used +in processing the log.
+
+
+scid
: The value of the SCID for this DID. +-
+
- This item MUST appear in the first DID log entry. +
+hash
: The hashing algorithm to use when executing hashes. +-
+
- By default, the value is initialized to
sha256
.
+ - Acceptable values:
+
-
+
sha256
: Use theSHA-256
algorithm from [RFC4634].
+
+
+- By default, the value is initialized to
cryptosuite
: The Data Integrity cryptosuite to use when generating and verifying the authentication proofs on the DID log entries. +-
+
- By default, the value is initialized to
eddsa-2022
+ - Acceptable values:
+
-
+
eddsa-jcs-2022
: Use the eddsa-jcs-2022 cryptosuite.
+
+
+- By default, the value is initialized to
prerotation
: A boolean value indicating that subsequent authentication keys +added to the DIDDoc (after this version) MUST have their hash included in +anextKeys
parameter item. +-
+
- The value is initialized to
false
until the item is included in an 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
nextKeys
: An array of strings that are hashes of future keys to be added to +the DIDDoc. +-
+
- The process for generating the hashes is defined in the Pre-Rotation Key +Hash Generation and +Validation section of +this specification. +
- If the parameter
prerotation
has been set totrue
, all keys added to a +version of the DIDDoc after version 1 MUST have a corresponding hash +listed in thenextKeys
items from a previous DID log entries.
+ - See the section of this specification Using Pre-Rotation +Keys for non-normative guidance in using +pre-rotation keys. +
+deactivated
: A JSON boolean that should be set totrue
when the DID is to +be deactivated. See the deactivate (revoke) section of +this specification for more details.
+ttl
: A number, the number of seconds that a cache entry for a resolved +did:tdw
DID should last, as recommended by the DID Controller. A +resolver can use this value in deciding whether to retrieve a new version of +the DID’sdid.jsonl
file. If not specified, resolvers may set a default +based on the business needs of the resolver clients. +-
+
- Caching of 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 every call.
+ - A Web Server handling one or more
did.jsonl
files MAY be configured to +use a comparable HTTP TTL per [RFC9111].
+
+- Caching of a
§ SCID Generation and Validation
+The Self-certifying identifier or scid
is a required parameter in the
+first DID log entry and is a portion of the hash of the initial DID
+Document.
§ Generate SCID
+To generate the required SCID for a did:tdw
DID, the DID Controller
+MUST execute the following function:
left(base32_lower(hash(JCS(initial DIDDoc with placeholders))), <length>)
Where:
+-
+
- The
initial DIDDoc with placeholders
is the initial DID Doc defined by the +DID Controller with the placeholder{SCID}
put everywhere the +SCID will be used in the resolved version 1 DIDDoc. At minimum, the +{SCID}
MUST appear in the top levelid
item of the DIDDoc. It MAY +occur elsewhere in the DIDDoc.
+ JCS
is an implementation of the JSON Canonicalization Scheme +[RFC8785]. It outputs a canonicalized representation of its input.
+hash
is eithersha256
or an alternative hash algorithm defined in the +hash
item in the parameters. Its output is the hash of its input.
+base32_lower
as defined by the base32_lower function. Its output +is the lower case of the Base32 encoded string of its input.
+left
extracts the<length>
number of characters from the string input. +-
+
<length>
MUST be at least 28 characters.
+
+
§ Verify SCID
+To verify the SCID of a did:tdw
DID being resolved, the resolver
+MUST execute the following process:
-
+
- Extract from the parameters in the first DID log entry for
+the DID the
scid
item’s value.
+ - Verify that the length of the
scid
is at least 28 characters. +-
+
- If less than 28 characters, terminate the resolution process with an +error. +
+ - Extract from the first DID log entry the
value
item’s value, which +is the initial DIDDoc.
+ - Treat the
value
s value as a string and do a text replacement of thescid
+from the first step with{SCID}
. This should result in theinitial DIDDoc with placeholders
data needed for the next step.
+ - Execute the hashing process defined in the generation defined above to
+generate the value
calculatedSCID
. +-
+
- For the
<length>
value, use the length of thescid
extracted in step +1.
+
+ - For the
- Verify that the
scid
matches thecalculatedSCID
.
+
§ Entry Hash Generation and Validation
+The entryHash
is the first item in each DID log entry and is a hash
+calculate across the entry, excluding the Data Integrity proof.
§ Generate Entry Hash
+To generate the required hash for a did:tdw
DID entry, the DID Controller
+MUST execute the following process:
-
+
- Make the value of the
entryHash
for this entry to theentryHash
of the +previous entry. For the first entry in the log, set the value ofentryHash
+to the SCID for the DID.
+ - Create the full entry JSON array with elements
entryHash
,versionId
, +versionTime
, anddidDocVersion
(which is either avalue
orpatch
). +See an example below.
+ - Calculate the hash string as
base32_lower(hash(JCS(entry)))
, where: +-
+
JCS
is an implementation of the JSON Canonicalization Scheme +([RFC8785]). Its output is a canonicalized representation of its +input.
+hash
is eithersha256
or an alternative hash algorithm defined in the +hash
item in the parameters. Its output is the hash of its +input JCS content.
+base32_lower
as defined by the base32_lower function. Its +output is the lower case of the Base32 encoded string of the input hash.
+
+ - Replace the
entryHash
value in the entry with the calculated value from +step 3.
+
Example of a DID log entry that is processed in step 3 to produce a hash. As
+this is a first entry in a DID Log, the entryHash
is the SCID of the DID.
["4c99uuenu8gk6n3bgf09fuf350gx",1,"2024-04-15T19:56:18Z",{"method": "did:tdw:1","scid": "4c99uuenu8gk6n3bgf09fuf350gx"},{"value": {"@context": ["https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1"],"id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","authentication": ["did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT"],"assertionMethod": ["did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B"],"verificationMethod": [{"id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT","controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","type": "Multikey","publicKeyMultibase": "z6Mksta2t7db1WSx2JBorfYFcJnaJMBKUyupD2qPy4SDXopT"},{"id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B","controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","type": "Multikey","publicKeyMultibase": "z6Mkw1KSvGWNAwSwWbcpwPgFARX4vKPa1xvcDMsJ5b48Zj6B"}]}}]
+
+Resulting entry hash: 4fbja27mgf0bumtbg2b4hbzqc2ux9a9crrqx7w6cfnd97k9u7k5g
§ Verify Entry Hash
+To verify the entryHash
for a did:tdw
DID entry, a DID Resolver MUST
+execute the following process:
-
+
- Extract the first item in the DID log entry as the
entryHash
+ - Remove the Data Integrity proof (5th item) from the entry array. +
- Set the first value of the entry to the
entryHash
of the previous entry. If +this is the first entry in the log, set the value to the SCID for +the DID.
+ - Calculate the hash string as
base32_lower(hash(JCS(entry)))
, where: +-
+
JCS
is an implementation of the JSON Canonicalization Scheme +([RFC8785]). Its output is a canonicalized representation of its +input.
+hash
is either [sha256] or an alternative hash algorithm defined in the +hash
item in the parameters. Its output is the hash of its +input JCS content.
+base32_lower
as defined by the base32_lower function. Its +output is the lower case of the Base32 encoded string of the input hash.
+
+ - Verify that the calculated value from Step 4 matches the extracted value from +Step 1. +
§ 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.
+For did:tdw
, the following defines the process for collecting the authorized
+keys.
-
+
- Retrieve the DIDDoc in which the set of authorized controller DIDs is found.
+For the first version (
1
) of the DID, that is the first (and only) DIDDoc. +For all subsequent versions of the DID, the previous DIDDoc version is +used.
+ - From the DIDDoc, the top-level
controller
item is retrieved to create a +(possibly empty) array of controller DIDs from the DIDDoc. +-
+
- If the list of controller DIDs is empty, the DID being signed is added to +the array. +
+ - For each DID in the list, the set of
authentication
key type references are +collected from within the DIDDoc. +-
+
- If there are no
authentication
key type references, the +verificationMethod
key references are collected.
+ - If the controller DID is for an external DID, the key referenced +MUST be present in the DIDDoc being processed. +
+ - If there are no
The controller of the DID MUST use a key from the resulting key references +to sign the DID Log entry.
+A resolver of the DID MUST verify that the key used for signing the DID Log entry is in the list of authorized DID key references, and MUST +verify the proof.
+-
+
- [DID-CORE] is not clear (at least to the authors of this +specification) on what key types define those authorized to update a DID. +
- The requirement to have the key reference for external DIDs (not the
+controlled DID) copied into the DIDDoc is to prevent an implementation from
+having to resolve external DIDs (that could use any DID Method)
+during the resolution of a DID. This might be too restrictive and could be
+changed in an update to this specification. For example, it might be
+reasonable to require that external DIDs of certain DID Methods
+(such as
did:tdw
ordid:web
) be resolved as part of resolving the +controlled DID.
+ - In a future version of the specification, the authors would like to require +support for verifiableConditions key types, to enable multi-sig DID control support, such as requiring “N of M” signatures must +be in a proof for it to be valid. +
§ 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 5th item. A DID Controller MAY set the
+fourth 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 fourth item of the DID log entry to
{"patch": "<patch>"}
, +removing all extraneous whitespace from the<patch>
.
+
When processing a DID log entry with a patch
, a resolver MUST:
-
+
- Have the fully resolved previous version of the DIDDoc. +
- Execute an implementation of JSON Patch that takes the previous +DIDDoc and the patch as inputs, and outputs the resulting new version of the +DIDDoc. +
§ 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 DIDDoc from
did:tdw
.
+ - Execute a text replacement across the DIDDoc of
did:tdw
todid:web
.
+ - Add to the DIDDoc
alsoKnownAs
array, the fulldid:tdw
DID. If the +alsoKnownAs
array does not exist in the DIDDoc, it MUST be added.
+ - Publish the resulting DIDDoc as the file
did.json
at the web location +determined by the specifieddid:web
DID to HTTP transformation.
+
Note that the SCID remains in the did:web
DID string.
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.
§ Pre-Rotation Key Hash Generation and Validation
+Pre-rotation is a term defining how a DID Controller can commit to the +keys that will be added (“rotated to”) in future versions of the DIDDoc. The +purpose of committing to future keys is that if the currently active keys are +compromised by an attacker, the attacker should not be able to rotate the +compromised keys to new ones only the attacker controls to take over the control +of the DID. The effectiveness of pre-rotation is based on the idea that an +attacker cannot compromised the future keys. See the non-normative section about +Using Pre-Rotation Keys in the implementors guide +section of this specification.
+As described in the parameters
+section of this specification, a DID Controller MAY define that
+prerotation
is active for the DID. When that is the case, all additions of
+new keys in future versions of the DIDDoc MUST have their hash in one or
+more of the nextKeys
arrays of previous DID log entry parameters.
To create a hash to be included in the nextKeys array, the DID Controller +MUST execute the following process:
+-
+
- Generate a new key pair. +
- Create the JSON dict Verification +Material, defined in +[DID-CORE], for the new key. An example of such an entry is defined +below. +
- Calculate the hash string as
base32_lower(hash(JCS(<verificationMaterial>)))
, +where: +-
+
JCS
is an implementation of the JSON Canonicalization Scheme +[RFC8785]. Its output is a canonicalized representation of its +input.
+hash
is eithersha256
or an alternative hash algorithm defined in the +hash
item in the parameters. Its output is the hash of its +input JCS content.
+base32_lower
as defined by the base32_lower function. Its +output is the lower case of the Base32 encoded string of the input hash.
+
+ - Add the hash calculated in Step 3 to a DID log entry
nextKeys
item +in the parameters (4th item of the entry array).
+ - The JSON dict from Step 2 can be inserted into a future version of the +DIDDoc. +
When processing a DID log entry where the prerotation
parameter is
+active, a resolver MUST:
-
+
- When processing each DID log entry, after verifying a DIDDoc, add an
+optional array of
nextKeys
from the parameters into an array of hash +strings. +-
+
- The collection of the
nextKeys
from the current entry must occur after +the processing and verification of that entries` DIDDoc version so that a +new key and its pre-rotation hash cannot be added in the same entry.
+
+ - The collection of the
- For all DIDDoc versions after versionId 1, detect when a new key
+Verification
+Material is added to
+a version of a DIDDoc. If so, for each new key:
+
-
+
- Extract the Verification Material JSON dict for the new key from the new +DIDDoc. +
- Calculate the hash string as
+
base32_lower(hash(JCS(verificationMaterial)))
, where: +-
+
JCS
is an implementation of the JSON Canonicalization Scheme +[RFC8785]. Its output is a canonicalized representation of its +input.
+hash
is eithersha256
or an alternative hash algorithm defined in +thehash
item in the parameters. Its output is the hash of +its input JCS content.
+base32_lower
as defined by the base32_lower function. Its +output is the lower case of the Base32 encoded string of the input +hash.
+
+ - Check to see if the hash string is listed in the collected list of
+
nextKeys
. +-
+
- If so, the new key is verified. +
- If not, the verification process failed. +
+
+
§ DID URL Resolution
+The did:tdw
DID Method embraces the power and usefulness of DID URLs, along
+with the semantic simplicity of using them in 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 is found with/whois.json
appended to it. +-
+
- For example,
did:tdw:{SCID}.example.com/whois
returns the verifiable +presentation fromhttps://{SCID}.example.com/.well-known/whois.json
.
+
+ - 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 the web location relative to where the +did.jsonl
file is found. +-
+
- For example,
did:tdw:{SCID}.example.com/governance/issuers.json
returns +the filehttps://{SCID}.example.com/.well-known/governance/issuer.json
+
+ - For example,
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 interested in 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 to decide to publish a whois
+verifiable presentation, along with which verifiable credentials to put into the
+verifiable presentation.
See the The /whois
Use Case in this specification for
+the background about why this capability is so useful, particularly for a
+web-based DID Method like did:tdw
.
did:tdw
DIDs automatically supports a #whois
service endpoint with the
+following definition based on the Linked VP specification, with the
+serviceEndpoint
matching the did:tdw
DID-to-HTTPS DIDDoc transformation and
+did.jsonl
changed to whois.json
.
{
+ "@context": "https://identity.foundation/linked-vp/contexts/v1",
+ "id": "#whois",
+ "type": "LinkedVerifiablePresentation",
+ "serviceEndpoint": "https://example.com/dids/<scid>/whois.json"
+}
+
+The returned whois.json
MUST contain a W3C VCDM verifiable signed by the DID and containing verifiable credentials
+with the DID as the credentialSubject
.
A DID Controller MAY explicitly add to their DIDDoc a did:tdw
+service with the "id": "#whois"
. Such an entry MUST override the implicit
+service
above. If the DID Controller wants to publish the /whois
+verifiable presentation in a different format than the W3C format, they MUST explicitly add to their DIDDoc a service with the
+"id": "#whois"
to specify the name and implied format of the verifiable.
To resolve the DID URL <did:tdw DID>/whois
, the resolver MUST:
-
+
- Resolve the given
did:tdw
DID by retrieving, processing, and verifying the +DID log for thedid:tdw
as defined in this specification.
+ - Find the DIDDoc
service
with theid
#whois
, if any, or use the implicit +service (above).
+ - Resolve the
serviceEndpoint
URL, if possible, and return the document +found. +-
+
- If the
serviceEndpoint
URL can’t be resolved by the resolver (such as if +the URL protocol is not supported by the resolver), the errorError XXX: YYY
MUST be returned.
+ - If the file at the defined
serviceEndpoint
is not found,Error 404: Not Found
MUST be returned.
+
+ - If the
§ DID URL Path Resolution Service
+The automatic resolution of did:tdw
DID URL paths follows the
+[DID-CORE] relativeRef
specification, as follows:
-
+
- a DID path, such as example 2 in section 3.2 DID URL
+Syntax gives the example:
+
did:example:123456/resume.pdf
+ - In turn, that can be treated as the following, as shown in example 8 in the
+same section:
did:example:123456?service=files&relativeRef=/resume.pdf
+ - The
#files
service defined below then defines theserviceEndpoint
for the +relativeRef
. +-
+
- For
did:tdw
, that service is implicitly defined, with the +serviceEndpoint
matching thedid:tdw
DID-to-HTTPS DIDDoc transformation +anddid.jsonl
replaced by the DID URL Path.
+
+ - For
Thus, the implicit service for DID did:tdw:example.com:dids:<scid>
is:
{
+ "id": "#files",
+ "type": "relativeRef",
+ "serviceEndpoint": "https://example.com/dids/<scid>"
+}
+
+A DID Controller MAY explicitly add to their DIDDoc a service with
+the "id": "#files"
. Such an entry MUST override the implicit service
+defined above.
To resolve the DID URL <did:tdw DID>/path/to/file
, the resolver MUST:
-
+
- Resolve the given
did:tdw
DID by retrieving, processing, and verifying the +DID log for thedid:tdw
as defined in this specification.
+ - Find the DIDDoc
service
with theid
#files
, if any, or use the implicit +service (above).
+ - Resolve the
serviceEndpoint
URL with the DID URL Path appended, if +possible, and return the document found at that location. +-
+
- If the
serviceEndpoint
URL can’t be resolved by the resolver (such as if +the URL protocol is not supported by the resolver), the errorError XXX: YYY
MUST be returned.
+ - If the file at the path appended to the defined
serviceEndpoint
is not +found, the errorError 404: Not Found
MUST be returned.
+
+ - If the
§ Security and Privacy Considerations
+§ DNS Considerations
+§ DNS Security Considerations
+Implementers must secure DNS resolution to protect against attacks like Man in +the Middle, following the detailed guidance in the did:web +specification. +The use of DNSSEC [RFC4033], [RFC4034], [RFC4035] is +essential to prevent spoofing and ensure authenticity of DNS records.
+§ DNS Privacy Considerations
+Resolving a did:tdw
identifier can expose users to tracking by DNS providers
+and web servers. To mitigate this risk, it’s recommended to use privacy-enhancing
+technologies such as VPNs, TOR, or trusted universal resolver services, in line
+with strategies outlined in the did:web
+specification
+including emerging RFCs such as Oblivious DNS over
+HTTPS
+for DNS privacy.
§ In-transit Security
+For in-transit security, the guidance provided in the did:web +specification +regarding the encryption of traffic between the server and client should be +followed.
+§ International Domain Names
+[DID-CORE] identifier syntax does not allow Unicode in method name nor +method specific identifiers.
+Implementers should be cautious when implementing support for DID URLs that rely +on domain names or path components that contain Unicode characters.
+See also:
+ +§ Implementors Guide
+§ Implementations
+Proof of concept implementations of did:tdw
software for DID Controllers and resolvers can be found here:
-
+
- Typescript: https://github.com/bcgov/trustdidweb-ts +
- Python: To be added +
Both currently (as of 2024.04.11) support all of the features of did:tdw
except for Key Pre-Rotation and Verifiable Conditions.
The Typescript implementation is currently less than 1000 lines of Typescript code.
+§ Using Pre-Rotation Keys
+Best practices are that the DID Controller generates the active key for the DIDDoc where it can be used for “production” purposes, and generates the “next key” in an isolated location from production
+Complete this section, covering guidance on where to hold pre-rotation keys and post-quantum key rotations.
+§ Moving a DID’s Web Location
+Complete this section
+§ 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.
In the following, all of the data for the DID log entries are displayed
+as prettified JSON for readability. In the log itself, the JSON has all
+whitespace removed, and each line ends with a CR
.
§ DID Creation Data
+These examples show the important structures used in the Create (Register) operation for a did:tdw
DID.
§ DIDDoc with SCID Placeholders
+This is the version of the DIDDoc that the DID Controller constructs +(however they see fit) and passes into the SCID Generation Process.
+{
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1"
+ ],
+ "id": "did:tdw:example.com:{SCID}",
+ "controller": "did:tdw:example.com:{SCID}",
+ "authentication": [
+ "did:tdw:example.com:{SCID}#y4SDXopT"
+ ],
+ "assertionMethod": [
+ "did:tdw:example.com:{SCID}#5b48Zj6B"
+ ],
+ "verificationMethod": [
+ {
+ "id": "did:tdw:example.com:{SCID}#y4SDXopT",
+ "controller": "did:tdw:example.com:{SCID}",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mksta2t7db1WSx2JBorfYFcJnaJMBKUyupD2qPy4SDXopT"
+ },
+ {
+ "id": "did:tdw:example.com:{SCID}#5b48Zj6B",
+ "controller": "did:tdw:example.com:{SCID}",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mkw1KSvGWNAwSwWbcpwPgFARX4vKPa1xvcDMsJ5b48Zj6B"
+ }
+ ]
+}
+
+§ DIDDoc with SCID In Place
+After the SCID is generated, the {SCID}
placeholders are replaced by the generated SCID value.
{
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1"
+ ],
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "authentication": [
+ "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT"
+ ],
+ "assertionMethod": [
+ "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B"
+ ],
+ "verificationMethod": [
+ {
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT",
+ "controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mksta2t7db1WSx2JBorfYFcJnaJMBKUyupD2qPy4SDXopT"
+ },
+ {
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B",
+ "controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mkw1KSvGWNAwSwWbcpwPgFARX4vKPa1xvcDMsJ5b48Zj6B"
+ }
+ ]
+}
+
+§ Entry Hash Generation Input
+The first item in the entry hashing input for Version 1 of the DIDDoc is SCID of
+the DID. The fifth item, containing the first version DIDDoc content is the full
+DIDDoc (as indicated by the value
item).
[
+ "4c99uuenu8gk6n3bgf09fuf350gx",
+ 1,
+ "2024-04-15T19:56:18Z",
+ {
+ "method": "did:tdw:1",
+ "scid": "4c99uuenu8gk6n3bgf09fuf350gx"
+ },
+ {
+ "value": {
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1"
+ ],
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "authentication": [
+ "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT"
+ ],
+ "assertionMethod": [
+ "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B"
+ ],
+ "verificationMethod": [
+ {
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT",
+ "controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mksta2t7db1WSx2JBorfYFcJnaJMBKUyupD2qPy4SDXopT"
+ },
+ {
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B",
+ "controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mkw1KSvGWNAwSwWbcpwPgFARX4vKPa1xvcDMsJ5b48Zj6B"
+ }
+ ]
+ }
+ }
+]
+
+§ First Log Entry
+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.
[
+ "4fbja27mgf0bumtbg2b4hbzqc2ux9a9crrqx7w6cfnd97k9u7k5g",
+ 1,
+ "2024-04-15T19:56:18Z",
+ {
+ "method": "did:tdw:1",
+ "scid": "4c99uuenu8gk6n3bgf09fuf350gx"
+ },
+ {
+ "value": {
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1"
+ ],
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "authentication": [
+ "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT"
+ ],
+ "assertionMethod": [
+ "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B"
+ ],
+ "verificationMethod": [
+ {
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT",
+ "controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mksta2t7db1WSx2JBorfYFcJnaJMBKUyupD2qPy4SDXopT"
+ },
+ {
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B",
+ "controller": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mkw1KSvGWNAwSwWbcpwPgFARX4vKPa1xvcDMsJ5b48Zj6B"
+ }
+ ]
+ }
+ },
+ [
+ {
+ "type": "DataIntegrityProof",
+ "cryptosuite": "eddsa-jcs-2022",
+ "verificationMethod": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT",
+ "created": "2024-04-15T19:56:18Z",
+ "proofPurpose": "authentication",
+ "challenge": "4fbja27mgf0bumtbg2b4hbzqc2ux9a9crrqx7w6cfnd97k9u7k5g",
+ "proofValue": "z4vP3KptRsxFcjpatqHNpywvwV5AfmAYhkHsMbF8K1gKqRA7WZuoyLheF9tabMu2HCXPnvNEKijfMqpRqkfKZRAHi"
+ }
+ ]
+]
+
+The same content as it is found in the did.jsonl
file:
["4fbja27mgf0bumtbg2b4hbzqc2ux9a9crrqx7w6cfnd97k9u7k5g",1,"2024-04-15T19:56:18Z",{"method":"did:tdw:1","scid":"4c99uuenu8gk6n3bgf09fuf350gx"},{"value":{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1"],"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","controller":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","authentication":["did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT"],"assertionMethod":["did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B"],"verificationMethod":[{"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT","controller":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","type":"Multikey","publicKeyMultibase":"z6Mksta2t7db1WSx2JBorfYFcJnaJMBKUyupD2qPy4SDXopT"},{"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B","controller":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","type":"Multikey","publicKeyMultibase":"z6Mkw1KSvGWNAwSwWbcpwPgFARX4vKPa1xvcDMsJ5b48Zj6B"}]}},[{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT","created":"2024-04-15T19:56:18Z","proofPurpose":"authentication","challenge":"4fbja27mgf0bumtbg2b4hbzqc2ux9a9crrqx7w6cfnd97k9u7k5g","proofValue":"z4vP3KptRsxFcjpatqHNpywvwV5AfmAYhkHsMbF8K1gKqRA7WZuoyLheF9tabMu2HCXPnvNEKijfMqpRqkfKZRAHi"}]]
+
+§ did:web
Version of DIDDoc
+As noted in the publishing a parallel did:web
+DID section of this specification, 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:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "controller": "did:web:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "alsoKnownAs": ["did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx"],
+ "authentication": [
+ "did:web:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT"
+ ],
+ "assertionMethod": [
+ "did:web:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B"
+ ],
+ "verificationMethod": [
+ {
+ "id": "did:web:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT",
+ "controller": "did:web:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mksta2t7db1WSx2JBorfYFcJnaJMBKUyupD2qPy4SDXopT"
+ },
+ {
+ "id": "did:web:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B",
+ "controller": "did:web:example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mkw1KSvGWNAwSwWbcpwPgFARX4vKPa1xvcDMsJ5b48Zj6B"
+ }
+ ]
+}
+
+§ 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.
§ Target Version 2 DIDDoc
+The DID Controller constructs the new target DIDDoc (below) in
+preparation for passing it into the process to Update the did:tdw
+DID.
{
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1",
+ "https://identity.foundation/linked-vp/contexts/v1"
+ ],
+ "id": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "controller": [
+ "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"
+ ],
+ "authentication": [
+ "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CpsUrTh3"
+ ],
+ "assertionMethod": [
+ "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#gJqvqaYD"
+ ],
+ "verificationMethod": [
+ {
+ "id": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CpsUrTh3",
+ "controller": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6MkuocstfAaHsJgRnQgfQdtJiECuWEMDAbQV61aCpsUrTh3"
+ },
+ {
+ "id": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#gJqvqaYD",
+ "controller": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6MksNvDtgMutKMzjezRqj8JbYuCHNjHR5HBaF2ogJqvqaYD"
+ }
+ ],
+ "service": [
+ {
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#whois",
+ "type": "LinkedVerifiablePresentation",
+ "serviceEndpoint": [
+ "https://example.com/docs/4c99uuenu8gk6n3bgf09fuf350gx/whois.json"
+ ]
+ }
+ ]
+}
+
+§ Version 2 Entry Hashing Input
+The first item in the entry hashing input for Version 2 of the DIDDoc is the
+entry hash generated for the Version 1 of the DIDDoc. The fifth item, containing the new
+version DIDDoc content is in the form of a [RFC6902] JSON Patch (as
+indicated by the patch
item), and are the set of operations to transition the
+DIDDoc from version 1 to this new version 2 DIDDoc.
[
+ "53vtcxfvmvwfzyfw4b9cjeygccwbhm8j1v90by5k66jt4ahbhu50",
+ 2,
+ "2024-04-15T19:56:18Z",
+ {},
+ {
+ "patch": [
+ {
+ "op": "replace",
+ "path": "/verificationMethod/1/publicKeyMultibase",
+ "value": "z6MksNvDtgMutKMzjezRqj8JbYuCHNjHR5HBaF2ogJqvqaYD"
+ },
+ {
+ "op": "replace",
+ "path": "/verificationMethod/1/controller",
+ "value": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"
+ },
+ {
+ "op": "replace",
+ "path": "/verificationMethod/1/id",
+ "value": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#gJqvqaYD"
+ },
+ {
+ "op": "replace",
+ "path": "/verificationMethod/0/publicKeyMultibase",
+ "value": "z6MkuocstfAaHsJgRnQgfQdtJiECuWEMDAbQV61aCpsUrTh3"
+ },
+ {
+ "op": "replace",
+ "path": "/verificationMethod/0/controller",
+ "value": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"
+ },
+ {
+ "op": "replace",
+ "path": "/verificationMethod/0/id",
+ "value": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CpsUrTh3"
+ },
+ {
+ "op": "replace",
+ "path": "/assertionMethod/0",
+ "value": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#gJqvqaYD"
+ },
+ {
+ "op": "replace",
+ "path": "/authentication/0",
+ "value": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CpsUrTh3"
+ },
+ {
+ "op": "replace",
+ "path": "/controller",
+ "value": [
+ "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"
+ ]
+ },
+ {
+ "op": "replace",
+ "path": "/id",
+ "value": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"
+ },
+ {
+ "op": "add",
+ "path": "/@context/2",
+ "value": "https://identity.foundation/linked-vp/contexts/v1"
+ },
+ {
+ "op": "add",
+ "path": "/service",
+ "value": [
+ {
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#whois",
+ "type": "LinkedVerifiablePresentation",
+ "serviceEndpoint": [
+ "https://example.com/docs/4c99uuenu8gk6n3bgf09fuf350gx/whois.json"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+]
+
+§ Log File For Version 2
+The new version 2 did.jsonl
file contains two entries, one for each version
+of the DIDDoc. The data integrity proof on the version 2 entry MUST be from
+an authentication
key from the version 1 DIDDoc.
["4fbja27mgf0bumtbg2b4hbzqc2ux9a9crrqx7w6cfnd97k9u7k5g",1,"2024-04-15T19:56:18Z",{"method":"did:tdw:1","scid":"4c99uuenu8gk6n3bgf09fuf350gx"},{"value":{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1"],"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","controller":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","authentication":["did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT"],"assertionMethod":["did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B"],"verificationMethod":[{"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT","controller":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","type":"Multikey","publicKeyMultibase":"z6Mksta2t7db1WSx2JBorfYFcJnaJMBKUyupD2qPy4SDXopT"},{"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B","controller":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","type":"Multikey","publicKeyMultibase":"z6Mkw1KSvGWNAwSwWbcpwPgFARX4vKPa1xvcDMsJ5b48Zj6B"}]}},[{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT","created":"2024-04-15T19:56:18Z","proofPurpose":"authentication","challenge":"4fbja27mgf0bumtbg2b4hbzqc2ux9a9crrqx7w6cfnd97k9u7k5g","proofValue":"z4vP3KptRsxFcjpatqHNpywvwV5AfmAYhkHsMbF8K1gKqRA7WZuoyLheF9tabMu2HCXPnvNEKijfMqpRqkfKZRAHi"}]]
+["53vtcxfvmvwfzyfw4b9cjeygccwbhm8j1v90by5k66jt4ahbhu50",2,"2024-04-15T19:56:18Z",{},{"patch":[{"op":"replace","path":"/verificationMethod/1/publicKeyMultibase","value":"z6MksNvDtgMutKMzjezRqj8JbYuCHNjHR5HBaF2ogJqvqaYD"},{"op":"replace","path":"/verificationMethod/1/controller","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"},{"op":"replace","path":"/verificationMethod/1/id","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#gJqvqaYD"},{"op":"replace","path":"/verificationMethod/0/publicKeyMultibase","value":"z6MkuocstfAaHsJgRnQgfQdtJiECuWEMDAbQV61aCpsUrTh3"},{"op":"replace","path":"/verificationMethod/0/controller","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"},{"op":"replace","path":"/verificationMethod/0/id","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CpsUrTh3"},{"op":"replace","path":"/assertionMethod/0","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#gJqvqaYD"},{"op":"replace","path":"/authentication/0","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CpsUrTh3"},{"op":"replace","path":"/controller","value":["did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"]},{"op":"replace","path":"/id","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"},{"op":"add","path":"/@context/2","value":"https://identity.foundation/linked-vp/contexts/v1"},{"op":"add","path":"/service","value":[{"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#whois","type":"LinkedVerifiablePresentation","serviceEndpoint":["https://example.com/docs/4c99uuenu8gk6n3bgf09fuf350gx/whois.json"]}]}]},[{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT","created":"2024-04-15T19:56:18Z","proofPurpose":"authentication","challenge":"53vtcxfvmvwfzyfw4b9cjeygccwbhm8j1v90by5k66jt4ahbhu50","proofValue":"z47viJruDDnAfpL6Zo3bowUB9Eumx1w7Qa8UwH6K1Df1Db6pExBMRvzdy9YgL452t3v5FmrKAnDGF7aQYgtG7bbga"}]]
+
+§ Version 3
+§ Version 3 Target DIDDoc
+Here is the target update for the version 3 DIDDoc, as constructed by the DID Controller. It is the data used as input to the did:tdw
log entry generation process.
{
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ "https://w3id.org/security/multikey/v1",
+ "https://identity.foundation/linked-vp/contexts/v1",
+ "https://didcomm.org/messaging/v2"
+ ],
+ "id": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "controller": [
+ "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"
+ ],
+ "authentication": [
+ "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CZSeAWLE"
+ ],
+ "assertionMethod": [
+ "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#9vYyiXiJ"
+ ],
+ "keyAgreement": [
+ "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#qnYZ6fWH"
+ ],
+ "verificationMethod": [
+ {
+ "id": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CZSeAWLE",
+ "controller": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mkq7Qoa2LCvLCUiq9W2J9vXH1ooDqSX2ehWGUzCZSeAWLE"
+ },
+ {
+ "id": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#9vYyiXiJ",
+ "controller": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6Mkr2D4ixckmQx8tAVvXEhMuaMhzahxe61qJt7G9vYyiXiJ"
+ },
+ {
+ "id": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#qnYZ6fWH",
+ "controller": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx",
+ "type": "Multikey",
+ "publicKeyMultibase": "z6LSdYjdAE7ZY1Gh5VPAxDJdgbg45Lq6im3N9o6HqnYZ6fWH"
+ }
+ ],
+ "service": [
+ {
+ "id": "did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#whois",
+ "type": "LinkedVerifiablePresentation",
+ "serviceEndpoint": [
+ "https://example.com/docs/4c99uuenu8gk6n3bgf09fuf350gx/whois.json"
+ ]
+ },
+ {
+ "id": "did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#didcomm",
+ "type": "DIDCommMessaging",
+ "serviceEndpoint": {
+ "uri": "https://example.com/didcomm",
+ "accept": [
+ "didcomm/v2",
+ "didcomm/aip2;env=rfc587"
+ ],
+ "routingKeys": [
+ "did:example:somemediator#somekey"
+ ]
+ }
+ }
+ ]
+}
+
+§ Log File For Version 3
+The new version 3 did.jsonl
file contains three entries, one for each version
+of the DIDDoc. The data integrity proof on the version 3 entry MUST be from
+an authentication
key from the version 2 DIDDoc.
["4fbja27mgf0bumtbg2b4hbzqc2ux9a9crrqx7w6cfnd97k9u7k5g",1,"2024-04-15T19:56:18Z",{"method":"did:tdw:1","scid":"4c99uuenu8gk6n3bgf09fuf350gx"},{"value":{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1"],"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","controller":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","authentication":["did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT"],"assertionMethod":["did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B"],"verificationMethod":[{"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT","controller":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","type":"Multikey","publicKeyMultibase":"z6Mksta2t7db1WSx2JBorfYFcJnaJMBKUyupD2qPy4SDXopT"},{"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#5b48Zj6B","controller":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx","type":"Multikey","publicKeyMultibase":"z6Mkw1KSvGWNAwSwWbcpwPgFARX4vKPa1xvcDMsJ5b48Zj6B"}]}},[{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT","created":"2024-04-15T19:56:18Z","proofPurpose":"authentication","challenge":"4fbja27mgf0bumtbg2b4hbzqc2ux9a9crrqx7w6cfnd97k9u7k5g","proofValue":"z4vP3KptRsxFcjpatqHNpywvwV5AfmAYhkHsMbF8K1gKqRA7WZuoyLheF9tabMu2HCXPnvNEKijfMqpRqkfKZRAHi"}]]
+["53vtcxfvmvwfzyfw4b9cjeygccwbhm8j1v90by5k66jt4ahbhu50",2,"2024-04-15T19:56:18Z",{},{"patch":[{"op":"replace","path":"/verificationMethod/1/publicKeyMultibase","value":"z6MksNvDtgMutKMzjezRqj8JbYuCHNjHR5HBaF2ogJqvqaYD"},{"op":"replace","path":"/verificationMethod/1/controller","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"},{"op":"replace","path":"/verificationMethod/1/id","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#gJqvqaYD"},{"op":"replace","path":"/verificationMethod/0/publicKeyMultibase","value":"z6MkuocstfAaHsJgRnQgfQdtJiECuWEMDAbQV61aCpsUrTh3"},{"op":"replace","path":"/verificationMethod/0/controller","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"},{"op":"replace","path":"/verificationMethod/0/id","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CpsUrTh3"},{"op":"replace","path":"/assertionMethod/0","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#gJqvqaYD"},{"op":"replace","path":"/authentication/0","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CpsUrTh3"},{"op":"replace","path":"/controller","value":["did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"]},{"op":"replace","path":"/id","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx"},{"op":"add","path":"/@context/2","value":"https://identity.foundation/linked-vp/contexts/v1"},{"op":"add","path":"/service","value":[{"id":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#whois","type":"LinkedVerifiablePresentation","serviceEndpoint":["https://example.com/docs/4c99uuenu8gk6n3bgf09fuf350gx/whois.json"]}]}]},[{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:tdw:example.com:4c99uuenu8gk6n3bgf09fuf350gx#y4SDXopT","created":"2024-04-15T19:56:18Z","proofPurpose":"authentication","challenge":"53vtcxfvmvwfzyfw4b9cjeygccwbhm8j1v90by5k66jt4ahbhu50","proofValue":"z47viJruDDnAfpL6Zo3bowUB9Eumx1w7Qa8UwH6K1Df1Db6pExBMRvzdy9YgL452t3v5FmrKAnDGF7aQYgtG7bbga"}]]
+["3nxcvupjdbetntt80ggnbxurkrz9bhh93nqega3ek5ex8xpfurb0",3,"2024-04-15T19:56:18Z",{},{"patch":[{"op":"add","path":"/service/1","value":{"id":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#didcomm","type":"DIDCommMessaging","serviceEndpoint":{"uri":"https://example.com/didcomm","accept":["didcomm/v2","didcomm/aip2;env=rfc587"],"routingKeys":["did:example:somemediator#somekey"]}}},{"op":"replace","path":"/verificationMethod/1/publicKeyMultibase","value":"z6Mkr2D4ixckmQx8tAVvXEhMuaMhzahxe61qJt7G9vYyiXiJ"},{"op":"replace","path":"/verificationMethod/1/id","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#9vYyiXiJ"},{"op":"replace","path":"/verificationMethod/0/publicKeyMultibase","value":"z6Mkq7Qoa2LCvLCUiq9W2J9vXH1ooDqSX2ehWGUzCZSeAWLE"},{"op":"replace","path":"/verificationMethod/0/id","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CZSeAWLE"},{"op":"add","path":"/verificationMethod/2","value":{"id":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#qnYZ6fWH","controller":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx","type":"Multikey","publicKeyMultibase":"z6LSdYjdAE7ZY1Gh5VPAxDJdgbg45Lq6im3N9o6HqnYZ6fWH"}},{"op":"replace","path":"/assertionMethod/0","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#9vYyiXiJ"},{"op":"replace","path":"/authentication/0","value":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CZSeAWLE"},{"op":"add","path":"/@context/3","value":"https://didcomm.org/messaging/v2"},{"op":"add","path":"/keyAgreement","value":["did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#qnYZ6fWH"]}]},[{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:tdw:migrated.example.com:4c99uuenu8gk6n3bgf09fuf350gx#CpsUrTh3","created":"2024-04-15T19:56:18Z","proofPurpose":"authentication","challenge":"3nxcvupjdbetntt80ggnbxurkrz9bhh93nqega3ek5ex8xpfurb0","proofValue":"zedM9gUK9KvMLEXLePemFB2W5jBtscHN9WRPcxmkuRanPHsvK76M1mKHUKqJtApcdSsykRZtoHPJLiagJo3KKJsU"}]]
+
+And so on…
+§ References
++
-
+
- DID-CORE +
- + Decentralized Identifiers (DIDs) v1.0. + Manu Sporny; Amy Guy; Markus Sabadello; Drummond Reed; 2022-07-19. Status: REC. + + +
- RFC1035 +
- + Domain names - implementation and specification. + P. Mockapetris; 1987-11. Status: Internet Standard. + + +
- RFC1123 +
- + Requirements for Internet Hosts - Application and Support. + R. Braden, Ed.; 1989-10. Status: Internet Standard. + + +
- RFC2181 +
- + Clarifications to the DNS Specification. + R. Elz; R. Bush; 1997-07. Status: Proposed Standard. + + +
- RFC2234 +
- + Augmented BNF for Syntax Specifications: ABNF. + D. Crocker, Ed.; P. Overell; 1997-11. Status: Proposed Standard. + + +
- RFC3912 +
- + WHOIS Protocol Specification. + L. Daigle; 2004-09. Status: Draft Standard. + + +
- RFC3986 +
- + Uniform Resource Identifier (URI): Generic Syntax. + T. Berners-Lee; R. Fielding; L. Masinter; 2005-01. Status: Internet Standard. + + +
- RFC4033 +
- + DNS Security Introduction and Requirements. + R. Arends; R. Austein; M. Larson; D. Massey; S. Rose; 2005-03. Status: Proposed Standard. + + +
- RFC4034 +
- + Resource Records for the DNS Security Extensions. + R. Arends; R. Austein; M. Larson; D. Massey; S. Rose; 2005-03. Status: Proposed Standard. + + +
- RFC4035 +
- + Protocol Modifications for the DNS Security Extensions. + R. Arends; R. Austein; M. Larson; D. Massey; S. Rose; 2005-03. Status: Proposed Standard. + + +
- RFC4634 +
- + US Secure Hash Algorithms (SHA and HMAC-SHA). + D. Eastlake 3rd; T. Hansen; 2006-07. Status: Informational. + + +
- RFC4648 +
- + The Base16, Base32, and Base64 Data Encodings. + S. Josefsson; 2006-10. Status: Proposed Standard. + + +
- RFC5895 +
- + Mapping Characters for Internationalized Domain Names in Applications (IDNA) 2008. + P. Resnick; P. Hoffman; 2010-09. 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. + + +