From 83876cc1547cf83f43184d320d82f74539466dd3 Mon Sep 17 00:00:00 2001 From: Stephen Curran Date: Tue, 24 Sep 2024 15:02:08 -0700 Subject: [PATCH 1/7] Update ver. 0.4 to the specification Signed-off-by: Stephen Curran --- spec/abstract.md | 2 +- spec/definitions.md | 30 ++-- spec/example.md | 4 + spec/header.md | 2 +- spec/implementors_guide.md | 19 +- spec/overview.md | 40 ++--- spec/specification.md | 346 +++++++++++++++++-------------------- spec/version.md | 8 + 8 files changed, 209 insertions(+), 242 deletions(-) diff --git a/spec/abstract.md b/spec/abstract.md index bbfbc27..45d05fb 100644 --- a/spec/abstract.md +++ b/spec/abstract.md @@ -1,7 +1,7 @@ ## 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 +providing complementary features that address `did:web`'s limitations. `did:tdw` features include: - Ongoing publishing of all DID Document ([[ref: DIDDoc]]) versions for a DID instead of, diff --git a/spec/definitions.md b/spec/definitions.md index 0fe219f..80f7f63 100644 --- a/spec/definitions.md +++ b/spec/definitions.md @@ -35,7 +35,7 @@ including new versions of the [[ref: DIDDoc]] or changed information necessary t [[def: DID Log Entry, DID Log Entries, Entries, Log Entries]] -~ A DID Log Entry is a JSON array of five items which define the authorized +~ A DID Log Entry is a JSON object that defines the authorized transformation of a [[ref: DIDDoc]] from one version to the next. The initial entry establishes the DID and version 1 of the [[ref: DIDDoc]]. All entries are stored in the [[ref: DID Log]]. @@ -49,7 +49,7 @@ the DID Method Specification for `DID:tdw`. [[def: DID Portability, DID:tdw portability, `DID:tdw` portability]] -~ `did:tdw` [[ref: portability]] encompasses the ability to change the DID string for the +~ `did:tdw` portability is the capability to change the DID string for the DID while retaining the [[ref: 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 @@ -76,11 +76,12 @@ the cryptosuite can be found in the specification, here: [[def: Entry Hash, entryHash]] ~ A `DID:tdw` entry hash is a hash generated using a formally defined process -over the input data to a [[ref: log entry]], excluding the [[ref: 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 [[ref: entry hash]] is subsequently included in the `versionId` element of the [[ref: log entry]] and **MUST** be -verified by a resolver. +over the input data to a [[ref: log entry]], excluding the [[ref: Data Integrity]] +proof. The input data includes content from the predecessor to the +version of the DID, ensuring that all the versions are "chained" together in a +sort of microledger. The generated [[ref: entry hash]] is subsequently included in the +`versionId` of the [[ref: log entry]] and **MUST** be verified by a +resolver. [[def: ISO8601, ISO8601 String]] @@ -99,12 +100,6 @@ structure such that is suitable for verifiable hashing or signing. whitespace removed and separated by a newline that is convenient for handling streaming JSON data or log files. -[[def: JSON Patch]] - -~ [[spec:rfc6902]] is a web standard format for describing how to change a JSON -document from one state to another. A [[ref: DID Controller]] **MAY** use it in `DID:tdw` -to define how a [[ref: DIDDoc]] is changed from one version to the next. - [[def: Pre-Rotation]] ~ A technique for a controller of a cryptographic key to commit to the public @@ -139,10 +134,11 @@ multi-signature is considered valid. [[def: parameters]] -~ `DID:tdw` [[ref: parameters]] are a defined set of configurations that control how the -issuer has generated the DID, and how the resolver should process the DID [[ref: Log -entries]]. The use of [[ref: parameters]] allows for the controlled evolution of `DID:tdw` -log handling, such as evolving the permitted hash algorithms. +~ `did:tdw` parameters are a defined set of configurations that control how the +issuer has generated the DID, and how the resolver must process the DID [[ref: +Log entries]]. The use of parameters allows for the controlled evolution of +`did:tdw` log handling, such as evolving the set of permitted hash algorithms or +cryptosuites. This enables support for very long lasting identifiers -- decades. [[def: self-certifying identifier, SCID, SCIDs]] diff --git a/spec/example.md b/spec/example.md index db6c913..47a6ea8 100644 --- a/spec/example.md +++ b/spec/example.md @@ -1,5 +1,9 @@ ## `did:tdw` Example +**THE EXAMPLES IN THIS CHAPTER ARE OUT OF DATE, PENDING AN IMPLEMENTATION OF VER. O.4 OF THE SPECIFICATION.** + +**See the [Change Log](#didtdw-version-changelog) for what has changed between these ver. 0.3 examples, and the ver. 0.4 specification.** + The following shows the evolution of a `did:tdw` from inception through several versions, showing the DID, [[ref: DIDDoc]], [[ref: DID Log]], and some of the intermediate data structures. diff --git a/spec/header.md b/spec/header.md index a4c4744..2386abb 100644 --- a/spec/header.md +++ b/spec/header.md @@ -3,7 +3,7 @@ Trust DID Web - `did:tdw` **Specification Status:** DRAFT -**Specification Version:** 0.3 (see [Changelog](#did-tdw-version-changelog)) +**Specification Version:** 0.4 (see [Changelog](#did-tdw-version-changelog)) **Latest Draft:** [https://github.com/decentralized-identity/trustdidweb](https://github.com/decentralized-identity/trustdidweb) diff --git a/spec/implementors_guide.md b/spec/implementors_guide.md index e213f4e..32cd518 100644 --- a/spec/implementors_guide.md +++ b/spec/implementors_guide.md @@ -8,15 +8,15 @@ Proof of concept implementations of `did:tdw` software for [[ref: DID Controller - [Python] - [Go] -Both currently (as of 2024.04.11) support all of the features of the core `did:tdw` including [[ref: Key Pre-Rotation]]. Not yet supported is the the concept of [[ref: witnesses]]. +The implementations support all of the features of the core `did:tdw` including [[ref: Key Pre-Rotation]], except support for [[ref: 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, [[ref: pre-rotation]] keys are introduced. These commitments, made by the [[ref: DID Controller]], are -declarations about the keys that will be published in future versions of the DID -document, without revealing the keys themselves. +declarations about the authorization keys that will be published in future +versions of the DID log, without revealing the keys themselves. The primary goal of [[ref: 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 @@ -25,18 +25,18 @@ a key they generate and control. Rather, they would need to have also compromised the unpublished (and presumably securely stored) [[ref: pre-rotation]] key in order to rotate the DID keys. -The cost of having [[ref: pre-rotation]] protection is a much more complicated process to update +The cost of having [[ref: pre-rotation]] protection is a 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 [[ref: pre-rotation]] feature. The feature definitely adds a +thinking about how to use the [[ref: pre-rotation]] feature. The feature adds a layer of key management complexity in return for the benefit. #### Key Rotation with Pre-Rotation In using [[ref: pre-rotation]], a [[ref: DID Controller]] should generate an "active" key -for the [[ref: DIDDoc]] where it can be used for "production" purposes (signing, +for the [[ref: DIDDoc]] that is accessible 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 +same intrusion attack. For example, if 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 [[ref: DID Controller]] creating the DID would request from an isolated @@ -74,11 +74,6 @@ both be for quantum-safe keys. #### Challenges in Using Pre-Rotation -This draft specification states that once [[ref: pre-rotation]] is enabled (via [[ref: -DID log entry]] [[ref: parameter]]), it **MUST** apply to all of the keys in the -DIDDoc. However, we're not sure if that is needed, or if the [[ref: 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 diff --git a/spec/overview.md b/spec/overview.md index 1a377ce..ae4b551 100644 --- a/spec/overview.md +++ b/spec/overview.md @@ -15,8 +15,8 @@ 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 [[ref: self-certifying identifier]] (SCID), update key(s) +method aims to enhance `did:web` by introducing features such +as a [[ref: self-certifying identifiers]] (SCIDs), update key(s) and a verifiable history, akin to what is available with ledger-based DIDs, without relying on a ledger. @@ -61,31 +61,29 @@ The following is a `tl;dr` summary of how `did:tdw` works: whitespace removed (per [[ref: JSON Lines]]). Each entry contains the information needed to derive a version of the [[ref: DIDDoc]] from its preceding version. The `did.jsonl` is also referred to as the [[ref: DID Log]]. -3. Each [[ref: DID log entry]] includes a JSON array of five items: - 1. The `versionId` of the entry, a value that combines the version number - (starting at `1` and incrementing by one per version), a literal dash +3. Each [[ref: DID log entry]] is a JSON object containing the following items: + 1. `versionId` -- a value that combines the version number + (starting at `1` and incremented by one per version), a literal dash `-`, and a hash of the entry. The [[ref: entry hash]] calculation links each entry to its predecessor in a ledger-like chain. - 2. The `versionTime` (as stated by the [[ref: DID Controller]]) of the entry. + 2. `versionTime` -- as asserted by the [[ref: DID Controller]]. 3. A set of `parameters` that impact the processing of the current and future [[ref: log entries]]. - Example [[ref: parameters]] are the version of the `did:tdw` specification and hash algorithm being used as well as the [[ref: SCID]] and update key(s). - 4. The new version of the [[ref: DIDDoc]] as either a `value` (the full document) or - a `patch` derived using [[ref: JSON Patch]] to update the new version from - the previous entry. - 5. A [[ref: Data Integrity]] (DI) proof across the entry, signed by a [[ref: DID - Controller]] authorized to update the [[ref: DIDDoc]], using the `versionId` as the - challenge. -4. In generating the first version of the [[ref: DIDDoc]], the [[ref: DID Controller]] calculates - the [[ref: SCID]] for the DID from the entire first [[ref: log entry]] (which - includes the [[ref: DIDDoc]]) by adding the string {SCID} everywhere the actual [[ref: SCID]] - is to be placed. The [[ref: DID Controller]] then replaces these placeholders - with the just calculated [[ref: SCID]], including it as a `parameter` in the first [[ref: log - entry]], and inserting it where needed in the initial (and all subsequent) - DIDDocs. The [[ref: SCID]] enables an optional [[ref: 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. + 4. The `state`, the new version of the [[ref: DIDDoc]]. + 5. A [[ref: Data Integrity]] (DI) proof across the entry, signed by a [[ref: + DID Controller]] authorized key to update the [[ref: DIDDoc]], and optionally, + a set of witnesses that monitor the actions of the DID Controller. +4. In generating the first version of the [[ref: DIDDoc]], the [[ref: DID + Controller]] calculates the [[ref: SCID]] for the DID from the first [[ref: + log entry]] (which includes the [[ref: DIDDoc]]) by using the string + `"{SCID}"` everywhere the actual [[ref: SCID]] is to be placed. The [[ref: DID + Controller]] then replaces the placeholders with the calculated [[ref: SCID]], + including it as a `parameter` in the first [[ref: log entry]], and inserting + it where needed in the initial (and all subsequent) DIDDocs. The [[ref: SCID]] + enables an optional [[ref: portability]] capability, allowing a DID's web + location to be moved, while retaining the DID and version history of the DID. 5. A [[ref: DID Controller]] generates and publishes the new/updated [[ref: DID Log]] file by making it available at the appropriate location on the web, based on the identifier of the DID. diff --git a/spec/specification.md b/spec/specification.md index a9c22a2..7532e5b 100644 --- a/spec/specification.md +++ b/spec/specification.md @@ -21,15 +21,16 @@ 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](#the-did-to-https-transformation) can be performed such that the [[ref: DID Log]] for the `did:tdw` DID is retrieved (via -an `HTTP GET`) and processed to produce the [[ref: DIDDoc]] for the DID. As per the -Augmented Backus-Naur Form (ABNF) notation below, the [[ref: SCID]] **MUST** be the first element of -the method-specific identifier. +an `HTTP GET`) and processed to produce the [[ref: DIDDoc]] for the DID. As per +the Augmented Backus-Naur Form (ABNF) notation below, the [[ref: SCID]] **MUST** +be the first element of the method-specific identifier. Formal rules describing valid domain name syntax are described in [[spec:RFC1035]], [[spec:RFC1123]], and [[spec:RFC2181]]. Each `did:tdw` DID's -globally unique [[ref: SCID]] is [generated](#scid-generation-and-verification) -during the creation of the DID based on its initial content and placed into -the DID identifier for publication and use. +globally unique [[ref: SCID]] **MUST** be +[generated](#scid-generation-and-verification) 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 @@ -128,7 +129,7 @@ path w/ port ::: The location of the `did:tdw` `did.jsonl` [[ref:DID Log]] file is the same as -where the comparable `did:web` `did.json` file is published. A [[ref: DID +where the comparable `did:web`'s `did.json` file is published. A [[ref: DID Controller]] **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](#publishing-a-parallel-didweb-did) section of this specification. @@ -140,35 +141,38 @@ version of the DID is an update to the contents of the resolved [[ref: DIDDoc]] DID, and/or a change to the [[ref: parameters]] that control the generation and verification of the DID. -Each entry is a JSON array consisting of the following 5 items. +Each entry is a JSON object consisting of the following items. -`[ versionId, versionTime, parameters, DIDDoc State, Data Integrity Proof ]` +`{ "versionId": "", "versionTime": "", "parameters": {}, "state": {}, "proof" : {} }` -1. The entry `versionId` is a value that combines the version number (starting at - `1` and incrementing by one per DID version), a literal dash `-`, and the - `entryHash`, a hash calculated across the [[ref: 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 +1. The value of `versionId` **MUST** be a string consisting of the DID version number + (starting at `1` and incrementing by one per DID version), a literal dash + `-`, and the `entryHash`, a hash calculated across the [[ref: 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](#entry-hash-generation-and-verification) section of this specification. -2. The `versionTime` (as stated by the [[ref: DID Controller]]) of the entry, in [[ref: ISO8601]] format. -3. A JSON object `parameters` that define configurations/options used in the - processing of current and future [[ref: log entries]]. `parameters` are defined in the - [`did:tdw` DID Method Parameters](#didtdw-did-method-parameters) section of - this specification. -4. The `DIDDoc State` for this version of the DID as either `value`, the full - [[ref: DIDDoc]], or `patch`, such that the new [[ref: DIDDoc]] is derived using - [[ref: JSON Patch]] from the previous entry. -5. A `Data Integrity Proof` across the entry, signed by a [[ref: DID - Controller]] authorized to update the [[ref: DIDDoc]], using the `versionId` as the - challenge. +2. The value of `versionTime` **MUST** be a timestamp of the entry in [[ref: + ISO8601]] format, as asserted by the [[ref: DID Controller]]. The timestamp + **MUST** be the time the DID will be retrieved by a [[ref: witness]] or resolver, + or before. +3. The JSON object `parameters` contains the configurations/options set by the + [[ref: DID Controller]] to be used in the processing of current and future + [[ref: log entries]]. Permitted `parameters` are defined in the [`did:tdw` + DID Method Parameters](#didtdw-did-method-parameters) section of this + specification. +4. The JSON object `state` contains the [[ref: DIDDoc]] for this version of the + DID. +5. The JSON object `proof` is a [[ref: Data Integrity]] proof calculated across + the entry and signed by key authorized to update the [[ref: DIDDoc]]. After creation, each entry has (per the [[ref JSON Lines]] specification) all extra whitespace removed, a `\n` character appended, and the result added to the [[ref: DID Log]] file for publication. -A more comprehensive description of how to create a [[ref: DID log entry]] and update it -into a [[ref: JSON Line]] is given in steps 4 - 6 of the next section. +A more comprehensive description of how to create and update a [[ref: DID log +entry]] is given in steps 4 - 6 of the [create DID](#create-register) section. Examples of [[ref: DID Logs]] and [[ref: DID log entries]] can be found in the [did:tdw` Examples](#didtdw-example) section of this specification. @@ -189,12 +193,13 @@ Creating a `did:tdw` DID is done by carrying out the following steps. The DID **MUST** be a valid `did:tdw` DID as per the ABNF of a `did:tdw` DID defined in the [Method-Specific Identifier](#method-specific-identifier) section of this specification. - 1. Note: the [[ref: SCID]] for a `did:tdw` DID is not by default in the HTTPS URL for the DID. - A [[ref: DID Controller]] that wants to include the [[ref: 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 [[ref: SCID]] have no impact on the handling of the - DID, and are treated like any other part of the domain and/or path. + 1. Note: the [[ref: SCID]] for a `did:tdw` DID is not by default in the HTTPS + URL for the DID. A [[ref: DID Controller]] **MAY** include the [[ref: + SCID]] in the HTTPS URL by inserting additional placeholder `{SCID}` + strings into the domain name or path components of the method-specific + identifier when creating the DID. Additional instance(s) of the [[ref: + SCID]] in the domain and/or path parts of the DID does not alter the + [DID-to-HTTPS transformation](#the-did-to-https-transformation). 2. **Generate the authorization key pair(s)** [Authorized keys](#authorized-keys) are authorized to control (create, update, deactivate) the DID. @@ -215,74 +220,71 @@ Creating a `did:tdw` DID is done by carrying out the following steps. step 1, including the placement of the `{SICD}` placeholder for the [[ref: SCID]]. Other [[ref: DIDDoc]] verifications **SHOULD** be performed. - All other absolute self-reference's to the DID in the [[ref: DIDDoc]] must use the form defined + All other absolute reference's to the DID in the [[ref: DIDDoc]] must use the form defined in step 1, with the identified placeholder for the [[ref: SCID]] (e.g., `did:tdw:{SCID}:example.com#key-1`, - `did:tdw:{SCID}:example.com:dids:issuer#key-1`, etc.). The [[ref: DIDDoc]] can contain any other content as deemed necessary by the [[ref: DID Controller]]. + `did:tdw:{SCID}:example.com:dids:issuer#key-1`, etc.). + + The [[ref: DIDDoc]] can contain any other content as deemed necessary by the [[ref: DID Controller]]. 1. Note: The placeholder (the string `{SCID}`) **MUST** be in every place in the [[ref: DIDDoc]] where the [[ref: SCID]] is to be placed. -4. **Generate a preliminary DID Log Entry** (input JSON array) - The [[ref: 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}", "", "parameters": [ ], { "value": "" } ]` - - 1. **Add a preliminary `versionId` value** - The first item in the input JSON array **MUST** be the placeholder string `{SCID}`. - 2. **Add the `versionTime` value** - The second item in the input JSON array **MUST** be a valid [[ref: ISO8601]] date/time string, - and that the represented time **MUST** be before or equal to the current time. - 3. **Define the [[ref: parameters]]** - The third item in the input JSON array **MUST** be the [[ref: parameters]] - JSON object. The [[ref: parameters]] are used to configure the DID generation and verification - processes. All [[ref: parameters]] **MUST** be valid and all required values in the first version - of the DID **MUST** be present. - - The [DID Generation and Verification Parameters](#didtdw-did-method-parameters) - section of this specification defines the permitted [[ref: parameters]]. That - section defines what items **MUST** be included in this first [[ref: log entry]] for the DID. - Collect and use the specified [[ref: parameters]] in the remainder of the DID creation steps. - - 4. **Add the initial [[ref: DIDDoc]]** - The fourth item in the input JSON array **MUST** be the JSON object `{"value": }`, - where `` is the initial [[ref: DIDDoc]] as described in the previous step 3. +4. **Generate a preliminary DID Log Entry** JSON object containing the same JSON + items that will be in the published [[ref: DID log entry]], but with some + values preset, pending calculation of the [[ref: SCID]] and [[ref entryHash]] and + without the `proof` item. + + 1. The value of `versionId` string **MUST** be the placeholder literal `"{SCID}"`. + 2. The value of `versionTime` string **MUST** be a valid [[ref: ISO8601]] date/time string, + and the represented time **MUST** be before or equal to the current time. + 3. The value of the `parameters` item must be a JSON object defined at the + discretion of the [[ref: DID Controller]]. The items in the object + **MUST** be as permitted in the [DID Generation and Verification + Parameters](#didtdw-did-method-parameters) section of this specification, + and all required values in the first version of the DID **MUST** be + present. In addition, where the [[ref: SCID]] of the DID is referenced in + the parameters, the placeholder literal string `{SCID}` **MUST** be used + in place of the to-be-calculated [[ref: SCID]]. + 4. The value of the `state` item **MUST** be the initial [[ref: DIDDoc]] as + defined in the previous step 3 of this process. 5. **Update the preliminary DID Log Entry to the initial DID Log Entry** Use the preliminary [[ref: DID log entry]] to perform the consecutive steps: 1. **Calculate the [[ref: SCID]]** - The input JSON array **MUST** be used to calculate the [[ref: SCID]] for the DID as defined in + The preliminary JSON object **MUST** be used to calculate the [[ref: SCID]] for the DID as defined in the [SCID Generation and Verification](#scid-generation-and-verification) section of this specification. - 2. **Replace the placeholder `{SCID}`** - Replace throughout the input JSON array the placeholder "`{SCID}`" for the [[ref: SCID]] with - the calculated [[ref: SCID]] from the previous step. + 2. **Replace the placeholder `{SCID}`** Replace throughout the preliminary + JSON object the placeholder "`{SCID}`" with the calculated [[ref: SCID]] from + the previous step. 3. **Calculate the [[ref: Entry Hash]]** - The JSON array updated in the previous step **MUST** be used to calculate the [[ref: Entry Hash]] + The preliminary JSON object updated in the previous step **MUST** be used to calculate the [[ref: Entry Hash]] (`entryHash`) for the [[ref: log entry]], as defined in the [Entry Hash Generation and Verification](#entry-hash-generation-and-verification) section of this specification. - 4. **Replace the preliminary `versionId` value** - The value of the `versionId` (first) item of the JSON array **MUST** be updated with the - literal string `1-` (for version number 1) followed by the `entryHash` value produced in the previous step. - 5. **Generate the [[ref: Data Integrity]] proof** - A [[ref: Data Integrity]] proof on the initial [[ref: DIDDoc]] **MUST** be generated - using an authorized key from a DID in the required `updateKeys` item in the [[ref: parameters]], - and the `versionId` as the proof `challenge`. - - If the [[ref: DID Controller]] has opted to use [[ref: witnesses]] for the DID, the required approvals - from the DID's [[ref: witnesses]] **MUST** be collected and added to the - [[ref: Data Integrity]] proof item. See the [DID Witnesses](#did-witnesses) section of this specification. - - 6. **Add the [[ref: Data Integrity]] proof** - The fifth item in the input JSON array **MUST** be added to the JSON array. The result is in the + 4. **Replace the preliminary `versionId` value** The value of the `versionId` + item **MUST** be updated with the literal string `1` (for version number 1), + a literal `-`, followed by the `entryHash` value calculated in the previous + step. + 5. **Generate the [[ref: Data Integrity]] proof** A [[ref: Data Integrity]] + proof on the preliminary JSON object as updated in the previous step **MUST** + be generated using an authorized key in the required `updateKeys` item in the + [[ref: parameters]] object. + + If the [[ref: DID Controller]] has opted to use [[ref: witnesses]] for the + DID, the required approvals from the DID's [[ref: witnesses]] **MUST** be + collected and added to the [[ref: Data Integrity]] proof item. See the [DID + Witnesses](#did-witnesses) section of this specification. + + 6. **Add the [[ref: Data Integrity]] proof** The [[ref Data Integrity]] proof + is added to the preliminary JSON object. The resultant JSON object is the initial [[ref: DID log entry]] for the DID. 6. **Generate the first [[ref: JSON Line]]** The [[ref: DID log entry]] **MUST** be updated to be a [[ref: JSON Lines]] entry by removing extraneous white space and appending a carriage return, - and stored as the contents of the file `did.jsonl`. + and the result stored as the contents of the file `did.jsonl`. 7. **Publish the [[ref: DID Log]]** The complete [[ref: DID Log]] file **MUST** be published at the appropriate Web location defined by @@ -320,16 +322,14 @@ The following steps MUST be executed to resolve the [[ref: DIDDoc]] for a `did:t To process the retrieved [[ref: DID Log]] file, the resolver **MUST** carry out the following steps on each of the [[ref: log entries]] in the order they appear in the file, applying the [[ref: parameters]] set from the current and previous -entries. As noted in the [DID Log File](#the-did-log-file) section, log entries -are each a JSON array with five items: +entries. As noted in the [DID Log File](#the-did-log-file) section, [[ref: log entries]] +are each a JSON object with the following items: 1. `versionId` 2. `versionTime` 3. `parameters` - 4. `DIDDoc State` -- either the full `value` or a [[ref: JSON Patch]] `patch` - to be applied to the prior version of the [[ref: DIDDoc]]. - 5. A [[ref: Data Integrity]] proof array for the version of the [[ref: DIDDoc]] corresponding to that - entry. + 4. `state` -- the version's [[ref: DIDDoc]]. + 5. `proof` -- a [[ref: Data Integrity]] proof across the [[ref: log entry]]. For each entry: @@ -349,7 +349,7 @@ For each entry: Integrity]] proofs **MUST** be valid and **MUST** be signed by a threshold of [[ref: witnesses]]. For details, see the [DID Witnesses](#did-witnesses) section of this specification. -3. Verify the `versionId` for the entry. Recall the the `versionId` is the +3. Verify the `versionId` for the entry. The `versionId` is the concatenation of the version number, a dash (`-`), and the `entryHash`. 1. The version number **MUST** be `1` for the the first [[ref: log entry]] and **MUST** be incremented by one for each subsequent [[ref: log entry]]. @@ -372,9 +372,8 @@ For each entry: (defined in the [[ref: parameters]]) according to the [SCID Generation and Verification](#scid-generation-and-verification) section of this specification. -7. Extract the contents of the [[ref: DIDDoc]] for each entry by using the JSON value - of the `value` item, or by using [[ref: JSON Patch]] to apply the JSON - value of the `patch` entry item to the previous version of the [[ref: DIDDoc]]. +7. Get the value of the [[ref: log entry]] item `state`, which is the [[ref: + DIDDoc]] for the version. 8. If [[ref: Key Pre-Rotation]] is being used, the hash of all `updateKeys` entries in the `parameters` item **MUST** match a hash in the active array of `nextKeyHashes` [[ref: parameter]], as defined in the @@ -438,10 +437,10 @@ verifiable [[ref: DID Log Entry]] follows a similar process to the is forced to) publish the DID at a different Internet location and wants to retain the [[ref: SCID]] and history of the DID. For details, see the [DID Portability](#did-portability) section of this specification. -2. Define a JSON array of [[ref: parameters]] that affect the evolution of the +2. Define the [[ref: parameters]] JSON object to include the items that affect the evolution of the DID. The `parameters` **MUST** be from those listed in the [`did:tdw` DID Method Parameters](#didtdw-did-method-parameters) section of this - specification. Any [[ref: parameters]] defined in the array override the + specification. Any [[ref: parameters]] defined in the JSON object override the previously active value, while any [[ref: parameters]] not included imply the existing values remain in effect. If no changes to the [[ref: parameters]] are needed, an empty JSON object `{}` **MUST** be used. @@ -450,35 +449,28 @@ verifiable [[ref: DID Log Entry]] follows a similar process to the effect after the entry has been published. For example, rotating the keys authorized to update a DID or changing the [[ref: witnesses]] for a DID take effect only *after* the entry in which they are defined has been published. -3. Generate a preliminary [[ref: DID Log Entry]] JSON array with the following JSON items: - 1. The `versionId` **MUST** be `versionId` value from the previous [[ref: DID Log Entry]]. - 2. The `versionTime` value **MUST** be an [[ref: ISO8601]] format time. The time - **MUST** be greater than the time of the previous [[ref: log entry]], and **MUST** be less - than or equal to the current time. +3. Generate a preliminary [[ref: DID log entry]] JSON object containing the following JSON items: + 1. The value of `versionId` **MUST** be the value of `versionId` from the *previous* [[ref: DID log entry]]. + 2. The `versionTime` value **MUST** be a string that is an [[ref: ISO8601]] + format timestamp. The time **MUST** be greater than the time of the + previous [[ref: log entry]], and **MUST** be the time the DID will be + retrieved by a [[ref: witness]] or resolver, or before. 3. The [[ref: parameters]] passed in as a JSON object. - 4. Generate a [[ref: JSON Patch]] to evolve the previous [[ref: DIDDoc]] version to - the new [[ref: DIDDoc]] version, and put the resulting patch in the item as - `{"patch": }`. For details of the process, see the - [Generating and Applying a JSON Patch](#generating-and-applying-a-json-patch) - section of this specification. - 1. An implementation **MAY** skip the [[ref: JSON Patch]] process and - simply put the full new version of the [[ref: DIDDoc]] in the item - `{"value": }` as is done in the initial entry in the log. + 4. Set the `state` JSON object to be the new version of the [[ref: DIDDoc]]. 4. Calculate the new `versionId` of the new [[ref: DID Log Entry]], including incrementing the version number integer and using the process described in the [Entry Hash Generation and Verification](#entry-hash-generation-and-verification) section of this specification. 5. Replace the value of the `versionId` item in the preliminary [[ref: DID Log Entry]] with the value produced in the previous step. -6. Generate a [[ref: Data Integrity]] proof on the new [[ref: DIDDoc]] of the entry - using an authorized key, and the `versionId` as the proof - `challenge`. The definition of "authorized" is formalized in the - [Authorized Keys](#authorized-keys) section of this specification. +6. Generate a [[ref: Data Integrity]] proof on the [[ref: DID log entry]] using + an authorized key, as defined in the [Authorized Keys](#authorized-keys) + section of this specification. 7. If the [[ref: DID Controller]] has opted to use [[ref: witnesses]] for the DID, collect the required approvals from the DID's [[ref: witnesses]], adding their proofs to the [[ref: data integrity]] proof. See the [DID Witnesses](#did-witnesses) section of this specification. -8. The proof array **MUST** be added as the fifth and last JSON item in the [[ref: log entry]]. +8. The proof JSON object **MUST** be added as the value of the `proof` item in the [[ref: log entry]]. 9. The entry **MUST** be made a [[ref JSON Line]] by removing extra whitespace, adding a `\n` to the entry. 10. The new [[ref: log entry]] **MUST** be appended to the existing contents of @@ -495,11 +487,12 @@ section of this specification. #### Deactivate (Revoke) -To deactivate the DID, the [[ref: DID Controller]] **SHOULD** add to the [[ref: +To deactivate the DID, the [[ref: DID Controller]] **MUST** add to the [[ref: DID log entry]] [[ref: parameters]] the item `"deactivated": true`. A [[ref: DID -Controller]] **MAY** update the [[ref: DIDDoc]] further to indicate the deactivation of -the DID, such as including an empty `updateKeys` list (`"updateKeys": []`) in -the [[ref: parameters]], preventing further versions of the DID. +Controller]] **SHOULD** update the [[ref: DIDDoc]] and `parameters` object to +further indicate the deactivation of the DID, such as including an empty +`updateKeys` list (`"updateKeys": []`) in the [[ref: parameters]], preventing +further versions of the DID. A resolver encountering in the [[ref: DID log entry]] [[ref: parameters]] the item `"deactivated": true` **MUST** return in the [[ref: DIDDoc]] Metadata the JSON item @@ -513,12 +506,12 @@ of those processes is specified in the following sections. #### `did:tdw` DID Method Parameters -Entries in the `did:tdw` [[ref: DID Log]] file contain, in the 3rd item, a JSON -object that defines the DID processing [[ref: parameters]] being used by the [[ref: DID -Controller]] when publishing that and subsequent [[ref: DID log entries]]. A DID Resolver -will use the same [[ref: parameters]] when processing the [[ref: DID Log]] to resolve the -DID. The [[ref: parameters]] object **MUST** include only the items defined in this -specification. +Entries in the `did:tdw` [[ref: DID Log]] contain the JSON object `parameters` +that define the DID processing [[ref: parameters]] being used by the [[ref: DID +Controller]] when publishing the current and subsequent [[ref: DID log +entries]]. A DID Resolver **MUST** use the same [[ref: parameters]] when +processing the [[ref: DID Log]] to resolve the DID. The `parameters` object +**MUST** only include items defined in this specification. ::: example @@ -545,16 +538,17 @@ The allowed [[ref: parameter]] items and (where applicable) enumerated values fo items are defined below. - `method`: Defines the `did:tdw` specification version to use when processing a - given DID's log file. As new versions of this specifications are - defined, additional [[ref: 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 [[ref: Data Integrity]] cryptosuite. + given DID's log file. As new versions of this specifications are defined, + additional [[ref: parameters]] and enumerated values will be associated with + the `method` values. This allows a long lasting DID to evolve the settings + being used by the DID over time, such as changing the hash algorithms + permitted, or allowing other [[ref: Data Integrity]] cryptosuites. - This item **MUST** appear in the first [[ref: DID log entry]]. - This item **MAY** appear in later [[ref: DID log entries]] to indicate that - the processing rules for that and later [[ref: entries]] have been changed to a + the processing rules for that and later [[ref: log 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 + - `did:tdw:0.4`: Requires that the rules defined in this version of the specification be used in processing the log. Implied by the value are the following: - The permitted hash algorithms used by the [[ref: DID Controller]] **MUST** be `SHA-256` as defined in [[spec: rfc6234]]. - The permitted [[ref: Data Integrity]] cryptosuites used by the [[ref: DID Controller]] **MUST** be `eddsa-jcs-2022` as referenced in [[ref: eddsa-jcs-2022]]. @@ -567,7 +561,9 @@ items are defined below. `updateKeys` item, the currently active list continues to apply. See the [Authorized Keys](#authorized-keys) section of this specification for additional details. - - This item **MUST** appear in the first [[ref: DID log entry]]. + - This item **MUST** appear in the first [[ref: DID log entry]] and **MAY** + appear in subsequent entries, at the discretion of the + [[ref: DID Controller]]. - A key from the `updateKeys` item in the first [[ref: DID log entry]] **MUST** be used to authorize the initial [[ref: log entry]]. In all other [[ref: DID log entries]], an `updateKeys` item becomes active *after* the @@ -637,7 +633,7 @@ first [[ref: DID log entry]] and is the hash of the DID's inception event. ##### Generate SCID -To generate the required [[ref: SCID]] for a `did:tdw` DID, the DID Controller +To generate the [[ref: SCID]] for a `did:tdw` DID, the DID Controller **MUST** execute the following function: `base58btc(multihash(JCS(preliminary log entry with placeholders), ))` @@ -645,7 +641,7 @@ To generate the required [[ref: SCID]] for a `did:tdw` DID, the DID Controller Where: 1. The `preliminary [[ref: log entry]] with placeholders` consists of the following - pre-publication JSON array of what will become the first [[ref: log entry]]. The + pre-publication JSON object of what will become the first [[ref: log entry]]. The placeholder is the literal string "`{SCID}`". - The `versionId` entry, which **MUST** be `{SCID}`. @@ -654,8 +650,9 @@ Where: - The complete `parameters` for the initial [[ref: log entry]] as defined by the [[ref: DID Controller]], with the placeholder wherever the [[ref: SCID]] will eventually be placed. - - The `{"value": }` element with placeholders wherever the [[ref: SCID]] will - eventually be placed in the [[ref: DIDDoc]]. + - The `state` JSON object with the value being the initial [[ref: DIDDoc]] + with placeholders (the literal string "`{SCID}`") wherever the [[ref: + SCID]] will eventually be placed in the [[ref: DIDDoc]]. 2. `JCS` is an implementation of the [[ref: JSON Canonicalization Scheme]] [[spec:rfc8785]]. It outputs a canonicalized representation of its JSON @@ -677,13 +674,13 @@ To verify the [[ref: SCID]] of a `did:tdw` DID being resolved, the resolver 1. Extract the first [[ref: DID log entry]] and use it for the rest of the steps in this process. -2. Extract the `scid` item value from the [[ref: parameters]] in the [[ref: DID log entry]]. +2. Extract the `scid` item value from the [[ref: parameters]] in the [[ref: DID log entry]]. 3. Determine the hash algorithm used by the [[ref: DID Controller]] from the [[ref: multihash]] `scid` value. - The hash algorithm **MUST** be one listed in the [parameters](#didtdw-did-method-parameters) defined by the version of the `did:tdw` specification being used by the [[ref: DID Controller]] based on the `method` [[ref: parameters]] item. -4. Remove the [[ref: data integrity]] proof item from the first [[ref: DID log entry]]. +4. Remove the [[ref: data integrity]] proof item from the [[ref: DID log entry]]. 5. Replace the `versionId` item's value with the literal `"{SCID}"`. 6. Treat the resulting [[ref: log entry]] as a string and do a text replacement of the `scid` value from Step 2 with the literal string `{SCID}`. @@ -726,29 +723,35 @@ The following is an example of a preliminary [[ref: log entry]] that is processe produce an [[ref: entry hash]]. As this is a first entry in a [[ref: DID Log]], the input `entryHash` (first item) is the [[ref: SCID]] of the DID. +::: todo + +To Do: Replace this example with one from a ver. 0.4 specification implementation. + +::: + ```json -["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"}}] +{"versionId": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu", "versionTime": "2024-07-29T17:00:27Z", "parameters": { "prerotation": true, "updateKeys": ["z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc"], "nextKeyHashes": ["QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv"], "method": "did:tdw:0.4", "scid": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu" }, "state": { "@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1"], "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example"}} ``` -Resulting [[ref: entry hash]]: `QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ` +Resulting [[ref: entryHash]]: `QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ` ##### Verify The Entry Hash To verify the `entryHash` for a given `did:tdw` [[ref: DID log entry]], a DID Resolver **MUST** execute the following process: -1. Extract the `versionId` (first item) in the [[ref: DID log entry]], and +1. Extract the `versionId` in the [[ref: DID log entry]], and remove from it the version number and dash prefix, leaving the log entry - `entryHash`. + `entryHash` value. 2. Determine the hash algorithm used by the [[ref: DID Controller]] from the [[ref: multihash]] `entryHash` value. - The hash algorithm **MUST** be one listed in the [parameters](#didtdw-did-method-parameters) defined by the version of the `did:tdw` specification being used by the [[ref: DID Controller]] based on the `method` [[ref: parameters]] item set in the current or most recent prior [[ref: log entry]]. -3. Remove the [[ref: Data Integrity]] proof (5th item) from the [[ref: log entry]]. -4. Set the first item of the entry to the `versionId` (first item) of the +3. Remove the [[ref: Data Integrity]] `proof` from the [[ref: log entry]]. +4. Set the `versionId` in the entry object to be the `versionId` from the previous [[ref: log entry]]. If this is the first entry in the log, set the value to - the ``, the [[ref: SCID]] of the DID. + ``, the value of the [[ref: SCID]] of the DID. 5. Calculate the hash string as `base58btc(multihash(JCS(entry), ))`, where: 1. `entry` is the data from the previous step. 2. `JCS` is an implementation of the [[ref: JSON Canonicalization Scheme]] @@ -766,7 +769,7 @@ Resolver **MUST** execute the following process: #### Authorized Keys Each entry in the [[ref: DID Log]] **MUST** include a [[ref: Data Integrity]] -proof signed by a key **authorized** to control (create, update, deactivate) the +`proof` item signed by a key **authorized** to control (create, update, deactivate) the DID. The authorized verification keys for `did:tdw` are the [[ref: multikey]]-formatted public keys in the **active** `updateKeys` list from the `parameters` item of the [[ref: log entries]]. Any of the authorized verification keys may be referenced @@ -777,52 +780,16 @@ that first [[ref: log entry]]. For all subsequent [[ref: entries]], the **active is the most recent `updateKeys` **before** the [[ref: log entry]] to be verified. Thus, the general case is that each [[ref: log entry]] is signed by the keys from the **previous** [[ref: log entry]]. Once a [[ref: log entry]] containing an `updateKeys` list is -published, that `updateKeys` becomes the active list, and the previous +published, that `updateKeys` becomes the active list, and previous `updateKeys` are ignored. -A resolver of the DID **MUST** verify the signature and that the key used for -signing each [[ref: DID Log]] entry is one from the list of active `updateKeys`. -If not, terminate the resolution process with an error. +A resolver of the DID **MUST** verify the signature and the key used for signing +each [[ref: DID Log]] entry **MUST** be 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 [[ref: DID Controller]] -**MAY** generate a [[ref: JSON Patch]] to concisely define the changes in the -DIDDoc from the previous version. A [[ref: DID log entry]] that uses [[ref: JSON Patch]] -has a JSON object with a `patch` property, with the value the [[ref: -JSON Patch]] as its `DIDDoc State` (fourth) item. A [[ref: DID Controller]] **MAY** set the -`DIDDoc State` item of a [[ref: DID log entry]] to be the JSON item `value`, with its -value the complete [[ref: DIDDoc]]. Typically (but not required), a [[ref: DID Controller]] -will use `value` for the first [[ref: DID log entry]] and `patch` for all -subsequent [[ref: entries]]. - -To create the value for a `patch` item for a [[ref: DID log entry]], the [[ref: -DID Controller]] **MUST**: - -1. Have the fully resolved previous version of the [[ref: DIDDoc]]. -2. Have the updated new version of the [[ref: DIDDoc]] to be added. -3. Execute an implementation of [[ref: JSON Patch]] that takes the two DIDDocs - as inputs (previous before, new after) and outputs the resulting [[ref: JSON Patch]] - from before to after. -4. Set the `DIDDoc State` (fourth) item of the [[ref: DID log entry]] to `{"patch": ""}`, - where `` is the output of the previous step. - -When processing a [[ref: DID log entry]] with a `patch` as the fourth item, a -resolver **MUST**: - -1. Have the fully resolved previous version of the [[ref: DIDDoc]]. -2. Extract the value of the `DIDDoc State` (fourth) item of the [[ref: DID log entry]] `patch` value. - 1. If the `DIDDoc State` item is `value`, its value is the [[ref: DIDDoc]], and the - next step is not needed. -3. Execute an implementation of [[ref: JSON Patch]] that takes the previous - [[ref: DIDDoc]] and the extracted `patch` value as inputs, and outputs the - resulting new version of the [[ref: DIDDoc]]. - -The output is the [[ref: DIDDoc]] for that version of the DID. - #### DID Portability As noted in the [Update (rotate)](#update-rotate) section of the specification, @@ -855,7 +822,7 @@ section of this specification, a [[ref: DID Controller]] **MAY** define that `prerotation` is active for the DID (value `true`). When [[ref: pre-rotation]] is active, all verification [[ref: multikeys]] in the `updateKeys` [[ref: parameters]] item in other than the initial version of the [[ref: DIDDoc]] **MUST** have their hash in the currently -active nextKeyHashes` arrays from a previous [[ref: DID log entry]]. If +active nextKeyHashes` array from a previous [[ref: DID log entry]]. If not, terminate the resolution process with an error. To create a hash to be included in the `nextKeyHashes` array, the [[ref: DID @@ -885,8 +852,8 @@ authorization key. published, the private key can be used to sign DID update authorizations proofs. -A [[ref: DID Controller]] **MAY** add extra hashes (for keys or just random -strings) into a `nextKeyHashes` array. +A [[ref: DID Controller]] **MAY** add include extra entries (for keys or just random +strings) in a `nextKeyHashes` array. When processing other than the first [[ref: DID log entry]] where the `prerotation` [[ref: parameter]] is active, a `did:tdw` resolver **MUST**: @@ -897,7 +864,7 @@ When processing other than the first [[ref: DID log entry]] where the 2. The hash algorithm **MUST** be one listed in the [parameters](#didtdw-did-method-parameters) defined by the version of the `did:tdw` specification being used by the [[ref: DID Controller]]. -3. The resultant hash **MUST** in the most recently set `nextKeyHashes` prior to +3. The resultant hash **MUST** be in the most recently set `nextKeyHashes` prior to the [[ref: log entry]] being processed. If not, terminate the resolution process with an error. 4. A new `nextKeyHashes` list **MUST** be in the `parameters` of the [[ref: log @@ -932,7 +899,7 @@ An overview of the [[ref: witness]] mechanism is as follows: - Ideally, the [[ref: DID Controller]] does that in the inception event for the DID. - Over time, the list of [[ref: witnesses]] may evolve, with each change being - approved by the declared list of [[ref: witnesses]] from before such a + approved by the declared list of [[ref: witnesses]] from **before** such a change. - The [[ref: DID Controller]] prepares a [[ref: DID Log Entry]] and shares it with the [[ref: witnesses]]. @@ -947,9 +914,8 @@ An overview of the [[ref: witness]] mechanism is as follows: deployment of `did:tdw`. That is up to the ecosystem in which the [[ref: DID Controller]] and [[ref: witnesses]] are participating. - If the verification is successful and the approval granted, the [[ref: - witness]] sends a [[ref: Data Integrity]] proof to the [[ref: DID Controller]] similar - to that generated by the [[ref: DID Controller]], with the [[ref: DIDDoc]] as the signed object, - the entry log's `versionId` as the challenge, but signed by the [[ref: witnesses]] key. + witness]] sends a [[ref: Data Integrity]] proof across the [[ref: DID log entry]] to the [[ref: DID Controller]], similar + to that generated by the [[ref: DID Controller]], but signed by the [[ref: witness]]'s key. - When a weighted threshold of proofs are received, the DID Controller inserts the [[ref: witnesses]]'s proofs into the array of proofs that are the last item in the [[ref: DID Log Entry]] and publishes the updated version of the [[ref: DID @@ -1001,7 +967,7 @@ where: [[ref: DID Controller]]'s weights for a [[ref: DID log entry]] to be considered approved. - `selfWeight`: an integer that is the weight given the [[ref: DID Controller]]'s verified proof, in determining if the threshold has been surpassed. -- `witnesses`: an array of witnesses +- `witnesses`: an array of witnesses, each including the required fields: - `id`: the DID of the witness - `weight`: the weight of this [[ref: witness]]'s approval diff --git a/spec/version.md b/spec/version.md index b9735a3..0c95c20 100644 --- a/spec/version.md +++ b/spec/version.md @@ -2,6 +2,14 @@ The following lists the substantive changes in each version of the specification. +- Version 0.4 + - Removes the use of JSON Patch from the specification. The full DIDDoc is included in each [[ref: DID log entry]]. + - Changes the data format of the [[ref: DID log entries]] from an array to an object. The [[ref: DID Log]] remains in the [[ref: JSON Lines]] format. + - Changes the array items to be named JSON objects. + - Makes each DID version's [[ref: Data Integrity]] proof apply across the JSON + [[ref: DID log entry]] object, as is typical with [[ref: DID Integrity + Proofs]]. Previously, the [[ref: Data Integrity]] proof was generated across + the current DIDDoc version, with the `versionId` as the challenge. - Version 0.3 - Removes the `cryptosuite` [[ref: parameter]], moving it to implied based on the `method` [[ref: parameter]]. - Change base32 encoding with [[ref: base58btc]], as it offers a better expansion rate. From f2852b08036fe0526a17efb37e11fa478b67bcae Mon Sep 17 00:00:00 2001 From: martipos <176692840+martipos@users.noreply.github.com> Date: Wed, 25 Sep 2024 08:45:47 +0200 Subject: [PATCH 2/7] Update spec/version.md (added change of data format for proof) Signed-off-by: martipos <176692840+martipos@users.noreply.github.com> Signed-off-by: martipos <176692840+martipos@users.noreply.github.com> --- spec/version.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/version.md b/spec/version.md index 0c95c20..da8166d 100644 --- a/spec/version.md +++ b/spec/version.md @@ -5,6 +5,7 @@ The following lists the substantive changes in each version of the specification - Version 0.4 - Removes the use of JSON Patch from the specification. The full DIDDoc is included in each [[ref: DID log entry]]. - Changes the data format of the [[ref: DID log entries]] from an array to an object. The [[ref: DID Log]] remains in the [[ref: JSON Lines]] format. + - Change the data format of the Data Integrity Proof from an array to an object - Changes the array items to be named JSON objects. - Makes each DID version's [[ref: Data Integrity]] proof apply across the JSON [[ref: DID log entry]] object, as is typical with [[ref: DID Integrity From d685b603907f0d8c0bda9175f735d0a26a451aa0 Mon Sep 17 00:00:00 2001 From: Stephen Curran Date: Thu, 26 Sep 2024 16:38:48 -0700 Subject: [PATCH 3/7] Update the examples to 0.4 examples Signed-off-by: Stephen Curran --- spec/example.md | 325 ++++++++++++++++++++---------------------- spec/specification.md | 10 +- 2 files changed, 153 insertions(+), 182 deletions(-) diff --git a/spec/example.md b/spec/example.md index 47a6ea8..8097c1c 100644 --- a/spec/example.md +++ b/spec/example.md @@ -1,18 +1,15 @@ ## `did:tdw` Example -**THE EXAMPLES IN THIS CHAPTER ARE OUT OF DATE, PENDING AN IMPLEMENTATION OF VER. O.4 OF THE SPECIFICATION.** - -**See the [Change Log](#didtdw-version-changelog) for what has changed between these ver. 0.3 examples, and the ver. 0.4 specification.** - The following shows the evolution of a `did:tdw` from inception through several versions, showing the DID, [[ref: DIDDoc]], [[ref: DID Log]], and some of the intermediate data structures. -**The examples are aligned with version 0.3 of the `did:tdw` specification.** +**The examples are aligned with version 0.4 of the `did:tdw` specification.** -In some of the following examples the data for the [[ref: 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 [[ref: JSON Lines]] convention. +In some of the following examples the data for the [[ref: 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 [[ref: JSON +Lines]] convention. ### DID Creation Data @@ -30,125 +27,115 @@ This example includes both the initial "authorized keys" to sign the [[ref: Data are in the `parameters` item in the [[ref: log entry]]. ```json -[ - "{SCID}", - "2024-07-29T17:00:27Z", - { +{ + "versionId": "{SCID}", + "versionTime": "2024-09-26T23:22:26Z", + "parameters": { "prerotation": true, "updateKeys": [ - "z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc" + "z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R" ], "nextKeyHashes": [ - "QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv" + "QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33" ], - "method": "did:tdw:0.3", + "method": "did:tdw:0.4", "scid": "{SCID}" }, - { - "value": { - "@context": [ - "https://www.w3.org/ns/did/v1", - "https://w3id.org/security/multikey/v1" - ], - "id": "did:tdw:{SCID}:domain.example" - } + "state": { + "@context": [ + "https://www.w3.org/ns/did/v1" + ], + "id": "did:tdw:{SCID}:domain.example" } -] +} ``` #### Output of the SCID Generation Process After the [[ref: SCID]] is generated, the literal `{SCID}` placeholders are -replaced by the generated [[ref: SCID]] value (below). This JSON is the input to -the [`entryHash` generation process](#entry-hash-generation-and-verification) -- -with the [[ref: 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 [[ref: SCID]] as the first item in the array --- the `versionId`. +replaced by the generated [[ref: SCID]] value (see below). This JSON is the +input to the [`entryHash` generation +process](#entry-hash-generation-and-verification) -- with the [[ref: SCID]] +`versionId``. 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 [[ref: +SCID]] as the `versionId` value. ```json -[ - "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu", - "2024-07-29T17:00:27Z", - { +{ + "versionId": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ", + "versionTime": "2024-09-26T23:22:26Z", + "parameters": { "prerotation": true, "updateKeys": [ - "z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc" + "z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R" ], "nextKeyHashes": [ - "QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv" + "QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33" ], - "method": "did:tdw:0.3", - "scid": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu" + "method": "did:tdw:0.4", + "scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ" }, - { - "value": { - "@context": [ - "https://www.w3.org/ns/did/v1", - "https://w3id.org/security/multikey/v1" - ], - "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example" - } + "state": { + "@context": [ + "https://www.w3.org/ns/did/v1" + ], + "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example" } -] +} ``` #### Data Integrity Proof Generation and First Log Entry The last step in the creation of the first [[ref: log entry]] is the generation of the [[ref: data integrity]] proof. One of the keys in the `updateKeys` [[ref: -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 [[ref: did log -entry]]) used as the `challenge` item. The generated proof is added to the [[ref: JSON -Line]] as the fifth item, and the entire array becomes the first entry in the -[[ref: DID Log]]. +parameter]] **MUST** be the `verificationMethod` in the proof (in `did:key` +form) to generate the signature across the post-[[ref: entryHash]] processed +[[ref: DID log entry]]. The generated proof is added to the [[ref: JSON Line]] +and the [[ref: log entry]] JSON object becomes the first entry in the [[ref: +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. +The following is the JSON prettified version of the entry log file that is +published as the initial `did.jsonl` file. When published, all extraneous +whitespace is removed, as shown in the block below the pretty-printed version. ```json -[ - "1-QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ", - "2024-07-29T17:00:27Z", - { +{ + "versionId": "1-QmQq6Kg4ZZ1p49znzxnWmes4LkkWgMWLrnrfPre8UD56bz", + "versionTime": "2024-09-26T23:22:26Z", + "parameters": { "prerotation": true, "updateKeys": [ - "z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc" + "z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R" ], "nextKeyHashes": [ - "QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv" + "QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33" ], - "method": "did:tdw:0.3", - "scid": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu" + "method": "did:tdw:0.4", + "scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ" }, - { - "value": { - "@context": [ - "https://www.w3.org/ns/did/v1", - "https://w3id.org/security/multikey/v1" - ], - "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example" - } + "state": { + "@context": [ + "https://www.w3.org/ns/did/v1" + ], + "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example" }, - [ + "proof": [ { "type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", - "verificationMethod": "did:key:z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc#z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc", - "created": "2024-07-29T17:00:27Z", + "verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R", + "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", - "challenge": "1-QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ", - "proofValue": "zDk24L4vbVrFm5CPQjRD9KoGFNcV6C3ub1ducPQEvDQ39U68GiofAndGbdG9azV6r78gHr1wKnKNPbMz87xtjZtcq9iwN5hjLptM9Lax4UeMWm9Xz7PP4crToj7sZnvyb3x4" + "proofValue": "z2fPF6fMewtV15kji2N432R7RjmmFs8p7MiSHSTM9FoVmJPtc3JUuZ472pZKoWgZDuT75EDwkGmZbK8ZKVF55pXvx" } ] -] +} ``` The same content "un-prettified", as it is found in the `did.jsonl` file: ```json -["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"}]] +{"versionId": "1-QmQq6Kg4ZZ1p49znzxnWmes4LkkWgMWLrnrfPre8UD56bz", "versionTime": "2024-09-26T23:22:26Z", "parameters": {"prerotation": true, "updateKeys": ["z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R"], "nextKeyHashes": ["QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33"], "method": "did:tdw:0.4", "scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ"}, "state": {"@context": ["https://www.w3.org/ns/did/v1"], "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"}, "proof": [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R", "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", "proofValue": "z2fPF6fMewtV15kji2N432R7RjmmFs8p7MiSHSTM9FoVmJPtc3JUuZ472pZKoWgZDuT75EDwkGmZbK8ZKVF55pXvx"}]} ``` #### `did:web` Version of DIDDoc @@ -162,12 +149,11 @@ Here is what the `did:web` [[ref: DIDDoc]] looks like for the `did:tdw` above. ```json { - "@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"] + "@context": [ + "https://www.w3.org/ns/did/v1" + ], + "id": "did:web:domain.example", + "alsoKnownAs": ["did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"] } ``` @@ -181,84 +167,85 @@ the [[ref: pre-rotation]] key. #### Version 2 Entry Hashing Input To generate a new version of the DID, the [[ref: DID Controller]] needs to -provide the existing [[ref: DID log]] file, the updated `parameters`, and the new [[ref: DIDDoc]]. -The following processing is done to create the new [[ref: DID log entry]]: +provide the updated `parameters`, and the new [[ref: DIDDoc]]. The following +processing is done to create the new [[ref: DID log entry]]: -- The `versionId` from the previous (first) [[ref: log entry]] is made the first item in the new [[ref: log entry]]. -- The `versionTime` is generated as the current time, and made the new `versionTime` (second) item. +- The `versionId` from the previous (first) [[ref: log entry]] is made the value + of the `versionId` in the new [[ref: log entry]]. +- The `versionTime` in the new [[ref: log entry]] is set to the current time. - The `parameters` entry passed in is processed. In this case, since the `updateKeys` array is updated, and [[ref: pre-rotation]] is active, the a -verification is done to ensure that the hash of the `updateKeys` are found in -the `nextKeyHashes` item from version 1 of the DID. As required by the `did:tdw` -specification, a new `nextKeyHashes` is included in the `parameters`. -- The new (but unchanged) [[ref: DIDDoc]] is included in its entirety, as the value of `value`, set as the third item in the array. - - The implementation could have used [[ref: JSON Patch]] to generate value of the `patch` item. -- The resulting array is passed into the [`entryHash` generation +verification is done to ensure that the hash of the `updateKeys` entries are +found in the `nextKeyHashes` item from version 1 of the DID. As required by the +`did:tdw` specification, a new `nextKeyHashes` is included in the new `parameters`. +- The new (but unchanged) [[ref: DIDDoc]] is included in its entirety, as the value of the `state` item. +- The resultant JSON object is passed into the [`entryHash` generation process](#entry-hash-generation-and-verification) which outputs the - `entryHash` for this [[ref: log entry]]. Once again, the first item - (`versionId`) in the [[ref: log entry]] is replaced by the version number (the - previous version number plus `1`), a dash (`-`), and the new `entryHash`. -- The [[ref: data integrity]] proof is generated added to the [[ref: log entry]] - as the sixth item, and the entire entry is added to the existing [[ref: DID - log]]. + `entryHash` for this [[ref: log entry]]. Once again, the `versionId` value is + replaced by the version number (the previous version number plus `1`, so `2` + in this case), a dash (`-`), and the new `entryHash`. +- The [[ref: data integrity]] proof is generated added to the [[ref: log + entry]], spaces are removed, a `CR` character added (per [[ref: JSON Lines]]) + and the entire entry is appended to the existing [[ref: DID log]] file. The [[ref: 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 [[ref: log entry]] for the second version of an example `did:tdw`. Things to note in this example: -- The [[ref: data integrity]] proof `verificationMethod` is the `did:key` from the first [[ref: log entry]], and the `challenge` is the `versionId` from this [[ref: log entry]]. -- A new `updateKeys` item in the `parameters` has been added, a commit to a future key that will control updates to the DID. +- The [[ref: data integrity]] proof `verificationMethod` is the `did:key` from + the first [[ref: log entry]], since the `updateKeys` change in the second + [[ref: log entry]] does not take affect until _after_ the version update is + complete. +- A new `updateKeys` item in the `parameters` has been added, along with + commitment to a future key (`nextKeyHashes`) that will control future updates + to the DID. ```json -[ - "2-QmY2v1VzkeMxF7MSfrLfZswQ74Y6FfrMR1LmuvPJQJwhi6", - "2024-07-29T17:00:28Z", - { +{ + "versionId": "2-QmXL6CLK1BMHAd3zQMqkY49VSc9T3zhUcPxu6zEW176PfN", + "versionTime": "2024-09-26T23:22:26Z", + "parameters": { "updateKeys": [ - "z82Lkvgj5NKYhoFh4hWzax9WicQaVDphN8MMzR3JZhontVfHaoGd9JbC4QRpDvmjQH3BLeQ" + "z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf" ], "nextKeyHashes": [ - "QmcCbGzGNr2EFduauzCoh3Hwt1GkRW4Gnkk5nxbr3625de" + "QmdA9fxQSLLwCQo6TkovcoaLgGYWq6Ttqx6A5D1RY13iFG" ] }, - { - "value": { - "@context": [ - "https://www.w3.org/ns/did/v1", - "https://w3id.org/security/multikey/v1" - ], - "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example" - } + "state": { + "@context": [ + "https://www.w3.org/ns/did/v1" + ], + "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example" }, - [ + "proof": [ { "type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", - "verificationMethod": "did:key:z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc#z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc", - "created": "2024-07-29T17:00:28Z", + "verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R", + "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", - "challenge": "2-QmY2v1VzkeMxF7MSfrLfZswQ74Y6FfrMR1LmuvPJQJwhi6", - "proofValue": "z2VDUyVapPpb6rC4YbLZRLcWS2zg9o53JU97QjNQYH7JvGs5Ccnf2b647Gw96G5N8rvEKc77uQTGqYvLJ6zrqNwGnqNLraTPD2AL2rR2eUiRKnM5KhbwWumDy5eqmTumm1FWp" + "proofValue": "z2nkLj9rYAMG7TStpvihuo4HTovpC7uvWcDoYiGhoN8cqQuiwW2EnPZdWtid2FZAQDQPoaNkTooKVftGKDTh9p3Fy" } ] -] +} ``` #### Log File For Version 2 The new version 2 `did.jsonl` file contains two [[ref: entries]], one for each version -of the [[ref: DIDDoc]]. +of the [[ref: DIDDoc]] -- as per the use of [[ref: JSON Lines]]. ```json -["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"}]] +{"versionId": "1-QmQq6Kg4ZZ1p49znzxnWmes4LkkWgMWLrnrfPre8UD56bz", "versionTime": "2024-09-26T23:22:26Z", "parameters": {"prerotation": true, "updateKeys": ["z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R"], "nextKeyHashes": ["QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33"], "method": "did:tdw:0.4", "scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ"}, "state": {"@context": ["https://www.w3.org/ns/did/v1"], "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"}, "proof": [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R", "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", "proofValue": "z2fPF6fMewtV15kji2N432R7RjmmFs8p7MiSHSTM9FoVmJPtc3JUuZ472pZKoWgZDuT75EDwkGmZbK8ZKVF55pXvx"}]} +{"versionId": "2-QmXL6CLK1BMHAd3zQMqkY49VSc9T3zhUcPxu6zEW176PfN", "versionTime": "2024-09-26T23:22:26Z", "parameters": {"updateKeys": ["z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf"], "nextKeyHashes": ["QmdA9fxQSLLwCQo6TkovcoaLgGYWq6Ttqx6A5D1RY13iFG"]}, "state": {"@context": ["https://www.w3.org/ns/did/v1"], "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"}, "proof": [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R", "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", "proofValue": "z2nkLj9rYAMG7TStpvihuo4HTovpC7uvWcDoYiGhoN8cqQuiwW2EnPZdWtid2FZAQDQPoaNkTooKVftGKDTh9p3Fy"}]} ``` #### Log File For Version 3 The same process is repeated for version 3 of the DID. In this case: -- The [[ref: DIDDoc]] is changed, and a patch generated. +- The [[ref: DIDDoc]] is changed. - an `authentication` method is added. - two services are added. - No changes are made to the authorized keys to update the DID. As a result, the `parameters` entry is empty (`{}`), and the [[ref: parameters]] in effect from previous versions of the DID remain in effect. @@ -266,72 +253,62 @@ The same process is repeated for version 3 of the DID. In this case: Here is the pretty-printed [[ref: log entry]]: ```json -[ - "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" - ] - }, +{ + "versionId": "3-QmaSKJRACGefmi19LkS6TFj5FeMEfr98GpBWk7vEmbhT92", + "versionTime": "2024-09-26T23:22:26Z", + "parameters": {}, + "state": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/multikey/v1", + "https://identity.foundation/.well-known/did-configuration/v1", + "https://identity.foundation/linked-vp/contexts/v1" + ], + "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example", + "authentication": [ + "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX" + ], + "assertionMethod": [ + "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX" + ], + "verificationMethod": [ { - "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" - } - ] - }, + "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX", + "controller": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example", + "type": "Multikey", + "publicKeyMultibase": "z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX" + } + ], + "service": [ { - "op": "add", - "path": "/@context/2", - "value": "https://identity.foundation/.well-known/did-configuration/v1" + "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#domain", + "type": "LinkedDomains", + "serviceEndpoint": "https://domain.example" }, { - "op": "add", - "path": "/@context/3", - "value": "https://identity.foundation/linked-vp/contexts/v1" + "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#whois", + "type": "LinkedVerifiablePresentation", + "serviceEndpoint": "https://domain.example/.well-known/whois.vc" } ] }, - [ + "proof": [ { "type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", - "verificationMethod": "did:key:z82Lkvgj5NKYhoFh4hWzax9WicQaVDphN8MMzR3JZhontVfHaoGd9JbC4QRpDvmjQH3BLeQ#z82Lkvgj5NKYhoFh4hWzax9WicQaVDphN8MMzR3JZhontVfHaoGd9JbC4QRpDvmjQH3BLeQ", - "created": "2024-07-29T17:00:28Z", + "verificationMethod": "did:key:z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf#z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf", + "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", - "challenge": "3-QmNwk72WkEjUMQxqkxYoKWNx8Y1pDiGUZCn9PpeLtfPtyk", - "proofValue": "z2TBssHyJj7dB4LDGjHWm3EfHhBiu534w4ucRF95XG3KzLg4m5kjtYbupGmf4txjqQRPko8Qd8PGeHgykWdutHXxJUmvvpGuiJxNBRpfwfKxnsbrT7jWeT6GqaFYqqkDcCG35" + "proofValue": "z2V72e7bRFpjvphDcWfYeSDTLsbkoVU5SfWAKMwpxYAL74D8GugTuoB2vH93cJqb8XXz8tN4es9AM787CogcbmXKa" } ] -] +} ``` Here is the [[ref: log entry]] for just version 3 of the DID. ```json -["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"}]] +{"versionId": "3-QmaSKJRACGefmi19LkS6TFj5FeMEfr98GpBWk7vEmbhT92", "versionTime": "2024-09-26T23:22:26Z", "parameters": {}, "state": {"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1", "https://identity.foundation/.well-known/did-configuration/v1", "https://identity.foundation/linked-vp/contexts/v1"], "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example", "authentication": ["did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX"], "assertionMethod": ["did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX"], "verificationMethod": [{"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX", "controller": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example", "type": "Multikey", "publicKeyMultibase": "z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX"}], "service": [{"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#domain", "type": "LinkedDomains", "serviceEndpoint": "https://domain.example"}, {"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#whois", "type": "LinkedVerifiablePresentation", "serviceEndpoint": "https://domain.example/.well-known/whois.vc"}]}, "proof": [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf#z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf", "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", "proofValue": "z2V72e7bRFpjvphDcWfYeSDTLsbkoVU5SfWAKMwpxYAL74D8GugTuoB2vH93cJqb8XXz8tN4es9AM787CogcbmXKa"}]} ``` And so on... diff --git a/spec/specification.md b/spec/specification.md index 7532e5b..fc334db 100644 --- a/spec/specification.md +++ b/spec/specification.md @@ -723,17 +723,11 @@ The following is an example of a preliminary [[ref: log entry]] that is processe produce an [[ref: entry hash]]. As this is a first entry in a [[ref: DID Log]], the input `entryHash` (first item) is the [[ref: SCID]] of the DID. -::: todo - -To Do: Replace this example with one from a ver. 0.4 specification implementation. - -::: - ```json -{"versionId": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu", "versionTime": "2024-07-29T17:00:27Z", "parameters": { "prerotation": true, "updateKeys": ["z82LkvR3CBNkb9tUVps4GhGpNvEVP6vWzdwgGwQbA1iYoZwd7m1F1hSvkJFSe6sWci7JiXc"], "nextKeyHashes": ["QmcbM5bppyT4yyaL35TQQJ2XdSrSNAhH5t6f4ZcuyR4VSv"], "method": "did:tdw:0.4", "scid": "Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu" }, "state": { "@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1"], "id": "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example"}} +{"versionId": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ", "versionTime": "2024-09-26T23:22:26Z", "parameters": {"prerotation": true, "updateKeys": ["z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R"], "nextKeyHashes": ["QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33"], "method": "did:tdw:0.4", "scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ"}, "state": {"@context": ["https://www.w3.org/ns/did/v1"], "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"}} ``` -Resulting [[ref: entryHash]]: `QmdwvukAYUU6VYwqM4jQbSiKk1ctg12j5hMTY6EfbbkyEJ` +Resulting [[ref: entryHash]]: `QmQq6Kg4ZZ1p49znzxnWmes4LkkWgMWLrnrfPre8UD56bz` ##### Verify The Entry Hash From 0d150e006007cd629a87bd74d8b3ee9061f97d41 Mon Sep 17 00:00:00 2001 From: Stephen Curran Date: Fri, 27 Sep 2024 11:26:43 -0700 Subject: [PATCH 4/7] Eradicate the term item, replaced mostly with property Signed-off-by: Stephen Curran --- spec/overview.md | 2 +- spec/specification.md | 120 +++++++++++++++++++++--------------------- spec/version.md | 3 +- 3 files changed, 62 insertions(+), 63 deletions(-) diff --git a/spec/overview.md b/spec/overview.md index ae4b551..06f8f3f 100644 --- a/spec/overview.md +++ b/spec/overview.md @@ -61,7 +61,7 @@ The following is a `tl;dr` summary of how `did:tdw` works: whitespace removed (per [[ref: JSON Lines]]). Each entry contains the information needed to derive a version of the [[ref: DIDDoc]] from its preceding version. The `did.jsonl` is also referred to as the [[ref: DID Log]]. -3. Each [[ref: DID log entry]] is a JSON object containing the following items: +3. Each [[ref: DID log entry]] is a JSON object containing the following properties: 1. `versionId` -- a value that combines the version number (starting at `1` and incremented by one per version), a literal dash `-`, and a hash of the entry. The [[ref: entry hash]] calculation links each entry diff --git a/spec/specification.md b/spec/specification.md index fc334db..4105539 100644 --- a/spec/specification.md +++ b/spec/specification.md @@ -141,9 +141,9 @@ version of the DID is an update to the contents of the resolved [[ref: DIDDoc]] DID, and/or a change to the [[ref: parameters]] that control the generation and verification of the DID. -Each entry is a JSON object consisting of the following items. +Each entry is a JSON object consisting of the following properties. -`{ "versionId": "", "versionTime": "", "parameters": {}, "state": {}, "proof" : {} }` +`{ "versionId": "", "versionTime": "", "parameters": {}, "state": {}, "proof" : [] }` 1. The value of `versionId` **MUST** be a string consisting of the DID version number (starting at `1` and incrementing by one per DID version), a literal dash @@ -164,7 +164,7 @@ Each entry is a JSON object consisting of the following items. specification. 4. The JSON object `state` contains the [[ref: DIDDoc]] for this version of the DID. -5. The JSON object `proof` is a [[ref: Data Integrity]] proof calculated across +5. The JSON array `proof` contains a [[ref: Data Integrity]] proof calculated across the entry and signed by key authorized to update the [[ref: DIDDoc]]. After creation, each entry has (per the [[ref JSON Lines]] specification) all @@ -211,12 +211,12 @@ Creating a `did:tdw` DID is done by carrying out the following steps. corresponding [[ref: pre-rotation]] hashes. 2. For each authorization key pair, generate a [[ref: multikey]] based on the key pair's public key. The [[ref: multikey]] representations of the public - keys are placed in the `updateKeys` item in [[ref: parameters]]. + keys are placed in the `updateKeys` property in [[ref: parameters]]. 3. The public key(s) of the authorization key pair(s) **MAY** be used in the [[ref: DIDDoc]] as well, but that is not required. 3. **Create the initial [[ref: DIDDoc]] for the DID** - The [[ref: DIDDoc]] **MUST** contain the top level `id` item which **MUST** be the DID string from + The [[ref: DIDDoc]] **MUST** contain the top level `id` property which **MUST** be the DID string from step 1, including the placement of the `{SICD}` placeholder for the [[ref: SCID]]. Other [[ref: DIDDoc]] verifications **SHOULD** be performed. @@ -230,22 +230,22 @@ Creating a `did:tdw` DID is done by carrying out the following steps. the [[ref: SCID]] is to be placed. 4. **Generate a preliminary DID Log Entry** JSON object containing the same JSON - items that will be in the published [[ref: DID log entry]], but with some + properties that will be in the published [[ref: DID log entry]], but with some values preset, pending calculation of the [[ref: SCID]] and [[ref entryHash]] and - without the `proof` item. + without the `proof`. 1. The value of `versionId` string **MUST** be the placeholder literal `"{SCID}"`. 2. The value of `versionTime` string **MUST** be a valid [[ref: ISO8601]] date/time string, and the represented time **MUST** be before or equal to the current time. - 3. The value of the `parameters` item must be a JSON object defined at the - discretion of the [[ref: DID Controller]]. The items in the object + 3. The value of the `parameters` property **MUST** be a JSON object defined at the + discretion of the [[ref: DID Controller]]. The properties in this nested JSON object **MUST** be as permitted in the [DID Generation and Verification Parameters](#didtdw-did-method-parameters) section of this specification, and all required values in the first version of the DID **MUST** be present. In addition, where the [[ref: SCID]] of the DID is referenced in the parameters, the placeholder literal string `{SCID}` **MUST** be used in place of the to-be-calculated [[ref: SCID]]. - 4. The value of the `state` item **MUST** be the initial [[ref: DIDDoc]] as + 4. The value of the `state` property **MUST** be the initial [[ref: DIDDoc]] as defined in the previous step 3 of this process. 5. **Update the preliminary DID Log Entry to the initial DID Log Entry** @@ -264,17 +264,17 @@ Creating a `did:tdw` DID is done by carrying out the following steps. [Entry Hash Generation and Verification](#entry-hash-generation-and-verification) section of this specification. 4. **Replace the preliminary `versionId` value** The value of the `versionId` - item **MUST** be updated with the literal string `1` (for version number 1), + property **MUST** be updated with the literal string `1` (for version number 1), a literal `-`, followed by the `entryHash` value calculated in the previous step. 5. **Generate the [[ref: Data Integrity]] proof** A [[ref: Data Integrity]] proof on the preliminary JSON object as updated in the previous step **MUST** - be generated using an authorized key in the required `updateKeys` item in the + be generated using an authorized key in the required `updateKeys` property in the [[ref: parameters]] object. If the [[ref: DID Controller]] has opted to use [[ref: witnesses]] for the DID, the required approvals from the DID's [[ref: witnesses]] **MUST** be - collected and added to the [[ref: Data Integrity]] proof item. See the [DID + collected and added to the [[ref: Data Integrity]] proof property. See the [DID Witnesses](#did-witnesses) section of this specification. 6. **Add the [[ref: Data Integrity]] proof** The [[ref Data Integrity]] proof @@ -323,7 +323,7 @@ To process the retrieved [[ref: DID Log]] file, the resolver **MUST** carry out the following steps on each of the [[ref: log entries]] in the order they appear in the file, applying the [[ref: parameters]] set from the current and previous entries. As noted in the [DID Log File](#the-did-log-file) section, [[ref: log entries]] -are each a JSON object with the following items: +are each a JSON object with the following properties: 1. `versionId` 2. `versionTime` @@ -372,10 +372,10 @@ For each entry: (defined in the [[ref: parameters]]) according to the [SCID Generation and Verification](#scid-generation-and-verification) section of this specification. -7. Get the value of the [[ref: log entry]] item `state`, which is the [[ref: +7. Get the value of the [[ref: log entry]] property `state`, which is the [[ref: DIDDoc]] for the version. 8. If [[ref: Key Pre-Rotation]] is being used, the hash of all `updateKeys` entries - in the `parameters` item **MUST** match a hash in + in the `parameters` property **MUST** match a hash in the active array of `nextKeyHashes` [[ref: parameter]], as defined in the [Key [[ref: Pre-Rotation]] Hash Generation and Verification](#pre-rotation-key-hash-generation-and-verification) section of this specification. @@ -433,11 +433,11 @@ verifiable [[ref: DID Log Entry]] follows a similar process to the 1. Make the desired changes to the [[ref: DIDDoc]]. While the contents of a new DIDDoc version are (mostly) up to the [[ref: DID controller]], there are some limitations: 1. If the DID is configured to support [[ref: portability]], the root `id` - item in the [[ref: DIDDoc]] **MAY** be changed when the [[ref: DID Controller]] wants to (or + property in the [[ref: DIDDoc]] **MAY** be changed when the [[ref: DID Controller]] wants to (or is forced to) publish the DID at a different Internet location and wants to retain the [[ref: SCID]] and history of the DID. For details, see the [DID Portability](#did-portability) section of this specification. -2. Define the [[ref: parameters]] JSON object to include the items that affect the evolution of the +2. Define the [[ref: parameters]] JSON object to include the properties that affect the evolution of the DID. The `parameters` **MUST** be from those listed in the [`did:tdw` DID Method Parameters](#didtdw-did-method-parameters) section of this specification. Any [[ref: parameters]] defined in the JSON object override the @@ -449,7 +449,7 @@ verifiable [[ref: DID Log Entry]] follows a similar process to the effect after the entry has been published. For example, rotating the keys authorized to update a DID or changing the [[ref: witnesses]] for a DID take effect only *after* the entry in which they are defined has been published. -3. Generate a preliminary [[ref: DID log entry]] JSON object containing the following JSON items: +3. Generate a preliminary [[ref: DID log entry]] JSON object containing the following properties: 1. The value of `versionId` **MUST** be the value of `versionId` from the *previous* [[ref: DID log entry]]. 2. The `versionTime` value **MUST** be a string that is an [[ref: ISO8601]] format timestamp. The time **MUST** be greater than the time of the @@ -461,7 +461,7 @@ verifiable [[ref: DID Log Entry]] follows a similar process to the incrementing the version number integer and using the process described in the [Entry Hash Generation and Verification](#entry-hash-generation-and-verification) section of this specification. -5. Replace the value of the `versionId` item in the preliminary [[ref: DID Log +5. Replace the value of the `versionId` property in the preliminary [[ref: DID Log Entry]] with the value produced in the previous step. 6. Generate a [[ref: Data Integrity]] proof on the [[ref: DID log entry]] using an authorized key, as defined in the [Authorized Keys](#authorized-keys) @@ -470,7 +470,7 @@ verifiable [[ref: DID Log Entry]] follows a similar process to the DID, collect the required approvals from the DID's [[ref: witnesses]], adding their proofs to the [[ref: data integrity]] proof. See the [DID Witnesses](#did-witnesses) section of this specification. -8. The proof JSON object **MUST** be added as the value of the `proof` item in the [[ref: log entry]]. +8. The proof JSON object **MUST** be added as the value of the `proof` property in the [[ref: log entry]]. 9. The entry **MUST** be made a [[ref JSON Line]] by removing extra whitespace, adding a `\n` to the entry. 10. The new [[ref: log entry]] **MUST** be appended to the existing contents of @@ -488,14 +488,14 @@ section of this specification. #### Deactivate (Revoke) To deactivate the DID, the [[ref: DID Controller]] **MUST** add to the [[ref: -DID log entry]] [[ref: parameters]] the item `"deactivated": true`. A [[ref: DID +DID log entry]] [[ref: parameters]] the property name and value `"deactivated": true`. A [[ref: DID Controller]] **SHOULD** update the [[ref: DIDDoc]] and `parameters` object to further indicate the deactivation of the DID, such as including an empty `updateKeys` list (`"updateKeys": []`) in the [[ref: parameters]], preventing further versions of the DID. A resolver encountering in the [[ref: DID log entry]] [[ref: parameters]] the -item `"deactivated": true` **MUST** return in the [[ref: DIDDoc]] Metadata the JSON item +property key:value pair `"deactivated": true` **MUST** return in the [[ref: DIDDoc]] Metadata the property key:value `"deactivated": true`, as per the [[spec:DID-RESOLUTION]] specification. ### DID Method Processes @@ -511,11 +511,11 @@ that define the DID processing [[ref: parameters]] being used by the [[ref: DID Controller]] when publishing the current and subsequent [[ref: DID log entries]]. A DID Resolver **MUST** use the same [[ref: parameters]] when processing the [[ref: DID Log]] to resolve the DID. The `parameters` object -**MUST** only include items defined in this specification. +**MUST** only include properties defined in this specification. ::: example -An example of the JSON prettified [[ref: parameters]] item in the first [[ref: DID Log]] entry for a DID: +An example of the JSON prettified `parameters` property in the first [[ref: DID Log]] entry for a DID: ``` json { @@ -534,8 +534,8 @@ An example of the JSON prettified [[ref: parameters]] item in the first [[ref: D ::: -The allowed [[ref: parameter]] items and (where applicable) enumerated values for those -items are defined below. +The allowed [[ref: parameter]] properties and (where applicable) enumerated values for those +properties are defined below. - `method`: Defines the `did:tdw` specification version to use when processing a given DID's log file. As new versions of this specifications are defined, @@ -543,8 +543,8 @@ items are defined below. the `method` values. This allows a long lasting DID to evolve the settings being used by the DID over time, such as changing the hash algorithms permitted, or allowing other [[ref: Data Integrity]] cryptosuites. - - This item **MUST** appear in the first [[ref: DID log entry]]. - - This item **MAY** appear in later [[ref: DID log entries]] to indicate that + - This property **MUST** appear in the first [[ref: DID log entry]]. + - This property **MAY** appear in later [[ref: DID log entries]] to indicate that the processing rules for that and later [[ref: log entries]] have been changed to a different specification version. - Acceptable values for this specification are: @@ -553,20 +553,20 @@ items are defined below. - The permitted hash algorithms used by the [[ref: DID Controller]] **MUST** be `SHA-256` as defined in [[spec: rfc6234]]. - The permitted [[ref: Data Integrity]] cryptosuites used by the [[ref: DID Controller]] **MUST** be `eddsa-jcs-2022` as referenced in [[ref: eddsa-jcs-2022]]. - `scid`: The value of the [[ref: SCID]] for this DID. - - This item **MUST** appear in the first [[ref: DID log entry]]. -- `updateKeys`: A list of one or more [[ref: multikey]] formatted public keys + - This property **MUST** appear in the first [[ref: DID log entry]]. +- `updateKeys`: An array of [[ref: multikey]] formatted public keys associated with the private keys that are authorized to sign the log entries that update the DID from one version to the next. An instance of the list in an entry replaces the previously active list. If an entry does not have the - `updateKeys` item, the currently active list continues to apply. See the + `updateKeys` property, the currently active list continues to apply. See the [Authorized Keys](#authorized-keys) section of this specification for additional details. - - This item **MUST** appear in the first [[ref: DID log entry]] and **MAY** + - This property **MUST** appear in the first [[ref: DID log entry]] and **MAY** appear in subsequent entries, at the discretion of the [[ref: DID Controller]]. - - A key from the `updateKeys` item in the first [[ref: DID log entry]] + - A key from the `updateKeys` array in the first [[ref: DID log entry]] **MUST** be used to authorize the initial [[ref: log entry]]. In all other - [[ref: DID log entries]], an `updateKeys` item becomes active *after* the + [[ref: DID log entries]], an `updateKeys` property becomes active *after* the publication of its entry -- meaning its [[ref: log entry]] **MUST** be signed by a key the most recent `updateKeys` list from a **prior** [[ref: DID log]] entry. @@ -579,8 +579,8 @@ items are defined below. for more details about renaming a `did:tdw` DID. - `prerotation`: A boolean value indicating that subsequent authentication keys added to the [[ref: DIDDoc]] (after this version) **MUST** have their hash included in - a `nextKeyHashes` [[ref: parameter]] item. - - The value is initialized to `false` until the item is included in a + a `nextKeyHashes` [[ref: parameter]] property. + - The value is initialized to `false` until the property is included in a [[ref: DID log entry]]. - Once the value is set to `true` in a [[ref: DID log entry]] it **MUST NOT** be set to `false` in a subsequent entry. @@ -594,19 +594,19 @@ items are defined below. formatted public keys added in a new `updateKeys` list **MUST** have their hashes listed in the currently active `nextKeyHashes` list. - A [[ref: DID Controller]] **MAY** put extra strings in the `nextKeyHashes` - item that are not subsequently used in an `updateKeys` entry. + array that are not subsequently used in an `updateKeys` entry. - When `prerotation` is active and the `updateKeys` [[ref: parameter]] is included in a - [[ref: parameters]] item, a `nextKeyHashes` item with a new set of hashes - **MUST** be included in the same [[ref: parameters]] item. Any unused + `parameters` property, a `nextKeyHashes` property with a new set of hashes + **MUST** be included in the same [[ref: parameters]] property. Any unused hashes in the prior `nextKeyHashes` are ignored. - `witness`: A JSON object containing the [[ref: parameters]] for declaring the witnesses for the DID, and the [[ref: parameters]] for the process of updating a DID via a collaboration with [[ref: witnesses]] prior to publication. For details of - this item data and its usage in the approvals process, see the + this data and its usage in the approvals process, see the [DID Witnesses](#did-witnesses) section of this specification. - - A `witness` item in the first [[ref: DID log entry]] is used to define the + - A `witness` property in the first [[ref: DID log entry]] is used to define the [[ref: witnesses]] and necessary threshold for that initial [[ref: log entry]]. In all other - [[ref: DID log entries]], a `witness` item becomes active **after** the publication + [[ref: DID log entries]], a `witness` property becomes active **after** the publication of its entry -- meaning its [[ref: log entry]] **MUST** be witnessed by the most recent `witnesses` from a **prior** [[ref: DID log]] entry. - `deactivated`: A JSON boolean that **SHOULD** be set to `true` when the DID is to @@ -674,14 +674,14 @@ To verify the [[ref: SCID]] of a `did:tdw` DID being resolved, the resolver 1. Extract the first [[ref: DID log entry]] and use it for the rest of the steps in this process. -2. Extract the `scid` item value from the [[ref: parameters]] in the [[ref: DID log entry]]. +2. Extract the `scid` property value from the [[ref: parameters]] in the [[ref: DID log entry]]. 3. Determine the hash algorithm used by the [[ref: DID Controller]] from the [[ref: multihash]] `scid` value. - The hash algorithm **MUST** be one listed in the [parameters](#didtdw-did-method-parameters) defined by the version of the `did:tdw` specification being used by the [[ref: DID Controller]] based on the - `method` [[ref: parameters]] item. -4. Remove the [[ref: data integrity]] proof item from the [[ref: DID log entry]]. -5. Replace the `versionId` item's value with the literal `"{SCID}"`. + `method` [[ref: parameters]] property. +4. Remove the [[ref: data integrity]] proof property from the [[ref: DID log entry]]. +5. Replace the `versionId` property value with the literal `"{SCID}"`. 6. Treat the resulting [[ref: log entry]] as a string and do a text replacement of the `scid` value from Step 2 with the literal string `{SCID}`. 7. Use the result and the hash algorithm (from Step 3) as input to the function @@ -692,13 +692,13 @@ To verify the [[ref: SCID]] of a `did:tdw` DID being resolved, the resolver #### 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 +`versionId` property in each DID log entry. Each `entryHash` is calculated across its [[ref: log entry]], excluding the [[ref: Data Integrity]] proof. The `versionId` used in the input to the hash is a predecessor value to the current [[ref: log entry]], ensuring that the [[ref: entries]] are cryptographically "chained" together in a microledger. For the first [[ref: 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. +`versionId` property from the previous log entry. ##### Generate Entry Hash @@ -721,7 +721,7 @@ preliminary [[ref: log entry]] as the string `entry`, where: The following is an example of a preliminary [[ref: log entry]] that is processed to produce an [[ref: entry hash]]. As this is a first entry in a [[ref: DID Log]], the input -`entryHash` (first item) is the [[ref: SCID]] of the DID. +`versionId` is the [[ref: SCID]] of the DID. ```json {"versionId": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ", "versionTime": "2024-09-26T23:22:26Z", "parameters": {"prerotation": true, "updateKeys": ["z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R"], "nextKeyHashes": ["QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33"], "method": "did:tdw:0.4", "scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ"}, "state": {"@context": ["https://www.w3.org/ns/did/v1"], "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"}} @@ -741,7 +741,7 @@ Resolver **MUST** execute the following process: - The hash algorithm **MUST** be one listed in the [parameters](#didtdw-did-method-parameters) defined by the version of the `did:tdw` specification being used by the [[ref: DID Controller]] based on the - `method` [[ref: parameters]] item set in the current or most recent prior [[ref: log entry]]. + `method` [[ref: parameters]] property set in the current or most recent prior [[ref: log entry]]. 3. Remove the [[ref: Data Integrity]] `proof` from the [[ref: log entry]]. 4. Set the `versionId` in the entry object to be the `versionId` from the previous [[ref: log entry]]. If this is the first entry in the log, set the value to @@ -763,9 +763,9 @@ Resolver **MUST** execute the following process: #### Authorized Keys Each entry in the [[ref: DID Log]] **MUST** include a [[ref: Data Integrity]] -`proof` item signed by a key **authorized** to control (create, update, deactivate) the +`proof` property signed by a key **authorized** to control (create, update, deactivate) the DID. The authorized verification keys for `did:tdw` are the [[ref: multikey]]-formatted -public keys in the **active** `updateKeys` list from the `parameters` item of +public keys in the **active** `updateKeys` list from the `parameters` property of the [[ref: log entries]]. Any of the authorized verification keys may be referenced in the [[ref: Data Integrity]] proof. @@ -814,7 +814,7 @@ in the Implementer's Guide for additional guidance. As described in the [parameters](#didtdw-did-method-parameters) section of this specification, a [[ref: DID Controller]] **MAY** define that `prerotation` is active for the DID (value `true`). When [[ref: pre-rotation]] is active, -all verification [[ref: multikeys]] in the `updateKeys` [[ref: parameters]] item in other +all verification [[ref: multikeys]] in the `updateKeys` [[ref: parameters]] property in other than the initial version of the [[ref: DIDDoc]] **MUST** have their hash in the currently active nextKeyHashes` array from a previous [[ref: DID log entry]]. If not, terminate the resolution process with an error. @@ -838,11 +838,11 @@ authorization key. 4. `base58btc` is an implementation of the [[ref: base58btc]] function. Its output is the base58 encoded string of its input. 4. Insert the calculated hash into the `nextKeyHashes` array being built up within - the [[ref: parameters]] item. + the [[ref: parameters]] property. 5. 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 [[ref: multikey]] representation of the public key will be inserted into the - `updateKeys` item in the [[ref: parameters]]. After that [[ref: log entry]] is + `updateKeys` property in the [[ref: parameters]]. After that [[ref: log entry]] is published, the private key can be used to sign DID update authorizations proofs. @@ -852,7 +852,7 @@ strings) in a `nextKeyHashes` array. When processing other than the first [[ref: DID log entry]] where the `prerotation` [[ref: parameter]] is active, a `did:tdw` resolver **MUST**: -1. For each [[ref: multikey]] in the `updateKeys` item in the `parameters` of +1. For each [[ref: multikey]] in the `updateKeys` property in the `parameters` of the [[ref: log entry]], calculate the hash and hash algorithm for the [[ref: mulithash]] [[ref: multikey]]. 2. The hash algorithm **MUST** be one listed in the @@ -911,7 +911,7 @@ An overview of the [[ref: witness]] mechanism is as follows: witness]] sends a [[ref: Data Integrity]] proof across the [[ref: DID log entry]] to the [[ref: DID Controller]], similar to that generated by the [[ref: DID Controller]], but signed by the [[ref: witness]]'s key. - When a weighted threshold of proofs are received, the DID Controller - inserts the [[ref: witnesses]]'s proofs into the array of proofs that are the last item in + inserts the [[ref: witnesses]]'s proofs into the `proof` array in the [[ref: DID Log Entry]] and publishes the updated version of the [[ref: DID Log]]. - In publishing a new version of the [[ref: DID Log]], the [[ref: DID @@ -920,7 +920,7 @@ An overview of the [[ref: witness]] mechanism is as follows: proofs on the last [[ref: log entry]] are needed because of the chaining of the proofs via the use of the `entryHash` challenge. - Removing the prior entry [[ref: witness]] proofs does not affect the verifiability of - the DID because the `entryHash` calculation does not include the proofs item. + the DID because the `entryHash` calculation does not include the `proof` property. - The specification leaves to implementers how the proofs are conveyed to the [[ref: DID Controller]]. @@ -938,7 +938,7 @@ change must be approved by the *prior* [[ref: witnesses]]. For the first entry in the [[ref: DID Log]], the [[ref: witnesses]] listed in that entry must approve the version, since there are no "prior" [[ref: witnesses]]. -The data object for the `witness` [[ref: parameters]] item is as follows. +The data model for the `witness` [[ref: parameter]] is as follows. The threshold design borrows from the [[ref: verifiable conditions]] specification. diff --git a/spec/version.md b/spec/version.md index da8166d..ad51e1f 100644 --- a/spec/version.md +++ b/spec/version.md @@ -5,8 +5,7 @@ The following lists the substantive changes in each version of the specification - Version 0.4 - Removes the use of JSON Patch from the specification. The full DIDDoc is included in each [[ref: DID log entry]]. - Changes the data format of the [[ref: DID log entries]] from an array to an object. The [[ref: DID Log]] remains in the [[ref: JSON Lines]] format. - - Change the data format of the Data Integrity Proof from an array to an object - - Changes the array items to be named JSON objects. + - Changes the array items to be named JSON objects or properties. - Makes each DID version's [[ref: Data Integrity]] proof apply across the JSON [[ref: DID log entry]] object, as is typical with [[ref: DID Integrity Proofs]]. Previously, the [[ref: Data Integrity]] proof was generated across From 5937e08ebe26372b329d6d5358fb26084fb9ef69 Mon Sep 17 00:00:00 2001 From: Stephen Curran Date: Fri, 27 Sep 2024 11:31:57 -0700 Subject: [PATCH 5/7] More item removals Signed-off-by: Stephen Curran --- spec/definitions.md | 2 +- spec/example.md | 8 ++++---- spec/implementors_guide.md | 4 ++-- spec/version.md | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/definitions.md b/spec/definitions.md index 80f7f63..5b78c6e 100644 --- a/spec/definitions.md +++ b/spec/definitions.md @@ -30,7 +30,7 @@ by the controller of the DID. [[def: DID Log, DID Logs]] -~ A DID Log is a list of [[ref: Entries]] one being added for each update of an entry item, +~ A DID Log is a list of [[ref: Entries]], with an entry added for each update of the DID, including new versions of the [[ref: DIDDoc]] or changed information necessary to generate or validate the DID. [[def: DID Log Entry, DID Log Entries, Entries, Log Entries]] diff --git a/spec/example.md b/spec/example.md index 8097c1c..4bf9b56 100644 --- a/spec/example.md +++ b/spec/example.md @@ -24,7 +24,7 @@ particularly boring, containing the absolute minimum for a valid [[ref: DIDDoc]] This example includes both the initial "authorized keys" to sign the [[ref: Data Integrity]] proof (`updateKeys`) and the [[ref: pre-rotation]] commitment to the next authorization keys (`nextKeyHashes`). Both -are in the `parameters` item in the [[ref: log entry]]. +are in the `parameters` property in the [[ref: log entry]]. ```json { @@ -176,9 +176,9 @@ processing is done to create the new [[ref: DID log entry]]: - The `parameters` entry passed in is processed. In this case, since the `updateKeys` array is updated, and [[ref: pre-rotation]] is active, the a verification is done to ensure that the hash of the `updateKeys` entries are -found in the `nextKeyHashes` item from version 1 of the DID. As required by the +found in the `nextKeyHashes` property from version 1 of the DID. As required by the `did:tdw` specification, a new `nextKeyHashes` is included in the new `parameters`. -- The new (but unchanged) [[ref: DIDDoc]] is included in its entirety, as the value of the `state` item. +- The new (but unchanged) [[ref: DIDDoc]] is included in its entirety, as the value of the `state` property. - The resultant JSON object is passed into the [`entryHash` generation process](#entry-hash-generation-and-verification) which outputs the `entryHash` for this [[ref: log entry]]. Once again, the `versionId` value is @@ -196,7 +196,7 @@ The following is the JSON pretty-print [[ref: log entry]] for the second version the first [[ref: log entry]], since the `updateKeys` change in the second [[ref: log entry]] does not take affect until _after_ the version update is complete. -- A new `updateKeys` item in the `parameters` has been added, along with +- A new `updateKeys` property in the `parameters` has been added, along with commitment to a future key (`nextKeyHashes`) that will control future updates to the DID. diff --git a/spec/implementors_guide.md b/spec/implementors_guide.md index 32cd518..68bee42 100644 --- a/spec/implementors_guide.md +++ b/spec/implementors_guide.md @@ -47,11 +47,11 @@ private keys both DID control keys would be lost. Thus, we expect the feature to - When a key rotation is to be done, two [[ref: entries]] are put in the log, using the following steps by the [[ref: DID Controller]]: 1. Get the full key reference entry from the isolated service for the [[ref: pre-rotation]] "nextKey". 2. Locally generate a [[ref: pre-rotation]] key hash for a new key that will soon become the "active" key. - 3. Add a [[ref: 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). + 3. Add a [[ref: DID log]] entry that includes the properties from the previous two steps, and signs the proof using an authorized key (that presumably it controls, though not required). 1. Although the [[ref: 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. 4. Get a new [[ref: pre-rotation]] hash from the isolated service. 5. Get the full key-rotation key reference for the [[ref: pre-rotation]] hash created for the last [[ref: DID log entry]]. - 6. Add a [[ref: DID Log]] entry that includes the items from the previous two step + 6. Add a [[ref: DID Log]] entry that includes the properties from the previous two step 7. If the key rotated in the previous [[ref: DID log entry]] was a/the authorized key to make updates to the DID, call the isolated service to produce the [[ref: Data Integrity]] proof over the entry using the key the isolated diff --git a/spec/version.md b/spec/version.md index ad51e1f..c3eeda1 100644 --- a/spec/version.md +++ b/spec/version.md @@ -5,7 +5,7 @@ The following lists the substantive changes in each version of the specification - Version 0.4 - Removes the use of JSON Patch from the specification. The full DIDDoc is included in each [[ref: DID log entry]]. - Changes the data format of the [[ref: DID log entries]] from an array to an object. The [[ref: DID Log]] remains in the [[ref: JSON Lines]] format. - - Changes the array items to be named JSON objects or properties. + - Changes the [[ref: DID log entry]] array to be named JSON objects or properties. - Makes each DID version's [[ref: Data Integrity]] proof apply across the JSON [[ref: DID log entry]] object, as is typical with [[ref: DID Integrity Proofs]]. Previously, the [[ref: Data Integrity]] proof was generated across From db042743671050a00035036111365500da39559c Mon Sep 17 00:00:00 2001 From: Stephen Curran Date: Fri, 27 Sep 2024 21:46:17 -0700 Subject: [PATCH 6/7] Added that the versionTime timestamp MUST be UTC time Signed-off-by: Stephen Curran --- spec/specification.md | 12 ++++++------ spec/version.md | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/spec/specification.md b/spec/specification.md index 4105539..e8eef79 100644 --- a/spec/specification.md +++ b/spec/specification.md @@ -153,7 +153,7 @@ Each entry is a JSON object consisting of the following properties. [Entry Hash Generation and Verification](#entry-hash-generation-and-verification) section of this specification. -2. The value of `versionTime` **MUST** be a timestamp of the entry in [[ref: +2. The value of `versionTime` **MUST** be a timestamp in UTC of the entry in [[ref: ISO8601]] format, as asserted by the [[ref: DID Controller]]. The timestamp **MUST** be the time the DID will be retrieved by a [[ref: witness]] or resolver, or before. @@ -235,7 +235,7 @@ Creating a `did:tdw` DID is done by carrying out the following steps. without the `proof`. 1. The value of `versionId` string **MUST** be the placeholder literal `"{SCID}"`. - 2. The value of `versionTime` string **MUST** be a valid [[ref: ISO8601]] date/time string, + 2. The value of `versionTime` string **MUST** be a valid UTC [[ref: ISO8601]] date/time string, and the represented time **MUST** be before or equal to the current time. 3. The value of the `parameters` property **MUST** be a JSON object defined at the discretion of the [[ref: DID Controller]]. The properties in this nested JSON object @@ -358,7 +358,7 @@ For each entry: the process defined in the [Entry Hash Generation and Verification](#entry-hash-generation-and-verification) section of this specification. -4. The `versionTime` **MUST** be a valid [[ref: ISO8601]] date/time string. The +4. The `versionTime` **MUST** be a valid UTC [[ref: ISO8601]] date/time string. The `versionTime` for each [[ref: log entry]] **MUST** be greater than the previous entry's time. The `versionTime` of the last entry **MUST** be earlier than the current time. @@ -384,7 +384,7 @@ For each entry: about each version: 1. The [[ref: DIDDoc]]. 2. The `versionId` of the [[ref: DIDDoc]]. - 3. The `versionTime`of the [[ref: DIDDoc]]. + 3. The UTC `versionTime`of the [[ref: DIDDoc]]. 4. The latest list of active [[ref: multikey]] formatted public keys authorized to update the DID, from the `updateKeys` lists in the [[ref: parameters]]. @@ -452,7 +452,7 @@ verifiable [[ref: DID Log Entry]] follows a similar process to the 3. Generate a preliminary [[ref: DID log entry]] JSON object containing the following properties: 1. The value of `versionId` **MUST** be the value of `versionId` from the *previous* [[ref: DID log entry]]. 2. The `versionTime` value **MUST** be a string that is an [[ref: ISO8601]] - format timestamp. The time **MUST** be greater than the time of the + format UTC timestamp. The time **MUST** be greater than the time of the previous [[ref: log entry]], and **MUST** be the time the DID will be retrieved by a [[ref: witness]] or resolver, or before. 3. The [[ref: parameters]] passed in as a JSON object. @@ -646,7 +646,7 @@ Where: - The `versionId` entry, which **MUST** be `{SCID}`. - The `versionTime` entry, which **MUST** be a string that is the current time in - [[ref: ISO8601]] format, e.g., `"2024-04-05T07:32:58Z"` + UTC [[ref: ISO8601]] format, e.g., `"2024-04-05T07:32:58Z"` - The complete `parameters` for the initial [[ref: log entry]] as defined by the [[ref: DID Controller]], with the placeholder wherever the [[ref: SCID]] will eventually be placed. diff --git a/spec/version.md b/spec/version.md index c3eeda1..c801f6c 100644 --- a/spec/version.md +++ b/spec/version.md @@ -10,6 +10,7 @@ The following lists the substantive changes in each version of the specification [[ref: DID log entry]] object, as is typical with [[ref: DID Integrity Proofs]]. Previously, the [[ref: Data Integrity]] proof was generated across the current DIDDoc version, with the `versionId` as the challenge. + - Specified that the `versionTime` must be recorded as a UTC time zone timestamp. - Version 0.3 - Removes the `cryptosuite` [[ref: parameter]], moving it to implied based on the `method` [[ref: parameter]]. - Change base32 encoding with [[ref: base58btc]], as it offers a better expansion rate. From 034954fe57534317ad307ebac53b7c9ac179b444 Mon Sep 17 00:00:00 2001 From: Stephen Curran Date: Wed, 2 Oct 2024 10:49:15 -0700 Subject: [PATCH 7/7] Fixes based on feedback Signed-off-by: Stephen Curran --- spec/overview.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/overview.md b/spec/overview.md index 06f8f3f..478df90 100644 --- a/spec/overview.md +++ b/spec/overview.md @@ -67,11 +67,11 @@ The following is a `tl;dr` summary of how `did:tdw` works: `-`, and a hash of the entry. The [[ref: entry hash]] calculation links each entry to its predecessor in a ledger-like chain. 2. `versionTime` -- as asserted by the [[ref: DID Controller]]. - 3. A set of `parameters` that impact the processing of the current and + 3. `parameters` -- a set of [[ref: parameters]] that impact the processing of the current and future [[ref: log entries]]. - Example [[ref: parameters]] are the version of the `did:tdw` specification and hash algorithm being used as well as the [[ref: SCID]] and update key(s). - 4. The `state`, the new version of the [[ref: DIDDoc]]. + 4. `state` -- the new version of the [[ref: DIDDoc]]. 5. A [[ref: Data Integrity]] (DI) proof across the entry, signed by a [[ref: DID Controller]] authorized key to update the [[ref: DIDDoc]], and optionally, a set of witnesses that monitor the actions of the DID Controller. @@ -84,20 +84,20 @@ The following is a `tl;dr` summary of how `did:tdw` works: it where needed in the initial (and all subsequent) DIDDocs. The [[ref: SCID]] enables an optional [[ref: portability]] capability, allowing a DID's web location to be moved, while retaining the DID and version history of the DID. -5. A [[ref: DID Controller]] generates and publishes the new/updated [[ref: DID Log]] file by making it +1. A [[ref: DID Controller]] generates and publishes the new/updated [[ref: DID Log]] file by making it available at the appropriate location on the web, based on the identifier of the DID. -6. Given a `did:tdw` DID, a resolver converts the DID to an HTTPS URL, +1. Given a `did:tdw` DID, a resolver converts the DID to an HTTPS URL, retrieves, and processes the [[ref: DID Log]] `did.jsonl`, generating and verifying each [[ref: log entry]] as per the requirements outlined in this specification. - In the process, the resolver collects all the [[ref: 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. -7. `did:tdw` DID URLs with paths and `/whois` are resolved to documents +1. `did:tdw` DID URLs with paths and `/whois` are resolved to documents published by the [[ref: DID Controller]] that are by default in the web location relative to the `did.jsonl` file. See the [note below](#the-whois-use-case) about the powerful capability enabled by the `/whois` DID URL path. -8. Optionally, a [[ref: DID Controller]] can easily generate and publish a `did:web` DIDDoc +1. Optionally, a [[ref: DID Controller]] can easily generate and publish a `did:web` DIDDoc from the latest `did:tdw` [[ref: DIDDoc]] in parallel with the `did:tdw` [[ref: DID Log]]. ::: warning