1 of 27

did:webvh — Getting to v1.0

2025.03.03 — OWF Wallet Interoperability SIG

2 of 27

Agenda

  • Introduction
  • Benefit/Cost: Ledger-based DIDs, did:web
  • did:webvh is did:web + Verifiable History (and more…)
  • Getting to did:webvh v1.0
  • The did:webvh AnonCreds Method, Attested Resources, and Demo

3 of 27

What makes DIDs Great?

  • The DID Controller controls creation/updating/publication of its own identifier
  • Given the DID (such as in a VC), anyone can resolve it and get the DIDDoc
  • The DIDDoc holds public keys, services, and more
    • The DID Controller can update the public key(s) without changing the DID
    • Arbitrary types of keys can be published in the DIDDoc — flexible, single purpose
  • DIDs can be published in many types of places, supporting many use cases
    • Getting the DIDDoc is dependent on the DID Method (and their 200+ DID Methods)
    • Once retrieved the DIDDocs are used in the same way, regardless of the source.
      • Assuming they all follow the standard…
  • Some DID Methods allow access to the full history of a DID
    • All the keys…

4 of 27

Pros and Cons: Ledger-base DIDs

  • Immutable: once a version of a DID is written it can’t be changed
  • Ledgers can store a chain of immutable versions of a DID
  • The DIDs are replicated across the network nodes — more robust
    • And creation/updates are signed / attested to by the nodes of the ledger
  • No need to contact the issuer to get the DIDDoc
  • Long lasting – as long as the ledger lives, independent of the Controller
    • But…ledgers can disappear…
  • In some cases: Governance over the ledger (permissioned)
  • But…ledgers are hard to run…
    • Especially ones that don’t have cryptocurrencies
    • … and ones that have cryptocurrencies

5 of 27

Pros and Cons: did:web DIDs

  • Easy to publish a DID – just put a file on a web server
    • Can be both indirectly and directly linked to the domain and hence, the DID Controller entity
    • DON’T rely on a visual inspection!!!!
  • No versioning: Rotate the DID, and the old DIDDoc is gone (poof!)
    • Anything using the old keys is “unusable” – e.g. a VC signed with the old key.
  • If DID is updated, no “proof” that the DID Controller actually made the change
  • Web location (and DID!) could disappear – merger, lost domain, etc.
  • May require a “call home” to get the DID and related resources
    • Although DIDs can be put anywhere – platforms, GitHub, etc.

6 of 27

What Holds Back DID Usage?

  • DIDs on ledgers are hard
  • did:web DIDs are OK, but lacking necessary capabilities
  • There are so many DID Methods — what should I do??
  • No DID Methods are “standardized” — recognized by a Standards Organization
  • x509 Certificates “kind of work”
    • Not intended for use on other than the browsers and web sites, but hey, they have keys…
    • …but no history

7 of 27

8 of 27

Introducing did:webvh

did:webvh:58xwpye628k4453w5pezqxnnzddz:aviary.id

resolves to

https://aviary.id/.well-known/did.jsonl

Self Certifying Identifier (SCID)

9 of 27

did:webvh is did:web + Verifiable History

  • Verifiable DID version history
    • Each version is an entry in a log that includes the DIDDoc and data to verify the version.
    • A resolver retrieves and processes the log, verifying each version of the log.
    • Parameters configure the DID and (potentially) each version of the DID (long-lasting DIDs)
    • Data format is JSON Lines — often used for streaming data

{ versionId, versionTime, parameters, DIDDoc, dataIntegrityProof }�{ versionId, versionTime, parameters, DIDDoc, dataIntegrityProof }�{ versionId, versionTime, parameters, DIDDoc, dataIntegrityProof }

10 of 27

did:webvh is did:web + Verifiable History

  • Self-certifying identifier verifies the creation of the DID – 44 character string
    • did:webvh:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example
  • List of keys authorized to update the DID (with optional pre-rotation keys)
  • Proof from one of the authorized keys is required to rotate a DID
  • Versions are chained so you can’t add a version in the middle (ledger-like)
  • Optional: External “witnesses” that sign a version update (...and watchers)

Version 1

SCID of DID

Version 3

Version 2

Hash of Ver. 1

Hash of Ver. 2

SCID of DID

11 of 27

did:webvh is did:web + Verifiable History

  • Can publish with a did:web
    • Publish both the did.json and the did.jsonl files
    • Mutual “alsoKnowAs” entries in the DIDDoc for
  • Works in concert with High Assurance DIDs with DNS spec.
  • Potential roadmap: did:webvh might become did:web
    • Thoughts??

12 of 27

Log Entry: versionId, versionTime, parameters, diddoc, proof

