Overview
The emergence of Decentralized Identifiers (DIDs) and with them the evolution of DID Methods continues to be a dynamic area of development in the quest for trusted, secure and private digital identity management where the users are in control of their own data.
The did:web method provides a solution that is recognized
for its simplicity of deployment and its cost-effectiveness, allowing for easy establishment of a
credential ecosystem. It leverages the Domain Name System (DNS) to perform the DID operations including
DID-to-HTTPS transformation and allowing for DIDs to be associated with a domain's reputation or published
on platforms such as GitHub. This approach is, however, not without its challenges. It is, for example, not
inherently decentralized as it relies on DNS domain names, which require centralized registries. In addition
did:web lacks a cryptographically verifiable, tamper-resistant, and persistently stored DID document,
including its verifiable history.
We propose the did:webhv (did:web + Verifiable History) method presented
here as an enhancement of did:web, providing a solution to address the
limitations inherent of did:web. The did:webvh was called did:tdw through
version v0.4 of the specification. did:webvh introduces features such as a
verifiable history, akin to what is available with ledger-based DIDs, but
without relying on a ledger, a self-certifying identifiers (SCIDs), and
authorized key(s) to increase control over the creation, update, and
deactivation of a DID. Furthermore, the did:webvh method provides a more
decentralized approach by ensuring that the security of the embedded SCID does
not depend on DNS, and enables resolving a cryptographically verifiable trust
registry and status lists, using DID-Linked Resources, which did:web lacks.
In summary, the did:webvh method offers a higher level of assurance for those
requiring more robust verification processes compared to what is provided by
did:web. It also represents a significant stride towards a more trusted and
secure web, where the integrity of cryptographic key publishing and management
is paramount. In addition, did:webvh maintains backward compatibility with
did:web and the resulting DID can be published as both did:web and
did:webvh. These possibilities carter to a flexible and broader range of use
cases and corresponding trust requirements, addressing both those who are
comfortable with the existing did:web infrastructure to those seeking greater
security assurances provided by did:webvh.
A tl;dr summary of did:webvh¶
The did:webvh Structure (or, Where is the DID Doc??)¶
did:webvhuses a so-called DID Log to publish cryptographic material and capabilities- A
DID Logis stored asdid.jsonlfile and represents a list of entries, each formatted as JSON line -
Every
DID Log Entrydescribes a specific version of the corresponding DID via a JSON object- DID Log Entry :=
{ "versionId": "", "versionTime": "", "parameters": {}, "state": {}, "proof" : [] }versionId-- a value that combines the version number (starting at1and incremented by one per version), followed by a literal dash-, and a hash of the entry, which links each entry to its predecessor in a ledger-like chainversionTime-- a string in UTC ISO8601 formatparameters-- a set of parameters that impact the processing of the current and future log entries- method
- SCID
- updateKeys
- portable (optional)
- prerotation (optional)
- nextKeyHashes (optional)
- witnesses (optional)
- deactivated (when accurate)
- ttl (optional)
state-- the current version of the DIDDocproof-- a Data Integrity (DI) proof calculated across the entry, signed by a DID Controller authorized key to update the DIDDoc, and optionally, a set of witnesses that monitor the actions of the DID Controller
- DID Log Entry :=
-
The entire
DID Docis part of the "state" object (in every JSON line of a DID Log Entry within the DID Log File)
Creating the first DID Doc¶
-
Create a preliminary log entry
- Create the JSON structure with the aforementioned properties and the following values:
versionId:= the literal string "{SCID}"versionTime:= as asserted by the DID Controller, for example,"2024-04-05T07:32:58Z"parameters:= as needed and defined by the DID Controller, for example:- method :=
did:webvh:0.4 - SCID := the literal string "
{SCID}" (here and wherever the calculated SCID value will eventually be placed)
- method :=
state:= initial DID Doc with placeholders (the literal string "{SCID}") wherever the calculated SCID value will eventually be placedproof:= not set at this point. Will be set in step 4 below
- Create the JSON structure with the aforementioned properties and the following values:
-
Calculate the SCID
- SCID :=
base58btc(multihash(JCS(preliminary log entry with placeholders), <hash algorithm>))JCS:= an implementation of the JSON Canonicalization Scheme (RFC8785)multihash:= an implementation of the multihash specification<hash algorithm>:= one of the hash algorithms accepted bydid:webvh(see parameters in the specification)base58btc:= an implementation of the base58btc function
- SCID :=
-
Update the preliminary log entry
- Replace all placeholders (the literal string
{SCID}) with the calculated SCID value. - Calculate the
entryHashasentryHash := base58btc(multihash(JCS(entry), <hash algorithm>)). - Set the
versionIdto1(for version 1 of the DID), followed by a literal dash-, followed by the calculatedentryHash.
- Replace all placeholders (the literal string
-
Calculate the data integrity (DI) proof
proof:= a proof calculated across the entire DID Log Entry and signed with anupdateKeys(and optionally by witnesses). Values of required attributes include:type:=DataIntegrityProofcryptosuite:=eddsa-jcs-2022proofPurpose:=assertionMethod
-
Add the DI proof to the
proofproperty of the DID Log Entry
Creating the first DID Log¶
- Turn the Log Entry into a JSON Line according the JSON Lines specification and add the line to the DID Log File for publication
Some considerations¶
- When updating the DID to a new version:
- The SCID is only calculated when creating the first DID Log Entry, and
only used as the
versionIdwhen calculating theentryHashof that first entry. - For each a new log entry after the first, the
entryHashis calculated with itsversionIdset to theversionIdof the prior log entry. This results in all of the entries being cryptographically "chained" together such that an alteration to an entry is evident in all succeeding entries. - The
versionIdis the number of the version (incrementing by one per version), the literal-, followed by the calculatedentryHashfor the entry. - Note: Both the SCID and the
entryHashare calculated before the DI proof calculation is added to the entry.
- The SCID is only calculated when creating the first DID Log Entry, and
only used as the
did:webvhuses the same DID-to-HTTPS transformation asdid:web, sodid:webvh'sdid.jsonl(JSON Lines) file is found in the same location asdid:web'sdid.jsonfile, and supports an easy transition fromdid:webto gain the added benefits ofdid:webvh.- For backwards compatibility, and for verifiers that "trust"
did:web, adid:webvhcan be trivially modified and published in parallel to adid:webDID. For resolvers that want more assurance,did:webvhprovides a way to "trust did:web" (or to enable a "trusted web" if you say it fast) enabled by the features listed in the introduction.