Wait, is that a typo? Do you mean did:web?
I did not, but I also did not not mean did:web. did:webvh is a new DID method, but it is also specifically designed to be a more production-worthy, “grown up” version of did:web, everyone’s favorite “training-wheel” DID method and growth hack for getting VCs issued from highly-trusted issuers. Crucially, did:webvh is a “backwards-compatible upgrade” to did:web, meaning it can be consumed in "legacy mode" by any software that already resolves did:web, but upgrades the featureset and trust-model when consumers upgrade their resolution logic to take advantage of the new syntax.
It was incubated at the Identifiers and Discovery Working Group at DIF, meaning it got extensive review and input from many other DID connoisseurs deep in the trenches of DID method design and “user research” as to what use-cases developers really want DIDs for in the first place. Having previously incubated other DID methods in the Sidetree family, early versions of the KERI system, and the did:peer specifications foundational to DIDComm, DIF is happy to see another DIF-incubated DID method graduate to v1!
If you’re hearing about did:webvh for the very first time here and now, let’s start at the beginning with a few high-level differences between did:web and did:webvh:
- The VH stands for Verifiable History. Each DID version links cryptographically (“chains”) back to its predecessor and ultimately to the verifiable self-certifying identifier (SCID) that is embedded in the DID identifier. The SCID is derived from the DID’s initial state. Further, each update is signed by a key authorized to update the DID.
- Each valid did:webvh (the URL) can be easily and deterministically translate to a did:web. Just delete the “vh” in the method segment and the subsequent segment (the “SCID” — self-certifying identifier), and you have a valid did:web identifier. Resolve that the way you would any other did:web, and you get a valid did:web DID Document. Easy-peasy, 100% interoperability with the most widely-deployed DID method other than did:key.
- Verifiability is not dependent on DNS. While DNS is used for discovery and retrieval of the DID Log file that contains a did:webvh history, the cryptographic verifiability of that history is not dependent on DNS. The DID Log can be retrieved from other locations/caches and fully verifies the history of its corresponding DID to date.
- Verifiability is independent of its DID Documents. A did:webvh DID Doc can contain anything the DID Controller wants it to have — different keys, key types, services and so on. The verifiability of the DID is secured by a more complex resolution mechanism, not the contents of the document. That allows the specification to be very opinionated on how the DID is secured (making interoperability easy and reliable), without limiting the purpose of the DID.
- Secure DID generation can now happen off-server. This allows DID doc hosting to be separate from key management, de-risking malicious hosts and allowing for “dumber” (e.g. key-oblivious) hosting pipelines, e.g. without access to /.well-known.
- “Common sense” DID URL Handling. The simple DID URL syntax <did>/path/to/{file} maps to just what one would expect: the "/path/to/" subdirectory where the <did> document is stored.
- Cross-Host Portability. A DID on one host, if configured from inception to allow it, can migrate to a host on another domain and still keep its long-lived and globally-unique “SCID” and verifiable history. This further decouples web hosting from the long-term value of the SCID as a stable, host-independent UUID, which (webvh-aware) consumers can use to link and deduplicate DIDs which migrate across multiple hosts.
- Optional extensions allow stronger guarantees for historical resolution and duplicity/forgery detection on the part of malicious hosts. Certificate Transparency-style “witnessing networks” (a web-of-trust approach to gossiping DID document histories, also used in the KERI key management/ID system) and/or aggressively cache-busting trusted resolvers can detect host malfeasance of various kinds.
The origins of did:webvh
From the start, did:web had some production implementations that were too load-bearing to break… and many unhappy implementers. When a given website/domain only needed one collective DID (common for issuers already highly-trusted and with highly-secured websites, e.g. institutional issuers of credentials), or even in cases where the entirety of a DID’s lifecycle could be assumed to live on the same unchanging domain (e.g., employees or appointees or departments of an institutional issuer), did:web was great, and no one needed to consider upgrades.
Corner-cases and unhappy implementers kept popping up over time, though:
- What about historical resolution of old signatures after rotations and de-activations?
- What if a merger or acquisition or rebrand needs to update a domain name, but keep all its old DIDs resolving after the change?
- What if students want to keep their DIDs (or at least keep old signatures validating) after they graduate and they get incrementally locked out of their university’s IT systems?
- What if anti-trust regulations forced portability (they way they do for phone numbers) and users wanted to keep connections after switching identity providers (or “hosts” in webvh terminology?
- What if hosts are perfectly willing to issue did:webs to hundreds of users, but cannot directly automate /.well-known/ documents for each, whether due to their JS framework, choice of contractor/service-provider, security policies, etc?
- What if consumers can’t fully trust all did:web hosts to faithfully produce the same document for all callers? What duplicity-detection mechanisms or historical guarantees could be offered to those consumers?
- Similarly, some use-cases are too high-stakes to trust all hosts equally; some consumers were demanding baseline guarantees about how securely DID documents get hosted over DNS-addressed HTTP beyond what is required for did:web
A backwards-compatible “version 2” of did:web was imagined but effectively deferred for years, before work started in earnest on an heir to did:web that focused primarily on improving its trust model. As the idea kept iterating and different requirements and design goals were debated by willing co-designers, the portability guarantees came to the fore as another key goal.
This portability goal dovetailed nicely with the requirements of the Open Wallet Foundation’s ACA-Py framework, which requires DID “agents” (a kind of general-purpose “backend” for many DID and VC operations) to be smoothly swappable over time by simply updating the services property in a DID document. As ACA-Py had originally been developed for blockchain-based did:indy DIDs, there was some amount of portability, key-management, and trust-model parity that needed to be achieved, which brought a lot of other difficult design problems in tow since websites are not stateful or append-only in the way blockchains are!
Another parity goal was in achieving many of the host-independent “microledger” properties central to the KERI identifier system (and Sidetree before it), whereby the entire history of every DID can be walked to detect duplicity or other malice in any part of the system. Another KERI feature which the designers wanted to achieve was KERI’s “witnessing” properties, inspired by Certificate Transparency, which keeps hosts honest with tamper-detection and caching. This survives in optional extensions, i.e. as a distinct mechanism that consumers and hosts can opt into for stronger guarantees in resolution.
The did:webvh method's requirements informed the design and its original name, “Trust did:web”. Namely, the eponymous goal was to achieve an HTTP-published but ultimately host-independent trust layer for DID-based interactions, without a common blockchain and with more conventional cryptography and tooling than KERI requires. Trust nerds can think of this as a move from the “CA-grounded” web trust model, the only one in which did:web is usably trustworthy and secure, to one usable in a more modern “Let’s Encrypt” trust model that the web has largely moved to in recent decades.
Playing Nice in a Multi-DID World
As mentioned above, a formative goal in the design of did:webvh was smooth interoperability with did:web and did:key, as well as properties that would normally require an append-only VDR to achieve. Contrary to many DID methods which strive to stand out from the crowd by offering unique features enabled by their particular VDR or low-level mechanisms, this method sought instead to achieve a superset of features already in production today, to offer existing DID-based and DID-like systems a beter option to migrate to or translate to. Anything permitted in the DID Core specification is available in did:webvh — no restrictions! If the early phase of DID design was one of innovation and experimentation, did:webvh strives to consolidate and unite in this phase marked by convergence and productionization.
A good example of this is how did:webvh appends a digest (which can be used as a checksum) of the DID log entry to the id property of each DID document. In the HTTP context, this makes each DID document “tamper-evident” thus reducing many of the opportunities for a malicious did:web host to produce inaccurate or adulterated DID documents on behalf of a DID controller. This also makes all did:webvh DIDs “self-certifying,” in the sense that their documents’ integrity can always be checked against this checksum. Similarly, the provenance back to inception of updated DID documents can be integrity-protected and proven by the same “SCID” (Self-Certifying Identifier) mechanism.
SCIDs are a powerful design pattern, which undergird early IPFS-based DID methods like did:ipid and the Sidetree methods like did:ion and did:element, both of which were incubated in the DID Sidetree WG and used the IPFS identifier scheme to address each DID document by its hash. Older mechanisms of hash-identification include RFC 6920, which underwrites the recent did:ni method; newer examples include did:iscc and the growing body of SubResource Integrity specs at W3C that allow location-independent, self-certifying identifiers for slow-moving, cacheable web resources. KERI pushed SCIDs to the fore and influenced a lot of design work at ToIP, but zooming out a little they can be seen across modern web development as a powerful counterbalance to the “same-domain principle” of modern web security.
SCIDs are also crucial to lots of ongoing design work at ToIP and elsewhere, such as the First Person Project which mandates the portability and self-certifying properties described above for ANY DID used across a wide patchwork of infrastructures and tooling. Does that mean any SCIDs will do? Can a did:webplus, used in the OCI ecosystem, be translated to a did:webvh, or a did:scid to let a controller of a did:webplus be part of such a bridged network?
Similarly, the optional witness and watcher capabilities defined in the did:webvh specification were defined to be open-ended building-blocks as well. The specification defines a clean and simple technical mechanism for each capability to ensure interoperability between different applications of these, while leaving use-cases and ecosystem-specific governance questions outside the specification, where they belong. One application of these has been to backfill the did:indy concept of "endorsers" in a web-based VDR, but many other trust mechanisms or policy engines could be built combining DID logs and witnesses and/or watchers. The did:webvh Work Item at DIF welcomes implementors with divergent use-cases and policy assumptions to collaborate on profiling these capabilities and specifying them in more detail in ongoing work.
These broader questions of interoperability beyond the boundaries of any one DID method are increasingly being tackled in other workstreams at DIF. One of these isthe DID Traits evaluative specification (which also hit V1.0 recently!) which defines shared or equivalent/translatable properties across methods to facilitate bridging and converging DID systems. Similarly, the DID Methods WG is trying to draw attention to how well DIDs can be combined or translated, as well as how “production-grade” their implementations can be tested (or even audited) to be. WebVH is the first method being evaluated for production-readiness and documentation completeness, literally setting the bar for others!
Where to from here?
Having reached v1.0, the focus will now turn to refinements and adoption, working with implementers and deployers to gather feedback and grow their numbers. Innovators are encouraged to review the didwebvh.info website and walk through the basic step-by-step "Understanding did:webvh". Checkout the Implementations page to find the did:webvh tooling you need for your initiatives, including three mature and complete implementations in Python, in TypeScript, (both incubated by the Government of British Columbia, Canada) and in Rust, recently contributed to DIF by Affinidi. There is lots of tooling to use in getting started, and the clean specification and interoperability tools make it easy if you want to build from scratch. Implementors are welcome to use the mature tooling available, and contributions are welcome to make it easier to understand and deploy deployments rooted in did:webvh DIDs!