diff --git a/normcheck.sh b/normcheck.sh new file mode 100755 index 0000000..41082c4 --- /dev/null +++ b/normcheck.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Define normative keywords +keywords="MUST|MUST NOT|REQUIRED|SHALL|SHALL NOT|SHOULD|SHOULD NOT|RECOMMENDED|NOT RECOMMENDED|MAY|OPTIONAL" + +# Iterate over all files in the spec directory +for file in $(find spec -type f); do + # Read the file line by line + while IFS= read -r line; do + # Check if the line contains a normative keyword and does not start with '1. ' (allowing whitespace prefixes) + echo "$line" | awk -v file="$file" -v keywords="$keywords" '( $0 ~ keywords ) && !( $0 ~ /^[[:space:]]*1. / ) {print "Missing line number: File: " file ", Line: " FNR ", Text: " $0}' + echo "$line" | awk -v file="$file" -v keywords="$keywords" '( $0 ~ /^[[:space:]]*[0-9]+. / ) && !( $0 ~ keywords ) {print "Missing keyword: File: " file ", Line: " FNR ", Text: " $0}' + done < "$file" +done \ No newline at end of file diff --git a/spec/appendix.md b/spec/appendix.md index 6b225ba..351a12a 100644 --- a/spec/appendix.md +++ b/spec/appendix.md @@ -16,7 +16,7 @@ [[def: verifiable identifier (VID), VID, VIDs]] ~ An identifier over which the controller can provide cryptographic proof of control. -See also: decentralized identifier, [ref: self-certifying identifier (SCID)]. +See also: decentralized identifier, [[ref: self-certifying identifier (SCID)]]. ### Terminology @@ -43,7 +43,7 @@ See also: decentralized identifier, [ref: self-certifying identifier (SCID)]. ~ A globally unique persistent identifier, as defined by [DID Core](https://www.w3.org/TR/did-core/#dfn-decentralized-identifiers). [[def: designated aliases, designated alias]] -~ An array of [[ref:AID controlled identifiers]] that have been designated by the AID controller to be used as aliases for `equivalentId` and `alsoKnownAs` DID document metadata and to foster verification of redirection to different did:webs identifiers. See [WebOfTrust glossary](https://github.com/WebOfTrust/WOT-terms/wiki/designated-aliases) for more detail. +~ An array of [[ref: AID controlled identifiers]] that have been designated by the AID controller to be used as aliases for `equivalentId` and `alsoKnownAs` DID document metadata and to foster verification of redirection to different did:webs identifiers. See [WebOfTrust glossary](https://github.com/WebOfTrust/WOT-terms/wiki/designated-aliases) for more detail. [[def: DID document, DID documents]] ~ A set of data describing the subject of a [[ref: DID]], as defined by [DID Core](https://www.w3.org/TR/did-core/#dfn-did-documents). See also section [DID Documents](#did-documents). diff --git a/spec/core.md b/spec/core.md index a942562..c3df7d6 100644 --- a/spec/core.md +++ b/spec/core.md @@ -1,22 +1,20 @@ ## Core Characteristics +This section is normative. ### Method Name 1. The method name that identifies this DID method SHALL be: `webs`. 1. A DID that uses this method MUST begin with the following prefix: `did:webs:`. 1. Per the DID specification, this string MUST be lower case. -1. The remainder of the DID, after the prefix, is the case-sensitive [[ref: method-specific identifier]] +1. The remainder of the DID, after the prefix, MUST be the case-sensitive [[ref: method-specific identifier]] ([[ref: MSI]]) described [below](#method-specific-identifier). -> Note: when pronounced aloud, “webs” SHOULD become two syllables: the word “web” and the letter “s” (which stands for “secure”). Separating the final letter this way emphasizes that the method offers a security upgrade surpassing the one HTTPS gives to HTTP. +> Note: when pronounced aloud, “webs” should become two syllables: the word “web” and the letter “s” (which stands for “secure”). Separating the final letter this way emphasizes that the method offers a security upgrade surpassing the one HTTPS gives to HTTP. ### Method-Specific Identifier -1. The `did:webs` [[ref: method-specific identifier]] has two -parts, a [[ref: host]] with an optional path (identical to -`did:web`), plus a KERI AID (autonomic identifier) that is always the final -component of the path. -1. The [[ref: ABNF]] definition of a `did:webs` DID is as follows: +1. The `did:webs` [[ref: method-specific identifier]] MUST have two parts, a [[ref: host]] with an optional path (identical to `did:web`), plus a KERI AID (autonomic identifier) that is always the final component of the path. +1. The [[ref: ABNF]] definition of a `did:webs` DID MUST be as follows: ```abnf webs-did = "did:webs:" host [pct-encoded-colon port] *(":" path) ":" aid @@ -42,32 +40,30 @@ component of the path. ; ALPHA, DIGIT are standard ABNF primitives for alphabetic and numeric characters ``` -1. The formal rules describing valid [[ref: host]] syntax are described in [RFC1035], [RFC1123], and [RFC2181]. +1. The [[ref: host]] MUST abide by the formal rules describing valid syntax found in [[ref: RFC1035]], [[ref: RFC1123]], and [[ref: RFC2181]]. 1. A port MAY be included and the colon MUST be percent encoded, like `%3a`, to prevent a conflict with paths. 1. Directories and subdirectories MAY optionally be included, delimited by colons rather than slashes. - 1. The KERI AID is a unique identifier and MUST be derived from the inception event of a KERI identifier. > The inception event is the first item in the identifier's [[ref: KEL]]. The algorithm used to generate the AID depends on the type of AID. If the AID is transferable (supports key rotation) then the AID is generated by taking a cryptographic digest of the inception event of the KEL of the AID. If the AID is non-transferable (does not support key rotation) the AID is generated by taking a cryptographic digest of the first (and only) public key of the identifier. See the [[ref: KERI Fundamentals]] section for more details. -> After the [[ref: host]] and optional path in a `did:webs` is a final path component, a colon and the AID. To be compatible with `did:web`, the AID is "just a path", the final (and perhaps only) path element. The presence of the required AID as a path element means that a `did:webs` always has a path,and so the "no path" version of a `did:web` that implicitly uses the `.well-known` folder is not supported by `did:webs`. Any `did:webs` can be expressed as a `did:web` but the inverse is not true--a `did:webs` MUST include an AID. +> To be compatible with `did:web`, the AID is "just a path", the final (and perhaps only) path element. The presence of the required AID as a path element means that a `did:webs` always has a path,and so the "no path" version of a `did:web` that implicitly uses the `.well-known` folder is not supported by `did:webs`. Any `did:webs` can be expressed as a `did:web` but the inverse is not true--a `did:webs` must include an AID. ### Target System(s) 1. As with `did:web`, `did:webs` MUST read data from whatever web server is referenced when the [[ref: host]] portion of one of its DID is resolved. 1. A `did:webs` DID MUST resolve to a [[ref: DID document]] using a simple text transformation to an HTTPS URL in the same way as a `did:web` DID. -1. A `did:web` DID and `did:webs` DID with the same [[ref: method-specific identifier]] will return the same -DID document, except for minor differences in the `id`, `controller`, and `alsoKnownAs` top-level properties that pertain to the identifiers themselves. +1. A `did:web` DID and `did:webs` DID with the same [[ref: method-specific identifier]] SHOULD return the same DID document, except for minor differences in the `id`, `controller`, and `alsoKnownAs` top-level properties that pertain to the identifiers themselves. 1. As with `did:web`, the location of the [[ref: DID document]] MUST be determined by transforming the DID to an HTTPS URL as follows: - 1. Replace `did:webs` with `https://` - 1. Replace the "`:`"s in the method-specific identifier with path separators, "'/'"s - 1. Convert the optional port percent encoding ("`%3A`"`) to a colon if present. - 1. Append "`/did.json`" to the resulting string. + 1. MUST replace `did:webs` with `https://` + 1. MUST replace the "`:`"s in the method-specific identifier with path separators, "'/'"s + 1. MUST convert the optional port percent encoding ("`%3A`"`) to a colon if present. + 1. MUST append "`/did.json`" to the resulting string. 1. A GET on that URL MUST return the DID document. -1. The location of the [[ref: KERI event stream]] is determined by transforming the previous URL as follows: - 1. Replace the trailing "`/did.json`" with "`/keri.cesr`". +1. The location of the [[ref: KERI event stream]] MUST be determined by transforming the previous URL as follows: + 1. MUST replace the trailing "`/did.json`" with "`/keri.cesr`". 1. A GET on that URL MUST return the [[ref: KERI event stream]] for the AID in the `did:webs` identifier. 1. The [[ref: KERI event stream]] MUST be [[ref: CESR]]-formatted (media type of application/cesr) and the KERI events must be verifiable using the KERI rules. -1. The `did:web` version of the DIDs are the same (minus the `s`) and point to the same `did.json` file, but have no knowledge of the `keri.cesr` file. +1. The `did:web` version of the DIDs MUST be the same (minus the `s`) and point to the same `did.json` file, but have no knowledge of the `keri.cesr` file. > The set of KERI features needed for most `did:webs` use cases is modest, with limited dependencies. These basics are summarized in the [KERI Fundamentals](#keri-fundamentals) section of this specification. This specification assumes a working knowledge of the concepts there. The inclusion of KERI in `did:webs` enables a number of capabilities for securing a `did:webs` identifier, including multi-signature support and the creation of [[ref: pre-rotated]] keys to prevent loss of control of the identifier if the current private key were to be compromised. @@ -88,36 +84,40 @@ URLs, based on the examples from the [[ref: did:web Specification]], but with th ### AID controlled identifiers -This section is non-normative. +1. [[ref: AID controlled identifiers]] MAY vary in how quickly they reflect the current identity information, DID document and [[ref: KERI event stream]]. Notably, as defined in section [Identifiers in a `did:webs` DID document](#identifiers-in-a-didwebs-did-document), the `id` property in the DID document will differ based on the web location of the DID document. +1. Different versions of the DID document and [[ref: KERI event stream]] MAY reside in different locations depending on the replication capabilities of the controlling entity. +1. If the [[ref: KERI event streams]] differ for `did:webs` DIDs with the same AID, the smaller [[ref: KERI event stream]] MUST be a prefix of the larger [[ref: KERI event stream]] (e.g., the only difference in the [[ref: KERI event streams]] being the extra events in one of the [[ref: KERI event streams]], not yet reflected in the other). +1. If the [[ref: KERI event streams]] diverge from one other (e.g., one is not a subset of the other), both the [[ref: KERI event streams]] and the DIDs MUST be considered invalid. +1. The verification of the [[ref: KERI event stream]] SHOULD provide mechanisms for detecting the forking of the [[ref: KERI event stream]] by using mechanisms such as KERI witnesses and watchers. -> Since an AID is a unique cryptographic identifier that is inseparably bound to the [[ref: KERI event stream]] it is associated with, any AIDs and any `did:webs` DIDs that have the same AID component have the same controller(s). [[ref: AID controlled identifiers]] may vary in how quickly they reflect the current identity information, DID document and [[ref: KERI event stream]]. Notably, as defined in section [Identifiers in a `did:webs` DID document](#identifiers-in-a-didwebs-did-document), the `id` property in the DID document will differ based on the web location of the DID document. As well, different versions of the DID document and [[ref: KERI event stream]] may reside in different locations depending on the replication capabilities of the controlling entity. If the [[ref: KERI event streams]] differ for `did:webs` DIDs with the same AID, the smaller [[ref: KERI event stream]] MUST be a prefix of the larger [[ref: KERI event stream]] (e.g., the only difference in the [[ref: KERI event streams]] being the extra events in one of the [[ref: KERI event streams]], not yet reflected in the other). If the [[ref: KERI event streams]] diverge from one other (e.g., one is not a subset of the other), both the [[ref: KERI event streams]] and the DIDs MUST be considered invalid. +> Since an AID is a unique cryptographic identifier that is inseparably bound to the [[ref: KERI event stream]] it is associated with any AIDs and any `did:webs` DIDs that have the same AID component. It can be verifiably proven that they have the same controller(s). > The web supports a number of ways to redirect users. See the section on [Handling Web Redirections](#handling-web-redirection) later in this specification. -> KERI anticipates the possibility of a duplicitous actor with an AID that forks a [[ref: KERI event stream]] and shares different versions of the [[ref: KERI event stream]] containing different events, such as publishing different versions of the [[ref: KERI event stream]] on different web servers. The verification of the [[ref: KERI event stream]] MAY provide mechanisms for detecting such behavior, such as KERI witnesses and watchers. +> KERI anticipates the possibility of a duplicitous actor with an AID that forks a [[ref: KERI event stream]] and shares different versions of the [[ref: KERI event stream]] containing different events, such as publishing different versions of the [[ref: KERI event stream]] on different web servers. ### Handling Web Redirection 1. A `did:webs` MAY be a "stable" (long-lasting) identifier that can be put into documents such as verifiable credentials, to be useful for a very long time -- generations. -1. When a `did:webs` is updated for another location: +1. When a `did:webs` is updated for another location the following rules MUST apply: 1. Its AID MUST not change. 1. The same [[ref: KERI event stream]] MUST be used to verify the DID document, with the only change being the designated aliases list reflecting the new location identifier. - 1. If a resolver can find a newly named DID that uses the same AID, and the [[ref: KERI event stream]] verifies the DID, then they have resolved the DID. + 1. If a resolver can find a newly named DID that uses the same AID, and the [[ref: KERI event stream]] verifies the DID, then the resolver MAY consider the resolution to be successful and should note it in the resolution metadata. -The following reslution paths that `did:webs` identfiers SHALL leverage to help in the face of resolution uncertainty: -1. The `did:webs` DID SHALL provide other [[ref: designated aliases]] DID(s) that are anchored to the [[ref: KERI event stream]]. -1. When a `did:webs` is permanently moved to some other location the resolver MAY redirect to any other `equivalentId` [[ref: designated aliases]]. - 1. The `id` in the DID document MUST be set to the new location. - 1. An `equivalentId` entry of the old location SHOULD remain for historical purposes and anchored to the [[ref: KERI event stream]] using [[ref: designated aliases]]. See section [Use of `equivalentId`](#use-of-equivalentid) for more details. - 1. If possible, the controller of the DID MAY use web redirects to allow resolution of the old location of the DID to the new location. +1. The following resolution paths that `did:webs` identfiers SHALL leverage to help in the face of resolution uncertainty: + 1. The `did:webs` DID SHALL provide other [[ref: designated aliases]] DID(s) that are anchored to the [[ref: KERI event stream]]. + 1. When a `did:webs` is permanently moved to some other location the resolver MAY redirect to any other `equivalentId` [[ref: designated aliases]]. + 1. The `id` in the DID document MUST be set to the new location. + 1. An `equivalentId` entry of the old location SHOULD remain for historical purposes and anchored to the [[ref: KERI event stream]] using [[ref: designated aliases]]. See section [Use of `equivalentId`](#use-of-equivalentid) for more details. + 1. If possible, the controller of the DID MAY use web redirects to allow resolution of the old location of the DID to the new location. + 1. If the previously published location of a `did:webs` is not redirected, an entity trying to resolve the DID MAY be able to find the data for the DID somewhere else using just the AID. > The web is not a very stable place, and documents are moved around and copied frequently. When two or more companies merge, often the web presence of some of the merged entities "disappears". It may not be possible to retain a permanent `did:webs` web location. > The purpose of the history of [[ref: designated aliases]] for the AID is so that if the `did:webs` DID has been put in long-lasting documents, and its URL instantiation is redirected or disappears, the controller can explicitly indicate that the new DID is an `equivalentId` to the old one. -> If the previously published location of a `did:webs` is not redirected, an entity trying to resolve the DID MAY be able to find the data for the DID somewhere else using just the AID. Since the AID is globally unique and -references the same identifier, regardless of the rest of the string that is the full `did:webs`, web searching could yield either the current location of the DID document, or a copy of the DID that may be useful. For example, even the [Internet Archive: Wayback Machine](https://archive.org/web) could be used to find a copy of the DID document and the [[ref: KERI event stream]] at some point in the past that may be sufficient for the purposes of the entity trying to resolve the DID. This specification does not rely on the Wayback Machine, but it might be a useful `did:webs` discovery tool. +> Since the AID is globally unique and references the same identifier, regardless of the rest of the string that is the full `did:webs`, web searching could yield either the current location of the DID document, or a copy of the DID that may be useful. For example, even the [Internet Archive: Wayback Machine](https://archive.org/web) could be used to find a copy of the DID document and the [[ref: KERI event stream]] at some point in the past that may be sufficient for the purposes of the entity trying to resolve the DID. This specification does not rely on the Wayback Machine, but it might be a useful `did:webs` discovery tool. > The DID document, [[ref: KERI event stream]] and other files related to a DID may be copied to other web locations. For example, someone might want to keep a cache of DIDs they use, or an entity might want to run a registry of "useful" DIDs for a cooperating group. While the combination of DID document and [[ref: KERI event stream]] make the DID and DID document verifiable, just as when published in their "intended" location, the absence of the `did:webs` in the [[ref: designated aliases]] for those locations in the DID document `equivalentId` means that the controller of the DID is not self-asserting any sort of tie between the DID and the location to which the DID-related documents have been copied. In contrast, if the controller confirms the link between the source and the copy with an `equivalentId`, the related copies will have to be kept in sync. @@ -129,13 +129,13 @@ references the same identifier, regardless of the rest of the string that is the #### Create -Creating a `did:webs` DID involves the following steps: -1. Choose the web URL where the DID document for the DID will be published, excluding the last element that will be the AID, once defined. -1. Create a KERI AID and add it as the last element of the web URL for the DID. -1. Add the appropriate KERI events to the AID's KERI logs that will correspond to properties of the DID document, such as verification methods and service endpoints. -1. Derive the `did:webs` [[ref: DID document]] by processing the [[ref: KERI event stream]] according to section [DID Document from KERI Events](#did-document-from-keri-events). -1. For compatibility reasons, transform the derived `did:webs` DID document to the corresponding `did:web` DID document according to section [Transformation to did:web DID Document](#transformation-to-didweb-did-document). -1. Create the AID folder on the web server at the selected location, and place the `did:web` DID document resource (`did.json`) and the [[ref: KERI event stream]] resource (`keri.cesr`) into that folder. See section [Target System(s)](#target-systems) for further details about the locations of these resources. +1. Creating a `did:webs` DID MUST follow these rules: + 1. MUST choose the web URL where the DID document for the DID will be published, excluding the last element that will be the AID, once defined. + 1. MUST create a KERI AID and add it as the last element of the web URL for the DID. + 1. MUST add the appropriate KERI events to the AID's KERI logs that will correspond to properties of the DID document, such as verification methods and service endpoints. + 1. MUST derive the `did:webs` [[ref: DID document]] by processing the [[ref: KERI event stream]] according to section [DID Document from KERI Events](#did-document-from-keri-events). + 1. For compatibility reasons, transformation of the derived `did:webs` DID document to the corresponding `did:web` DID document MUST be according to section [Transformation to did:web DID Document](#transformation-to-didweb-did-document). + 1. MUST create the AID folder on the web server at the selected location, and place the `did:web` DID document resource (`did.json`) and the [[ref: KERI event stream]] resource (`keri.cesr`) into that folder. See section [Target System(s)](#target-systems) for further details about the locations of these resources. > Of course, the web server that serves the resources when asked might be a simple file server (as implied above) or an active component that generates them dynamically. Further, the publisher of the resources placed on the web can use capabilities like [CDNs] to distribute the resources. How the resources are posted at the required location is not defined by this spec; complying implementations need not support any HTTP methods other than GET. @@ -143,14 +143,15 @@ Creating a `did:webs` DID involves the following steps: #### Read (Resolve) -Resolving a `did:webs` DID must follow these steps: -1. Convert the `did:webs` DID back to HTTPS URLs as described in section [Target System(s)](#target-systems). -1. Execute HTTP GET requests on both the URL for the DID document (ending in `/did.json`) and the URL for the [[ref: KERI event stream]] (ending in `/keri.cesr`). -1. Process the [[ref: KERI event stream]] using [KERI Rules] to verify it, then derive the `did:webs` [[ref: DID document]] by processing the [[ref: KERI event stream]] according to section [DID Document from KERI Events](#did-document-from-keri-events). -1. Transform the retrieved `did:web` DID document to the corresponding `did:webs` DID document according to section [Transformation to did:webs DID Document](#transformation-to-didwebs-did-document). -1. Verify that the derived `did:webs` DID document equals the transformed DID document. +1. Resolving a `did:webs` DID MUST follow these steps: + 1. MUST convert the `did:webs` DID back to HTTPS URLs as described in section [Target System(s)](#target-systems). + 1. MUST execute HTTP GET requests on both the URL for the DID document (ending in `/did.json`) and the URL for the [[ref: KERI event stream]] (ending in `/keri.cesr`). + 1. MUST process the [[ref: KERI event stream]] using [KERI Rules] to verify it, then derive the `did:webs` [[ref: DID document]] by processing the [[ref: KERI event stream]] according to section [DID Document from KERI Events](#did-document-from-keri-events). + 1. MUST transform the retrieved `did:web` DID document to the corresponding `did:webs` DID document according to section [Transformation to did:webs DID Document](#transformation-to-didwebs-did-document). + 1. MUST verify that the derived `did:webs` DID document equals the transformed DID document. + 1. KERI-aware applications MAY use the [[ref: KERI event stream]] to make use of additional capabilities enabled by the use of KERI. -> KERI-aware applications MAY use the [[ref: KERI event stream]] to make use of additional capabilities enabled by the use of KERI. Capabilities beyond the verification of the DID document and [[ref: KERI event stream]] are outside the scope of this specification. +> Capabilities beyond the verification of the DID document and [[ref: KERI event stream]] are outside the scope of this specification. #### Update @@ -162,5 +163,5 @@ the [[ref: KERI event stream]]. #### Deactivate 1. To deactivate a `did:webs` DID, A controller SHOULD execute a KERI event that has the effect of rotating the key(s) to null and continue to publish the DID document and [[ref: KERI event stream]]. - 1. Once the deactivation events have been applied, the controller should regenerate the DID document from the [[ref: KERI event stream]] and republish both documents (did.json and keri.cesr) to the web server, overwriting the existing files. + 1. Once the deactivation events have been applied, the controller SHOULD regenerate the DID document from the [[ref: KERI event stream]] and republish both documents (did.json and keri.cesr) to the web server, overwriting the existing files. 1. A controller SHOULD NOT remove the DID folder and files from the web server on which it has been published. This is considered to be a bad approach, as those resolving the DID will not be able to determine if the web service is offline or the DID has been deactivated. \ No newline at end of file diff --git a/spec/did_metadata.md b/spec/did_metadata.md index d7725d3..ffa80b8 100644 --- a/spec/did_metadata.md +++ b/spec/did_metadata.md @@ -1,10 +1,11 @@ ## DID Metadata +This section is normative. This section describes the support of the `did:webs` method for metadata, including [[ref: DID resolution metadata]] and [[ref: DID document metadata]]. This metadata is returned by a DID Resolver in addition to the DID document. Also see the [DID Resolution](https://w3c-ccg.github.io/did-resolution/) specification for further details. ### DID Resolution Metadata -At the moment, this specification does not define the use of any specific [[ref:DID resolution metadata]] properties in the `did:webs` method, but may in the future include various metadata, such as which KERI Watchers were used during the resolution process. +At the moment, this specification does not define the use of any specific [[ref: DID resolution metadata]] properties in the `did:webs` method, but may in the future include various metadata, such as which KERI Watchers were used during the resolution process. ### DID Document Metadata @@ -14,8 +15,8 @@ This section of the specification defines how various DID document metadata prop The `versionId` DID document metadata property indicates the current version of the DID document that has been resolved. -1. `did:webs` versionId is defined to be the sequence number (i.e. the `s` field) of the last event in the [[ref: KERI event stream]] that was used to construct the DID document according to the rules in section [DID Document from KERI Events](#did-document-from-keri-events). -1. If the DID parameter `versionId` (see section [Support for `versionId`](#support-for-versionid)) was used when resolving the `did:webs` DID, and if the DID Resolution process was successful, then this corresponding DID document metadata property is guaranteed to be equal to the value of the DID parameter. +1. The `did:webs` versionId MUST be the sequence number (i.e. the `s` field) of the last event in the [[ref: KERI event stream]] that was used to construct the DID document according to the rules in section [DID Document from KERI Events](#did-document-from-keri-events). +1. If the DID parameter `versionId` (see section [Support for `versionId`](#support-for-versionid)) was used when resolving the `did:webs` DID, and if the DID Resolution process was successful, then this corresponding DID document metadata property MUST be guaranteed to be equal to the value of the DID parameter. Example: @@ -37,8 +38,8 @@ Example: The `nextVersionId` DID document metadata property indicates the next version of the DID document after the version that has been resolved. -1. `did:webs` `nextVersionId` is defined to be the sequence number (i.e. the `s` field) of the next event in the [[ref: KERI event stream]] after the last one that was used to construct the DID document according to the rules in section [DID Document from KERI Events](#did-document-from-keri-events). -1. This DID document metadata property is only present if the DID parameter `versionId` +1. The `did:webs` `nextVersionId` MUST be the sequence number (i.e. the `s` field) of the next event in the [[ref: KERI event stream]] after the last one that was used to construct the DID document according to the rules in section [DID Document from KERI Events](#did-document-from-keri-events). +1. This DID document metadata property MUST be present if the DID parameter `versionId` (see section [Support for `versionId`](#support-for-versionid)) was used when resolving the `did:webs` DID, and if the value of that DID parameter was not the sequence number of the last event in the [[ref: KERI event stream]]. Example: @@ -63,11 +64,11 @@ Example: The `equivalentId` DID document metadata property indicates other DIDs that refer to the same subject and are logically equivalent to the DID that has been resolved. It is similar to the `alsoKnownAs` DID document property (see section [Also Known As](#also-known-as)), but it has even stronger semantics, insofar as the logical equivalence is guaranteed by the DID method itself. 1. The `did:webs` `equivalentId` metadata property SHOULD contain a list of the controller AID [[ref: designated aliases]] `did:webs` DIDs that differ -in the [[ref:host]] and/or port portion of the [[ref: method-specific identifier]] -but share the same AID. Also see section [[ref:AID controlled identifiers]]. +in the [[ref: host]] and/or port portion of the [[ref: method-specific identifier]] +but share the same AID. Also see section [[ref: AID controlled identifiers]]. 1. `equivalentId` depends on the controller AIDs array of [[ref: designated aliases]]. A `did:webs` identifier MUST not verify unless it is found in the `equivalentId` metadata that corresponds to the [[ref: designated aliases]]. -> Note that [[ref:AID controlled identifiers]] like `did:web` and `did:keri` identifiers with the same AID are not listed in `equivalentId` because they do not have the same DID method. A `did:web` identifier with the same domain and AID does not have the same security characteristics as the `did:webs` identifier. Conversely, a `did:keri` identifier with the same AID has the same security characterisitcs but not the same dependence on the web. For these reasons, they are not listed in `equivalentId`. +> Note that [[ref: AID controlled identifiers]] like `did:web` and `did:keri` identifiers with the same AID are not listed in `equivalentId` because they do not have the same DID method. A `did:web` identifier with the same domain and AID does not have the same security characteristics as the `did:webs` identifier. Conversely, a `did:keri` identifier with the same AID has the same security characterisitcs but not the same dependence on the web. For these reasons, they are not listed in `equivalentId`. Example: diff --git a/spec/diddocuments.md b/spec/diddocuments.md index 94ea666..f299408 100644 --- a/spec/diddocuments.md +++ b/spec/diddocuments.md @@ -1,7 +1,8 @@ ## DID Documents +This section is normative. -1. `did:webs` DID documents MUST be generated or derived from the [[ref:Keri event stream]] of the corresponding AID. - 1. Processing the [[ref: KERI event stream]] of the AID, the generation algorithm will be reading the AID [[ref: KEL]] and any anchored [[ref: TELs]] to produce the DID document. +1. `did:webs` DID documents MUST be generated or derived from the [[ref: Keri event stream]] of the corresponding AID. + 1. Processing the [[ref: KERI event stream]] of the AID, the generation algorithm MUST read the AID [[ref: KEL]] and any anchored [[ref: TELs]] to produce the DID document. 1. `did:webs` DID documents MUST be pure JSON. They MAY be processed as JSON-LD by prepending an `@context` if consumers of the documents wish. 1. All hashes, cryptographic keys, and signatures MUST be represented as [[ref: CESR]] strings. This is an approach similar to multibase, making them self-describing and terse. @@ -70,7 +71,7 @@ sections detail the algorithm to follow for each case. ``` ### DID Controller -The value of the `controller` property MUST be a single string that is the same as the `id` (the DID Subject). +1. The value of the `controller` property MUST be a single string that is the same as the `id` (the DID Subject). ```json { @@ -83,7 +84,7 @@ The value of the `controller` property MUST be a single string that is the same 1. The `alsoKnownAs` property in the root of the DID document MAY contain any DID that has the same AID. See the [[ref: designated aliases]] section for information on how an AID anchors the `alsoKnownAs` identifiers to their [[ref: KERI event stream]]. 1. `did:webs` DIDs MUST serve the `did:webs` and corresponding `did:web`as an `alsoKnownAs` identifier. 1. `did:webs` DIDs MUST provide the corresponding `did:keri` as an `alsoKnownAs` identifier. -1. The same AID MAY be associated with multiple `did:webs` DIDs, each with a different [[ref:host]] and/or path, but with the same AID. +1. The same AID MAY be associated with multiple `did:webs` DIDs, each with a different [[ref: host]] and/or path, but with the same AID. 1. `did:webs` DIDs MUST be listed in the [[ref: designated aliases]] attestation of the AID. 1. For each [[ref: AID controlled identifier]] DID defined above, an entry in the `alsoKnownAs` array in the DID document MUST be created. @@ -195,14 +196,14 @@ would result in a DID document with the following verification methods array: #### Thresholds 1. If the current signing keys threshold (the value of the `kt` field) is a string containing a number that is greater than 1, or if it is an array containing fractionally weighted thresholds, then in addition to the verification methods generated according to the rules in the previous sections, another verification method with a type of `ConditionalProof2022` MUST be generated in the DID document. This verification method type is defined [here](https://w3c-ccg.github.io/verifiable-conditions/). - 1. It is constructed according to the following rules: + 1. It MUST be constructed according to the following rules: 1. The `id` property of the verification method MUST be a relative DID URL and use the AID as the value of the fragment component, e.g., `"id": "#"`. 1. The `controller` property of the verification method MUST be the value of the `id` property of the DID document. (Does the method spec need to specify this?) - 1. If the value of the `kt` field is a string containing a number that is greater than 1: + 1. If the value of the `kt` field is a string containing a number that is greater than 1 then the following rules MUST be applied: 1. The `threshold` property of the verification method MUST be the integer value of the `kt` field in the current key state. 1. The `conditionThreshold` property of the verification method MUST contain an array. For each key listed in the array value of the `k` field in the key state: 1. The relative DID URL corresponding to the key MUST be added to the array value of the `conditionThreshold` property. - 1. If the value of the `kt` field is an array containing fractionally weighted thresholds: + 1. If the value of the `kt` field is an array containing fractionally weighted thresholds then the following rules MUST be applied: 1. The `threshold` property of the verification method MUST be half of the lowest common denominator (LCD) of all the fractions in the `kt` array. 1. The `conditionWeightedThreshold` property of the verification method MUST contain an array. For each key listed in the array value of the `k` field in the key state, and for each corresponding fraction listed in the array value of the `kt` field: 1. A JSON object MUST be added to the array value of the `conditionWeightedThreshold` property. @@ -348,23 +349,23 @@ would result in a DID document with the following verification methods array: ``` ### Verification Relationships -1. If the value of `kt` == 1: +1. If the value of `kt` == 1 then the following rules MUST be applied: 1. For each public key in `k` and its corresponding verification method, two verification relationships MUST be generated in the DID document. One verification relationship of type `authentication` and one verification relationship of type `assertionMethod`. - 1. The `authentication` verification relationship defines that the DID controller can authenticate using each key. - 1. The `assertionMethod` verification relationship defines that the DID controller can express claims using each key. -1. If the value of `kt` > 1 or if the value of `kt` is an array containing fractionally weighted thresholds: + 1. The `authentication` verification relationship SHALL define that the DID controller can authenticate using each key. + 1. The `assertionMethod` verification relationship SHALL define that the DID controller can express claims using each key. +1. If the value of `kt` > 1 or if the value of `kt` is an array containing fractionally weighted thresholds then the following rules MUST be applied: 1. For the verification method of type `ConditionalProof2022` (see section [Thresholds](#thresholds)), two verification relationships MUST be generated in the DID document. One verification relationship of type `authentication` and one verification relationship of type `assertionMethod`. - 1. The `authentication` verification relationship defines that the DID controller can authenticate using a combination of multiple keys above the threshold. - 1. The `assertionMethod` verification relationship defines that the DID controller can express claims using a combination of multiple keys above the threshold. + 1. The `authentication` verification relationship SHALL define that the DID controller can authenticate using a combination of multiple keys above the threshold. + 1. The `assertionMethod` verification relationship SHALL define that the DID controller can express claims using a combination of multiple keys above the threshold. 1. References to verification methods in the DID document MUST use the relative form of the identifier, e.g., `"authentication": ["#"]`. > Private keys of a KERI AID can be used to sign a variety of data. This includes but is not limited to logging into a website, challenge-response exchanges, credential issuances, etc. #### Key Agreement -This section is non-normative: +This section is informative: There are multiple ways to establish key agreement in KERI. We detail common considerations and techniques: -* If the 'k' field references a Ed25519 key, then key agreement MAY be established using the corresponding x25519 key for Diffie-Helman key exchange. +* If the 'k' field references a Ed25519 key, then key agreement may be established using the corresponding x25519 key for Diffie-Helman key exchange. * If the key is an ECDSA or other NIST algorithms key then it will be the same key for signatures and encryption and can be used for key agreement. * *BADA-RUN for key agreement:* Normally in KERI we would use [[ref: BADA-RUN]], similar to how we specify endpoints, [[ref: host]] migration info, etc. This would allow the controller to specify any Key Agreement key, without unnecessarily adding KERI events to their [[ref: KEL]]. @@ -373,9 +374,9 @@ There are multiple ways to establish key agreement in KERI. We detail common con * Likely the best mechanism is to anchor an [[ref: ACDC]] to a [[ref: TEL]] which is anchored to the KEL. #### Other Key Commitments -This section is non-normative: +This section is informative. -Data structures similar to Location Scheme and Endpoint Authorizations and managed in KERI using [[ref: BADA-RUN]] MAY be created and used for declaring other types of keys, for example encryption keys, etc +Data structures similar to Location Scheme and Endpoint Authorizations and managed in KERI using [[ref: BADA-RUN]] may be created and used for declaring other types of keys, for example encryption keys, etc To support new data structures, propose them in KERI and detail the transformation in the spec. @@ -388,7 +389,7 @@ To support new data structures, propose them in KERI and detail the transformati #### KERI Service Endpoints as DID Document Metadata -1. `did:webs` endpoints must be specified using the two data sets KERI uses to define service endpoints; Location Schemes and Endpoint Role Authorizations. +1. `did:webs` endpoints MUST be specified using the two data sets KERI uses to define service endpoints; Location Schemes and Endpoint Role Authorizations. 1. Both MUST be expressed in KERI `rpy` events. 1. For URL scheme endpoints that an AID has exposed, `did:webs` DIDs MUST use Location Schemes URLs. 1. For endpoints that relate a role of one AID to another, `did:webs` DIDs MUST use KERI Endpoint Role Authorizations. @@ -467,8 +468,8 @@ TODO: Propose a new role in KERI to map to the existing [DIDCommMessaging](http The DID document that exists as a resource on a webserver is compatible with the `did:web` DID method and therefore necessarily different from a `did:webs` DID document with regard to the `id`, `controller`, and `alsoKnownAs` properties. 1. To transform the `did:web` form of the DID Document to a `did:webs` the transformation MUST do the following: - 1. In the values of the top-level `id` and `controller` properties of the DID document, replace the `did:webs` prefix string with `did:web`. - 1. In the value of the top-level `alsoKnownAs` property, replace the entry that is now the new value of the `id` property (using `did:web`) with the old value of the `id` property (using `did:webs`). + 1. In the values of the top-level `id` and `controller` properties of the DID document, the transformation MUST replace the `did:webs` prefix string with `did:web`. + 1. In the value of the top-level `alsoKnownAs` property, the transformation MUST replace the entry that is now the new value of the `id` property (using `did:web`) with the old value of the `id` property (using `did:webs`). 1. All other content of the DID document MUST not be modified. For example, this transformation is used during the [Create](#create) DID method operation, given the following `did:webs` DID document: @@ -535,7 +536,7 @@ This section defines an inverse transformation algorithm from a `did:web` DID do ``` ### Full Example -> This section is non-normative +This section is informative. The following blocks contain full annotated examples of a KERI AID with two events, an inception event and an interaction event, some witnesses, multiple public signing and rotation keys and an Agent with the resulting DID document that an implementation would generate assuming the implementation was running on the `example.com` domain with no unique port and no additional path defined: @@ -730,21 +731,21 @@ Resulting DID document: #### Key state events 1. When processing the [[ref: KERI event stream]] `did:webs` MUST account for two broad types of key state events (KERI parlance is 'establishment events') that can alter the key state of the AID. 1. Any change in key state of the AID MUST be reflected in the DID document. -1. If a key state event does not commit to a future set of rotation key hashes, then the AID can't be rotated to new keys in the future (KERI parlance is that the key state of the AID becomes 'non-transferrable'). +1. If a key state event does not commit to a future set of rotation key hashes, then the AID SHALL NOT be rotated to new keys in the future (KERI parlance is that the key state of the AID becomes 'non-transferrable'). 1. If a key state event does commit to a future set of rotation key hashes, then any future key state rotation MUST be to those commitment keys. This foundation of [[ref: pre-rotation]] is post-quantum safe and allows the `did:webs` controller to recover from key compromise. 1. The [[ref: Inception event]] MUST be the first event in the [[ref: KEL]] that establishes the AID. - 1. This defines the initial key set + 1. This MUST define the initial key set 1. If the controller(s) desire future key rotation (transfer) then the inception event MUST commit to a set of future rotation key hashes. - 1. When processing the [[ref: KERI event stream]], if there are no rotation events after the inception event, then this is the current key state of the AID and will be reflected in the DID Document as specified in [Verification Methods](#verification-methods) and [Verification Relationships](#verification-relationships). + 1. When processing the [[ref: KERI event stream]], if there are no rotation events after the inception event, then this is the current key state of the AID and MUST be reflected in the DID Document as specified in [Verification Methods](#verification-methods) and [Verification Relationships](#verification-relationships). 1. [[ref: Rotation events]] MUST come after inception events. -1. If the controller(s) desires future key rotation (transfer) then the rotation event must commit to a set of future rotation key hashes. +1. If the controller(s) desires future key rotation (transfer) then the rotation event MUST commit to a set of future rotation key hashes. 1. [[ref: Rotation events]] MUST only change the key state to the previously committed to rotation keys. 1. The last rotation event is the current key state of the AID and MUST be reflected in the DID Document as specified in [Verification Methods](#verification-methods) and [Verification Relationships](#verification-relationships). > You can learn more about the inception event in the [[ref: KERI specification]] and you can see an example inception event. > To learn about future rotation key commitment, see the sections about [pre-rotation](#pre-rotation) and the [[ref: KERI specification]]. -> You can learn more about rotation events in the [[ref:KERI specification]] and you can see an example rotation event. +> You can learn more about rotation events in the [[ref: KERI specification]] and you can see an example rotation event. > To learn about future rotation key commitment, see the sections about [pre-rotation](#pre-rotation) and the [[ref: KERI specification]]. ### Delegation KERI event details diff --git a/spec/didparameters.md b/spec/didparameters.md index 7b27468..8be87dd 100644 --- a/spec/didparameters.md +++ b/spec/didparameters.md @@ -1,4 +1,5 @@ ## DID Parameters +This section is normative. This section describes the support of the `did:webs` method for certain DID parameters. diff --git a/spec/iana_considerations.md b/spec/iana_considerations.md index 0aa5211..6b7240c 100644 --- a/spec/iana_considerations.md +++ b/spec/iana_considerations.md @@ -1,3 +1,4 @@ ## IANA Considerations +This section is normative. -This document has no IANA actions. \ No newline at end of file +1. This document has no IANA actions. \ No newline at end of file diff --git a/spec/introduction.md b/spec/introduction.md index 1258ade..7dae49e 100644 --- a/spec/introduction.md +++ b/spec/introduction.md @@ -1,4 +1,5 @@ ## Introduction +This section is informative. DID methods answer many questions. Two noteworthy ones are: diff --git a/spec/keri.md b/spec/keri.md index 98db537..a9640f8 100644 --- a/spec/keri.md +++ b/spec/keri.md @@ -1,5 +1,5 @@ ## KERI Fundamentals -This section is non-normative. +This section is informative. [[ref: Key Event Receipt Infrastructure (KERI)]] is a protocol for managing cryptographic keys, identifiers, and associated verifiable data structures. KERI was first described in an [academic paper](https://arxiv.org/abs/1907.02143), and its [specification](https://github.com/trustoverip/tswg-keri-specification) is currently incubated under [Trust Over IP Foundation](https://trustoverip.org/). The open source community that develops KERI-related technologies can be found at https://github.com/WebOfTrust. This section outlines the fundamentals and components of the KERI protocol that are related to the `did:webs` method. @@ -13,8 +13,8 @@ The binding between an [[ref: AID]] and its cryptographic keys is proved by a da A KEL is a hash-chain append-only log and can be considered a variant of blockchain. However, a KEL differs from the traditional blockchain technology in at least two important ways: -1. It records the [[ref: key event]] history of a single AID with a single [[ref: controller]], instead of an arbitrarily large collection updated by other participants in the network. This makes a KEL memory-efficient, fast, cheap, and trivially scalable. -2. It is fully [[ref: self-certifying]], meaning its correctness can be proved by direct inspection, without a distributed consensus algorithm or assumptions about trust in an external data source or its governance. +* It records the [[ref: key event]] history of a single AID with a single [[ref: controller]], instead of an arbitrarily large collection updated by other participants in the network. This makes a KEL memory-efficient, fast, cheap, and trivially scalable. +* It is fully [[ref: self-certifying]], meaning its correctness can be proved by direct inspection, without a distributed consensus algorithm or assumptions about trust in an external data source or its governance. These properties allows a KEL to be published anywhere, without special guarantees from its storage mechanism. For example, a KEL of an AID could be published and migrated between different KERI-compatible blockchain networks that use different DID methods. A KEL also records changes to key types and cryptographic algorithms, providing the AID portability and adaptability to multiple ecosystems throughout its lifecycle. diff --git a/spec/normative_references.md b/spec/normative_references.md index 017756c..9c112f5 100644 --- a/spec/normative_references.md +++ b/spec/normative_references.md @@ -7,10 +7,19 @@ ~ The data integrity proof defined in the [[ref: Verifiable Credential Data Model]] spec. See https://www.w3.org/TR/vc-data-model/#data-integrity-proofs. [[def: JSON Serialization]] -~ See https://datatracker.ietf.org/doc/html/rfc7515#section-3.2 +~ See https://datatracker.ietf.org/doc/html/rfc7515#section-3.2. [[def: multiformat multihash]] -~ See https://github.com/multiformats/multihash +~ See https://github.com/multiformats/multihash. + +[[def: RFC1035]] +~ Domain names - implementation and specification. See https://www.rfc-editor.org/info/rfc1035. + +[[def: RFC1123]] +~ Requirements for Internet Hosts -- Application and Support. See https://datatracker.ietf.org/doc/html/rfc1123. + +[[def: RFC2181]] +~ Clarifications to the DNS Specification. See https://www.rfc-editor.org/info/rfc2181. [[def: Trust over IP - Authentic Chained Data Containers (ACDC) specification, ACDC specification, ACDC protocol]] ~ The [ACDC specification](https://trustoverip.github.io/tswg-acdc-specification/) details the core ACDC specification including the Issuance and Presentation Exchange (IPEX) Protocol and Public Transaction Event Log (PTEL) specification. diff --git a/spec/privacy_considerations.md b/spec/privacy_considerations.md index dfa337f..b4ceb79 100644 --- a/spec/privacy_considerations.md +++ b/spec/privacy_considerations.md @@ -1,5 +1,5 @@ ## Privacy Considerations -This section is non-normative. +This section is informative. This section addresses the privacy considerations from [RFC6973](https://datatracker.ietf.org/doc/html/rfc6973) section 5. For privacy considerations related to web infrastructure, see [`did:web` privacy considerations](https://w3c-ccg.github.io/did-method-web/#security-and-privacy-considerations). diff --git a/spec/requirements_notations_conventions.md b/spec/requirements_notations_conventions.md index a3404fb..5ee9d68 100644 --- a/spec/requirements_notations_conventions.md +++ b/spec/requirements_notations_conventions.md @@ -1,8 +1,8 @@ ## Requirements, Notation and Conventions +This section is normative. -The following key words in this document are to be interpreted as -described in BCP 14 [RFC2119] [RFC8174] when, and only when, they -appear in all capitals, as shown here: +### Keywords +The following key words in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here: 1. "MUST" 1. "MUST NOT" 1. "REQUIRED" @@ -13,4 +13,15 @@ appear in all capitals, as shown here: 1. "RECOMMENDED" 1. "NOT RECOMMENDED" 1. "MAY" -1. "OPTIONAL" \ No newline at end of file +1. "OPTIONAL" + +### Conventions + +1. Normative sections MUST start with "This section is normative." +1. Normative statements SHOULD read in a way that can be implemented. +1. Normative statements MUST be numbered so that they are easily referenced and addressed in discussions, issues, pull requests, etc. +1. Informative sections MUST start with "This section is informative." +1. Informative statements MUST NOT be numbered. Instead they can use prose or bulleted points. +1. If informative statements accompany normative statements then they MUST be separated like: + > This is informative text accompanying but separated from the normative statements. +1. If a normative section contains an informative sub-section then the sub-section MUST be marked with "This section is informative." \ No newline at end of file diff --git a/spec/security_considerations.md b/spec/security_considerations.md index 3ecc2eb..e9d5d32 100644 --- a/spec/security_considerations.md +++ b/spec/security_considerations.md @@ -1,34 +1,36 @@ ## Security Considerations +This section is normative. + There are many security considerations related to web requests, storing information securely, etc. It is useful to address these considerations along with the common security threats found on the web. ### Common security threats -1. All `did:webs` features MUST reduce the attack surface against common threats, such as: - 1. Broken Object Level Authorization (BOLA) - 1. Denial of service (DoS) attack - 1. Deletion attack - 1. Duplicity detection - 1. Eclipse attack - 1. Forgery - 1. Impersonation attack - 1. Key Compromise attack - 1. Malleability attack - 1. Replay attack +1. All `did:webs` features MUST reduce the attack surface against common threats: + 1. Broken Object Level Authorization (BOLA) attacks MUST be eliminated or reduced. + 1. Denial of service (DoS) attacks MUST be eliminated or reduced. + 1. Deletion attacks MUST be eliminated or reduced. + 1. Duplicity detection MUST be available and reliable. + 1. Eclipse attacks MUST be eliminated or reduced. + 1. Forgery attacks MUST be eliminated or reduced. + 1. Impersonation attacks MUST be eliminated or reduced. + 1. Key Compromise attacks MUST be eliminated or reduced. + 1. Malleability attacks MUST be eliminated or reduced. + 1. Replay attacks MUST be eliminated or reduced. ### Using HTTPS Perfect protection from eavesdropping is not possible with HTTPS, for various reasons. -1. URLs of DID documents and [[ref: KERI event streams]] SHOULD be hosted in a way that embodies accepted cybersecurity best practice. This is not strictly necessary to guarantee the authenticity of the data. However, the usage of HTTPS MUST: - 1. Safeguard privacy - 1. Discourage denial of service - 1. Work in concert with defense-in-depth mindset - 1. Aid regulatory compliance - 1. Allow for high-confidence fetches of the DID document and a [[ref: KERI event stream]] +1. URLs of DID documents and [[ref: KERI event streams]] SHOULD be hosted in a way that embodies accepted cybersecurity best practice. This is not strictly necessary to guarantee the authenticity of the data. However, the usage: + 1. MUST safeguard privacy + 1. MUST discourage denial of service + 1. MUST work in concert with defense-in-depth mindset + 1. MUST aid regulatory compliance + 1. MUST allow for high-confidence fetches of the DID document and a [[ref: KERI event stream]] 1. A [[ref: host]] that uses a fully qualified domain name of the [[ref: method-specific identifier]] MUST be secured by a TLS/SSL certificate. 1. The fully qualified domain name MUST match the common name used in the SSL/TLS certificate. 1. The common name in the SSL/TLS certificate from the server MUST correspond to the way the server is referenced in the URL. This means that if the URL includes `www.example.com`, the common name in the SSL/TLS certificate must be `www.example.com` as well. 1. Unlike `did:web`, the URL MAY use an IP address instead. - 1. If it does, then the common name in the certificate must be the IP address as well. + 1. If it does, then the common name in the certificate MUST be the IP address as well. 1. Essentially, the URL and the certificate MUST NOT identify the server in contradictory ways; subject to that constraint, how the server is identified is flexible. 1. The server certificate MAY be self-issued 1. OR it MAY chain back to an unknown certificate authority. However, to ensure reasonable security hygiene, it MUST be valid. This has two meanings, both of which are required: @@ -42,34 +44,31 @@ reasons. ### International Domain Names -1. As with `did:web`, implementers of this method SHOULD consider how non-ASCII characters manifest in URLs and DIDs. - 1. The [[spec:DID-CORE]] identifier syntax does not allow the direct representation of such characters in method name or method specific identifiers.This prevents a `did:webs` value from embodying a homograph attack. +1. As with `did:web`, implementers of `did:webs` SHOULD consider how non-ASCII characters manifest in URLs and DIDs. + 1. `did:webs` MUST follow the [[ref: DID-CORE]] identifier syntax which does not allow the direct representation of such characters in method name or method specific identifiers. This prevents a `did:webs` value from embodying a homograph attack. 1. However, `did:webs` MAY hold data encoded with punycode or percent encoding. This means that IRIs constructed from DID values could contain non-ASCII characters that were not obvious in the DID, surprising a casual human reader. 1. Caution is RECOMMENDED when treating a `did:webs` as the equivalent of an IRI. 1. Treating it as the equivalent of a URL, instead, is RECOMMENDED as it preserves the punycode and percent encoding and is therefore safe. -See also: -* [UTS-46](https://unicode.org/reports/tr46/) -* [[spec:rfc5895]] - ### Concepts for securing `did:webs` information The following security concepts are used to secure the data, files, signatures and other information in `did:webs`. 1. All security features and concepts in `did:webs` MUST be use one or more of the following mechanisms: 1. All data that requires the highest security MUST be [[ref: KEL]] backed. This includes any information that needs to be end-verifiably authentic over time: - 1. All [[ref: ACDCs]] used by a `did:webs` identifier MUST be anchored to a KEL directly. - 1. OR indirectly through a [[ref: TEL]] that itself is anchored to a KEL. + 1. All [[ref: ACDCs]] used by a `did:webs` identifier MUST be one of the following: + 1. MAY be anchored to a KEL directly. + 1. MAY be anchored indirectly through a [[ref: TEL]] that itself is anchored to a KEL. 1. All data that does not need to incur the cost of [[ref: KEL]] backing for secuirty but can benefit from the latest data-state such as a distributed data-base MUST use _Best Available Data - Read, Update, Nullify_ ([[ref: BADA-RUN]]). - 1. BADA-RUN information MUST be ordered in a consistent way, using a combination of: - 1. date-time - 1. key state + 1. BADA-RUN information MUST be ordered in a consistent way, using the following: + 1. date-time MUST be used. + 1. key state MUST be used. 1. Discovery information MAY use [[ref: BADA-RUN]] because the worst-case attack on discovery information is a DDoS attack where nothing gets discovered. 1. The controller(s) of the AID for a `did:webs` identifier MAY use [[ref: BADA-RUN]] for service end-points as discovery mechanisms. - 1. All data that does not need the security of being [[ref: KEL]] backed nor [[ref: BADA-RUN]] should be served using _KERI Request Authentication Mechanism_ ([[ref: KRAM]]). + 1. All data that does not need the security of being [[ref: KEL]] backed nor [[ref: BADA-RUN]] SHOULD be served using _KERI Request Authentication Mechanism_ ([[ref: KRAM]]). 1. For a `did:webs` resolver to be trusted it SHOULD use KRAM to access the service endpoints providing KERI event streams for verification of the DID document. ### On-Disk Storage -This section is non-normative. +This section is informative. Both KEL backed data and [[ref: BADA-RUN]] security approaches are suitable for storing information on disk because both provide a link between the keystate and date-time on some data when a signature by the source of the data was created. [[ref: BADA-RUN]] is too weak for important information because an attacker who has access to the database on disk can overwrite data on disk without being detected by a verifier hosting the on-disk data either through a replay of stale data (data regression attack) or if in addition to disk access the attacker has compromised a given key state, then the attacker can forge new data with a new date-time stamp for a given compromised key and do a regression attack so that the last seen key state is the compromised key state. @@ -84,7 +83,7 @@ The use of DH key exchange as a weak form of authentication is no more secure th Often, DID methods have focused on features that erode security characteristics. The paper [Five DID Attacks](https://github.com/WebOfTrustInfo/rwot11-the-hague/blob/master/final-documents/taking-out-the-crud-five-fabulous-did-attacks.pdf) highlights some attacks to which `did:webs` should NOT be vulnerable. So when a pull request exposes `did:webs` to a known attack, it should not be accepted. ### Alignment of Information to Security Posture -This section is non-normative. +This section is informative. As a general security principle each block of information should have the same security posture for all the sub-blocks. One should not attempt to secure a block of information that mixes security postures across is constituent sub-blocks. The reason is that the security of the block can be no stronger than the weakest security posture of any sub-block in the block. Mixing security postures forces all to have the lowest common denominator security. The only exception to this rule is if the block of information is purely informational for discovery purposes and where it is expected that each constituent sub-block is meant to be verified independently. @@ -93,19 +92,19 @@ This means that any recipient of such a block information with mixed security po Unfortunately, what happens in practice is that users are led into a false sense of security because they assume that they don’t have to explode and re-verify, but merely may accept the lowest common denominator verification on the whole block of information. This creates a pernicious problem for downstream use of the data. A downstream use of a constituent sub-block doesn’t know that it was not independently verified to its higher level of security. This widens the attack surface to any point of down-stream usage. This is a root cause of the most prevalent type of attack called a BOLA. #### Applying the concepts -This section is non-normative. +This section is informative. Lets explore the implications of applying these concepts to various `did:webs` elements. -Using [[ref: KEL]] backed elements in a DID doc simplifies the security concerns. However, future discovery features related to endpoints might consider BADA-RUN. For instance, 'whois' data could be used with [[ref: BADA-RUN]] whereas did:web aliases should not because it could lead to an impersonation attack. We could have a DID document that uses [[ref: BADA-RUN]] if we modify the DID CRUD semantics to be RUN semantics without necessarily changing the verbs but by changing the semantics of the verbs. Then any data that fits the security policy of BADA (i.e. where BADA is secure enough) can be stored in a DID document as a database in the sky. For sure this includes service endpoints for discovery. One can sign with [[ref:CESR]] or JWS signatures. The payloads are essentially KERI reply messages in terms of the fields (with modifications as needed to be more palatable), but are semantically the same. The DID doc just relays those replies. Anyone reading from the DID document is essentially getting a KERI reply message, and they then should apply the BADA rules to their local copy of the reply message. +Using [[ref: KEL]] backed elements in a DID doc simplifies the security concerns. However, future discovery features related to endpoints might consider BADA-RUN. For instance, 'whois' data could be used with [[ref: BADA-RUN]] whereas did:web aliases should not because it could lead to an impersonation attack. We could have a DID document that uses [[ref: BADA-RUN]] if we modify the DID CRUD semantics to be RUN semantics without necessarily changing the verbs but by changing the semantics of the verbs. Then any data that fits the security policy of BADA (i.e. where BADA is secure enough) can be stored in a DID document as a database in the sky. For sure this includes service endpoints for discovery. One can sign with [[ref: CESR]] or JWS signatures. The payloads are essentially KERI reply messages in terms of the fields (with modifications as needed to be more palatable), but are semantically the same. The DID doc just relays those replies. Anyone reading from the DID document is essentially getting a KERI reply message, and they then should apply the BADA rules to their local copy of the reply message. -To elaborate, these security concepts point us to modify the DID CRUD semantics to replicate RUN semantics. _Create_ becomes synonymous with _Update_ where Update uses the RUN update. _Delete_ is modified to use the Nullify semantics. _Read_ data is modified so that any recipient of the Read response can apply BADA to its data (Read is a GET). So we map the CRUD of DID docs to RUN for the `did:webs` method. Now you have reasonable security for things like signed data. If its [[ref: KEL]] backed data you could even use an [[ref:ACDC]] as a data attestation for that data and the did resolver would become a caching store for [[ref:ACDCs]] issued by the AID controller. +To elaborate, these security concepts point us to modify the DID CRUD semantics to replicate RUN semantics. _Create_ becomes synonymous with _Update_ where Update uses the RUN update. _Delete_ is modified to use the Nullify semantics. _Read_ data is modified so that any recipient of the Read response can apply BADA to its data (Read is a GET). So we map the CRUD of DID docs to RUN for the `did:webs` method. Now you have reasonable security for things like signed data. If its [[ref: KEL]] backed data you could even use an [[ref: ACDC]] as a data attestation for that data and the did resolver would become a caching store for [[ref: ACDCs]] issued by the AID controller. Architecturally, a Read (GET) from the did resolver acts like how KERI reply messages are handled for resolving service endpoint discovery from an [[ref: OOBI]]. The query is the read in RUN and so uses KRAM. The reply is the response to the READ request. The controller of the AID updates the DID resolvers cache with updates(unsolicited reply messages). A trustworthy DID resolver applies the BADA rules to any updates it receives. Optionally the DID resolver may apply [[ref: KRAM]] rules to any READ requests to protect it from replay attacks. -In addition, a DID doc can be a discovery mechanism for an [[ref:ACDC]] caching server by including an index (label: said) of the [[ref:SAIDs]] of the [[ref:ACDCs]] held in the resolvers cache. +In addition, a DID doc can be a discovery mechanism for an [[ref: ACDC]] caching server by including an index (label: said) of the [[ref: SAIDs]] of the [[ref: ACDCs]] held in the resolvers cache. #### Reducing the attack surface -This section is non-normative. +This section is informative. The above considerations have lead us to focus on [[ref: KEL]] backed DID document blocks and data (whois files, signatures, etc) so that the trusted (local) did:webs resolver is secure. Any future features that could leverage [[ref: BADA-RUN]] and [[ref: KRAM]] should be considered carefully according to the above considerations. diff --git a/spec/signed_files.md b/spec/signed_files.md index e2a3e57..47c96cd 100644 --- a/spec/signed_files.md +++ b/spec/signed_files.md @@ -1,29 +1,30 @@ ## Signed Files +This section is normative. `did:webs` signed files combine the semantics of folders of files on web servers, and the [[ref: DID Specification]]'s [[ref: DID URL path]] semantics to enable the controller of the DID to publish documents cryptographically signed using the verification key(s) of the DID. This kind of signed file capability has been implemented in a variety of ways in the past, such as with [hashlinks](https://datatracker.ietf.org/doc/html/draft-sporny-hashlink). The value of including this as part of the `did:webs` DID method is that it ensures consistency in its application, including how the signed files can be verified when using a [[ref: multisig]]-enabled DID, and in the face of rotations of the DID's key(s). -1. In publishing a file, the controller of the DID may use the KERI [[ref: TEL]] to record the signing event, prior to publishing the file. In that case, in processing the KERI Audit log, the publication event can be found, verified, and ordered relative to key state changes and other signing events. +1. In publishing a file, the controller of the DID MAY use the KERI [[ref: TEL]] to record the signing event, prior to publishing the file. In that case, in processing the KERI Audit log, the publication event MUST be found, verified, and ordered relative to key state changes and other signing events. 1. If the file is NOT [[ref: KEL backed data]] or if the controller would like to provide additional signature, the controller MUST do the following: - 1. The controller of the DID may place arbitrary files into the folder structure below the root did:webs folder. - 1. The DID URL for the signed file is of the form `/`. + 1. The controller of the DID MAY place arbitrary files into the folder structure below the root did:webs folder. + 1. The DID URL for the signed file MUST be of the form `/`. 1. The HTTPS path to the file MUST be `/`. 1. To be a valid `did:webs` signed file, each file MUST have an associated JSON Web Signature file named `.jws` beside (in the same Web folder as) the file. For example, a file `revocation_registry.bin` MUST have a file `revocation_registry.bin.jws` beside it. 1. The HTTPS path to the associated JWS file MUST be `/.jws`. - 1. The JWS web signature MUST: - 1. Use the [[ref: JSON Serialization]] form of the JWS. This is necessary to support multi-signatures in the JWS. - 1. Have a payload that is the [multiformat multihash] hash of the content of the associated signed file. - 1. Be signed with a verification key(s) that is (are) either currently in the DIDDoc of the DID, or found in the [[ref: KEL]] associated with the DID. A verification key found in a valid [[ref: KEL]] represents a key that had been in use previously, but has been rotated away. - 1. Be verified such that: - 1. A calculated hash of the file matches the hash in the JWS. - 1. The signature(s) in the JWS is (are) valid. - 1. If the DID has (or had at the time of signing) [[ref: multisig]] requirements, those requirements are met. + 1. The JWS web signature MUST apply the following rules: + 1. MUST use the [[ref: JSON Serialization]] form of the JWS. This is necessary to support multi-signatures in the JWS. + 1. MUST have a payload that is the [multiformat multihash] hash of the content of the associated signed file. + 1. MUST be signed with a verification key(s) that is (are) either currently in the DIDDoc of the DID, or found in the [[ref: KEL]] associated with the DID. A verification key found in a valid [[ref: KEL]] represents a key that had been in use previously, but has been rotated away. + 1. MUST be verified such that: + 1. A calculated hash of the file MUST match the hash in the JWS. + 1. The signature(s) in the JWS MUST be valid. + 1. If the DID has (or had at the time of signing) [[ref: multisig]] requirements, those requirements MUST be met. See: * [[ref: JSON Serialization]] * [[ref: multiformat multihash]] -The following is non-normative: +The following is informative. Examples: * DID URL: `did:webs:w3c-ccg.github.io:12124313423525/members-list.txt` * HTTPS URL: `https://w3c-ccg.github.io/12124313423525/members-list.txt` diff --git a/spec/whois.md b/spec/whois.md index 56b7bd6..2330ce4 100644 --- a/spec/whois.md +++ b/spec/whois.md @@ -9,16 +9,16 @@ This convention enables those that receive the DID to retrieve and verify the ve 1. If the controller of the `did:webs` DID has not published a `whois` verifiable presentation, the web server MUST respond with an HTTP `404` response ("Not Found"). 1. The resolved `whois` DID URL MUST resolve to a verifiable presentation in which the presentation proof is signed by a key or keys from the current `did:webs` DID Document or a valid previous version of the DID Document. 1. All of the verifiable credentials in the verifiable presentation MUST have the `did:webs` DID as the credential subject. -1. The verifiable presentation may be in one of three formats: - 1. A W3C Verifiable Credentials Data Model Standard JSON-LD [[ref: Data Integrity Proof]] Verifiable Presentation. - 1. A W3C Verifiable Credentials Data Model Standard [[ref: JSON Web Token Verifiable Presentation]]. - 1. An [[ref: ACDC]] or [[ref: ACDC IPEX]] disclosure. +1. The verifiable presentation MUST be in one of three formats: + 1. A W3C [[ref: Verifiable Credentials Data Model]] Standard JSON-LD [[ref: Data Integrity Proof]] Verifiable Presentation MAY be used. + 1. A W3C [[ref: Verifiable Credentials Data Model]] Standard [[ref: JSON Web Token Verifiable Presentation]] MAY be used. + 1. An [[ref: ACDC]] or [[ref: ACDC IPEX]] disclosure MAY be used. 1. When the verifiable presentation is requested, the resolved object MUST contain the appropriate MIME type of the verifiable presentation format. > It is up to the DID Controller to decide to publish a verifiable presentation and if so, which Verifiable Credentials to put into the verifiable presentation. ### `whois` Use Case -This section is non-normative. +This section is informative. The following is a use case for this capability. Consider an example of the `did:webs` controller being an educational institution that issues "degree" verifiable credentials to its graduate students. A graduate from the school submits as part of their job application to a company a [[ref: Verifiable Presentation]] derived from the verifiable credential they received from the school. The company receiving the presentation can verify the cryptography of the presentation, but can they trust the school that issued the verifiable credential? If the school issued the verifiable credential using its `did:webs` DID, the company can resolve the DID. It can also resolve the DID's `whois` DID URL where it might find VCs from issuers it trusts with the `did:webs` DID as the subject. For example: