Implementing a did:webvh Resolver¶
This article summarizes the process that a did:webvh resolver might use in processing a did:webvh DID. The process covers both the DID Log File processing, as well as the processing of the DID Witness Proofs file (if applicable). This article is not a specification, and there is no requirement for a did:webvh to follow this approach. It is provided to help those beginning a registrar/resolver implementation to navigate the specification (links into the specification are embedded in the algorithm) using the experience of those that have gone before. Updates to the algorithm are welcome (via Issues or PRs) from implementers wanting to make life easier for those who will follow.
This approach draws heavily from the did:webvh Python implementation at DIF.
The verification passes below may be interleaved. In particular, the did:webvh Python implementation collects log entry proofs and verifies them in a thread pool in the background while doing the primary verification. Witness log retrieval could be performed when the first witness rule is seen in the DID Log.
Primary verification¶
- Fetch
did.jsonl(Spec Ref). If not found, abort (error=notFound). - For each entry in the history log:
- Perform preliminary checks:
- Check the entry is a valid JSON object with only the required properties. (Spec Ref)
- If it is the first entry, check the SCID derivation. (Spec Ref)
- Check the derivation of the entry hash and the sequencing of the version number. (Spec Ref)
- Verify the DIDDoc ID contains the SCID.
- Verify the type, value, and validity (allowed or not) of the parameters in the Log Entry. (Spec Ref)
- If preliminary checks fail:
- Set
INVALID=true. - Move to the next verification phase.
- Set
- If a specific
versionIdis specified:- If the requested
versionIdequals the current entry'sversionId: - If a specific
versionTimeis requested and is less than the entry'sversionTime, abort (error=notFound) - cannot reconcileversionIdandversionTime. - Set
FOUNDto the current entry.
- If the requested
- If a specific
versionTimeis requested and a specificversionIdis not requested:- If the current entry's
versionTime<=versionTime: - Set
FOUNDto the current entry.
- If the current entry's
- If the current entry updates the parameters (Spec Ref)
updateKeys,nextKeyHashes, orwitness:- Add the entry to
AUTH_ENTRIES.
- Add the entry to
- If the
witnessparameter is non-null and thethresholdis non-zero (Spec Ref):- Add
(versionNumber, witness)toWITNESS_CHECKS.
- Add
- If the previous value of
witnesswas non-null and different fromwitness:- Add
(versionNumber, prevWitness)toWITNESS_CHECKS.
- Add
- Add the current entry's
versionIdtoCHECKED. - Set
LATESTto the current entry.
Proof verification¶
- If
LATESTis not set, abort (error=invalidDid) - no entries. - If
FOUNDis not set: - If
INVALID, abort (error=invalidDid) - latest version is needed, but verification short-circuited. - If a specific
versionIdorversionTimeis requested, abort (error=notFound). - Set
FOUND=LATEST. - Add
FOUNDtoAUTH_ENTRIES. - For each entry in
AUTH_ENTRIES: - Check the associated entry proof(s). There must be at least one valid proof from an active update key. (Define active keys) (Spec Ref)
- If no valid proof is found, abort (
error=invalidDid).
Witness verification¶
- If
WITNESS_CHECKSis not set, then skip to next verification phase. - Fetch
did-witness.json. If not found, abort (error=invalidDid). (Spec Ref) - For each proof in the log:
- Check the
versionIdis set and is inCHECKED, otherwise skip. - Check the validity of the proof, otherwise skip.
- Extract the version number from the
versionId. - Add
(versionNumber, witnessId)toWITNESS_VALID. - For each
(versionNumber, rule)inWITNESS_CHECKS: - Check the witness rule against
WITNESS_VALID. Each entry with a laterversionNumberand one of the requested witness IDs may add to the weight. (Don't count multiple proofs from the same witness ID.) - If the threshold of a rule is met, remove it from
WITNESS_CHECKS. (Spec Ref) - If any values remain in
WITNESS_CHECKS, abort(error=invalidDid).
Final checks¶
- For the resolved entry
FOUND, check that the ID of the document matches the resolution target. - If not, abort (
error=notFound). - Add implicit services (
#files/#whois) to the DID document as needed. (Spec Ref Files), (Spec Ref Whois) - Perform dereferencing if necessary.
- If
INVALIDis set, add (TBD) to the resolution metadata. Adjust the internal TTL to the standard 'verification failure' TTL.
TODO: define caching behavior