Skip to content

The did:webvh Test Suite

The did:webvh Test Suite is an interoperability and conformance test suite for did:webvh v1.0. It checks that did:webvh implementations produce DID logs that other implementations can resolve, that they resolve each other's logs to the same results, and that they reject logs that are invalid.

How It Works

The test suite has no single "reference" implementation. Every implementation is tested against every other one, and the specification and the DIF did:webvh Work Item decide which behaviour is correct.

  1. Scenarios. Each test scenario is a small, language-agnostic YAML script (vectors/<scenario>/script.yaml) that describes the steps to run: create a DID, update it, rotate keys, add witnesses, deactivate it, and resolve it. Keys are derived from fixed seeds, so running a script again gives the same output.
  2. Generation. Each implementation runs the scripts with its own library, and commits the DID logs (did.jsonl, and did-witness.json where needed) and resolution results it produces under vectors/<scenario>/<impl>/.
  3. Cross-resolution. Each implementation then resolves the logs that every implementation committed, including its own, and compares its output with the committed results.
  4. Results. Each implementation's results are written to implementations/<impl>/status.md, with the details of any differences in diffs.txt.

An implementation resolving its own logs should always match exactly. A difference when resolving another implementation's logs means the two resolvers genuinely disagree. Results are compared after JCS canonicalisation, so key ordering and whitespace don't count, but nothing else is normalised. Each difference is either a bug in an implementation or a question for the Working Group about what the specification means.

Each implementation is built and run in its own Docker container, so the only thing you need to run the test suite is Docker. It can also be run against a branch or a fork of an implementation's library, so a fix can be checked before it is merged.

What Is Tested

Valid DIDs. Scenarios that each implementation creates and that every implementation resolves:

Scenario What it covers
basic-create Create a DID and resolve it
basic-update Create, then update once
multi-update Create, then update twice; resolve each version
key-rotation Rotate the update key
multiple-update-keys Two update keys; an update signed by the second
pre-rotation Create with a pre-rotation commitment (nextKeyHashes)
pre-rotation-consume Update signed by a pre-rotated key
witness-threshold Witnessed DID, with witness proofs
witness-update Change the witness configuration from 2-of-2 to 1-of-1
portable Create a portable DID
portable-move Move a portable DID to a new domain
services Add services
deactivate Deactivate a DID

Invalid DIDs. The negative-* scenarios are DID logs and DIDs that a conforming resolver must reject, each with the error it is expected to return. Each one comes from a real security bug found in an audit of several implementations, covering things such as witness proofs replayed from another DID, duplicate witnesses, a witness threshold of zero, SCID mismatches, path traversal and percent-encoding tricks in the DID, a non-increasing or future versionTime, and an unknown method version. See the negative test vectors for the full list.

Implementations and Results

The following implementations are in the test suite. Follow the links for each implementation's latest results.

Implementation Library Results
TypeScript didwebvh-ts status
Python didwebvh-py status
Rust didwebvh-rs status
Java (DIF) didwebvh-java status
Java (EECC) european-epc-competence-center/didwebvh status
Dart didwebvh-dart status
ThisDID (resolver only) thisdid status

ThisDID is a universal resolver, so it only resolves the other implementations' logs and doesn't generate its own.

Each status.md has three sections: DID Creation (did the implementation generate its own logs for each scenario?), Negative Resolution (did it reject each invalid log?), and Cross-Resolution (did it resolve every implementation's logs to the expected result?). Results are marked:

  • ✅ PASS: an exact match.
  • 🔶 DIFF: the DID resolved, but the result differs from the committed one.
  • ❌ FAIL: resolution failed, or an invalid log was accepted.
  • ⚠️ SKIP: the implementation doesn't support that scenario.

Adding Your Implementation

If you have a did:webvh implementation, please add it to the test suite. You'll need a Docker build for your library and a small harness that reads the scenario scripts, writes your implementation's logs and resolution results, and resolves the other implementations' logs. The existing implementations in the repository's implementations/ folder are the best starting point. See the did:webvh Test Suite repository for the details, and raise an issue or pull request there.