{"versionId": "1-QmQq6Kg4ZZ1p49znzxnWmes4LkkWgMWLrnrfPre8UD56bz", "versionTime": "2024-09-26T23:22:26Z", "parameters": {"updateKeys": ["z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R"], "nextKeyHashes": ["QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33"], "method": "did:webvh:0.5", "scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ"}, "state": {"@context": ["https://www.w3.org/ns/did/v1"], "id": "did:webvh:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"}, "proof": [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R", "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", "proofValue": "z2fPF6fMewtV15kji2N432R7RjmmFs8p7MiSHSTM9FoVmJPtc3JUuZ472pZKoWgZDuT75EDwkGmZbK8ZKVF55pXvx"}]}

13 of 27

Dependencies

14 of 27

did:webvh is did:web + Verifiable History … and more!

  • Implicitly defined access to resources
    • The path of a DID resolves to a file on the same web server at the relative location
    • Example:
      • did:webvh:<scid>:example.com/statuslist/serving-it-right/1.0/statuslist.vc
        • becomes
      • https://example.com/statuslist/serving-it-right/1.0/statuslist.vc
        • and resolves to a Status List Revocation VC

15 of 27

did:webvh is did:web + Verifiable History … and more!

  • Portability
    • A DID MAY move to another place and retain the SCID and history (and reputation)
      • did:webvh:<scid>:example.comdid:webvh:<scid>:new.home.com
      • did:webvh:<scid>:google.com/stephen.curran
        • did:webvh:<scid>:yahoo.com/stephen.curran

16 of 27

did:webvh is did:web + Verifiable History … and more!

  • Additional security mechanisms — witnesses, watchers
    • Specification contains only a simple definition of the features
    • The “hard work” is left to specific deployments
      • Governance, protocols, etc. are outside the scope of the specification

17 of 27

did:webvh in the Real World

  • Process
    • An issuer/verifier creates a did:webvh DID/DIDDoc using something like ACA-Py/Traction
    • They follow the rules of their did:webvh Server to publish the DID
      • Governance, witnessing, watchers, etc.
    • They publish other resources to the did:webvh Server — AnonCreds objects, OCA Files, etc.
    • They use the key(s) published in their DIDDoc to sign/decrypt data
      • Others resolve the DID to verify/encrypt data
    • The DID Controller creates an updated DIDDoc and publishes that — adding a new entry to the log
      • Authorizing the update, having it witnessed, watched, etc.
    • And so on…

18 of 27

Specification and Implementation Status

  • Currently at v0.5
  • 5 implementations/3 open source — each providing feedback into the spec.
  • Information site: https://didwebvh.info
  • Registered in the DID Methods Registry (PR)
  • Available in the Universal Resolver

19 of 27

Specification Status Part 2

  • V1.0 — close!
    • Remove weight from the witnesses and the threshold algorithm
    • Clarification of the DID-to-HTTPS Transformation to deal with internationalization
    • Add the concept of Watchers
      • URLs of services that have agreed (somehow) to “watch” a did:webvh
      • Technically limited:
        • watchers listed in the parameters.
        • Each watcher **MUST** respond to two endpoints:
          • GET <URL>?scid=<scid> — returns the DID Log, witness proofs of the SCID
          • POST <URL>?scid=<scid> — a webhook meaning “DID updated”
    • Clarifications — e.g. error codes

20 of 27

Roadmap

  • Finalize the specification — and move to standardization
    • Perhaps including aligning with a proposed did:scid DID “Meta-Method”
  • did:webvh Server
    • Separation from the DID Controller — create, rotate, use — and publication of the DID
    • Resource hosting
      • AnonCreds support as the first example
  • Implementations!
    • Standalone resolver library
    • ACA-Py, Credo-TS, Bifold Wallet — with full AnonCreds support
    • Reference witness
    • Reference watcher
      • Long-lived resolution — independent of the DID Controller

21 of 27

Demonstration of Progress:

The did:webvh AnonCreds Method

22 of 27

Background

  • AnonCreds Methods — how to use AnonCreds with a given DID Method
  • Defines how to publish/resolve AnonCreds JSON objects:
    • Schema — list of attributes in a type of VC
    • CredDef — the public keys for a type of VC from a specific issuer
    • RevRegDef — a revocation registry for a given CredDef (public key, metadata)
    • RevRegEntry — the state of a revocation registry at a certain timestamp for a given CredDef
      • Resolvers need the full history of entries — “was a given VC revoked at a given time?”
  • Historically — published on a ledger, with some verifiability

23 of 27

Attested Resources

  • Defined currently in the did:webvh AnonCreds Method
  • Gives verifiability to the resources associated with a DID
  • Definition:
    • Resources are a JSON object — “resource”: { <resource> }
      • Schema, CredDef, etc.
    • Resources are embedded within a JSON-LD Attested Resource with metadata, and a proof
    • An identifier for the resource is generated whose last element is a hash of the resource
      • This gives an immutability proof, since a resolver gets the identifier and resolves it.
    • A proof is added by the DID Controller across the entire attested resource object
  • Easy for all except RevRegEntry objects…
    • Trickery detailed in the did:webvh AnonCreds Method

24 of 27

25 of 27

One more thing…/whois

  • Super clever idea that should be part of all DIDs, but really easy in did:webvh
    • Returns a Verifiable Presentation signed by the DID.
    • The VP contains Verifiable Credential about the DID from other issuers
    • The VP resides beside the did.jsonl file — https request.
  • The VCs are from authorities:
    • A VC that binds a legal entity identifier and the DID
    • Permits, licenses and registrations from Government
    • Credentials from auditors
    • Membership credentials from Trust Registries
  • Goal: Separate spec that applies to ALL DID Methods
    • Have approval at DIF to incubate the spec — just need some time

26 of 27

Using /whois in the Real World

  • You receive a DID you don’t know — how do you decide to trust it?
  • The /whois Process:
    • Check a local list of “known DIDs”. If trusted / not trusted, stop.
    • Resolve <did>/whois
      • Loop
        • Find a verified VC and issuer DID you know? Stop.
        • Use those issuer DIDs and for each, resolve their <did>/whois
      • Repeat until you stop or there is no VP for a DID (top of the hierarchy).
    • At the end:
      • You found a DID you trust / don’t trust the DID, or
      • Pass the collected data to human to decide
        • Add the human results to the local list
        • Periodically — re-evaluate the local list

27 of 27

And that’s did:webvh