Repository navigation
did:webvh and did:web: key rotation, and signing with your own domain - #25
Open
harlantwood wants to merge 2 commits into
Open
harlantwood wants to merge 2 commits into
harlantwood wants to merge 2 commits into
Conversation
Core (pure, no I/O): - did: DID document model (DID 1.1 / Controlled Identifiers 1.0, Multikey + publicKeyMultibase, assertionMethod), did:key documents, sign_atom_as / verify_atom_with against a resolved document. - did::web: DID-to-HTTPS mapping for did:web and did:webvh (ports, paths, punycode). - did::webvh: own implementation of DIF did:webvh v1.0 log verification (SCID, entry-hash chain, update-key proofs, pre-rotation, portability, deactivation, witnesses), creation, append and key rotation, historical resolution by proof time. Passes the DIF didwebvh-test-suite vectors and a 120-entry didwebvh-rs log; didwebvh-rs was not used because it pulls tokio and getrandom. - api: didDocumentUrl, resolveDidKey, resolveDidWebvh, verifyWith, exposed in WebAssembly, Node and the TypeScript types. CLI: - trust did resolve | show | web create | webvh create | webvh rotate. - HTTPS resolver (ureq 3 + rustls) with an on-disk cache; trust verify and trust add resolve did:web / did:webvh issuers; global --offline. - Signing with a key that has a did:web/webvh identity uses that DID and its verification method. Docs: doc/identity.md (which method when, GitHub Pages hosting). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UdKneRqUnsbv1t7NyvcT68
…bsuvj4 # Conflicts: # README.md # doc/plan/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
This PR adds roadmap Phase 5 "key rotation" and Phase 3 "did:web so an organization can sign with its own domain". A key can now sign as a
did:webvh(DIF Ratified v1.0) and rotate keys, with pre-rotation. Credentials signed before a rotation stay valid. A key can also sign as adid:web.The core verifies did:webvh logs purely, from their bytes. It passes the DIF did:webvh test suite. The CLI fetches DID documents over HTTPS, caches them, and supports
--offline. JavaScript hosts get the same verification throughverifyWith.Core (
trustgraph-core, still pure)did: a DID document model following DID 1.1 and Controlled Identifiers 1.0 (Multikey+publicKeyMultibase,assertionMethodreferences or embedded methods, relative#ids).DidDocument::for_did_keybuilds a did:key document locally.sign_atom_as(atom, keypair, doc, created)andverify_atom_with(credential, doc)sign and verify any issuer against a resolved document. They work for did:key too, with byte-identical output tocredential::sign_atom.did::web: maps a DID to its HTTPS URL for did:web and did:webvh. Covers ports (%3A), path segments, percent-encoding, punycode for international domain names, and rejects IP addresses and bad labels. Tested against the spec examples, includingjp納豆.例.jp.did::webvh: our own did:webvh v1.0 implementation.verify_log) checks:nowis giveneddsa-jcs-2022proofs by authorized update keys, using the spec's active-key rulesnextKeyHashes), which must be set explicitly while activestate.idalsoKnownAsmust name the previous DID)did-witness.jsonversionId,versionNumberorversionTime, with the implicit#filesand#whoisservices added.DidLog::document_at(proof.created)returns the document in force when a proof was made.create,append,create_identity,rotate_identity.didwebvh-rs0.8.0 depends ontokio,getrandom,async-traitand the affinidi crates unconditionally. That would break core purity and grow the WebAssembly build.api:did_document_url,resolve_did_key,resolve_did_webvh(did, log, options)andverify_with(credential, resolved).resolvedis either a DID document or{didLog, didWitness?}.credential.rsedits are minimal for the v1-formats merge: three constants andhash_databecomepub(crate), and nothing else changes. The proof checks indid/proof.rscopy those incredential::verify(about 30 lines). Fold them together after v1-formats lands.error.rs: newError::InvalidDidvariant.Bindings
didDocumentUrl,resolveDidKey,resolveDidWebvhandverifyWith. Types are inbindings/trustgraph.d.ts.tests/js/smoke.mjscovers them, including resolving a DIF vector.CLI
trust did resolve DID [--log FILE [--witness FILE]] [--version-id|--version-number|--version-time]prints a DID resolution result.--logverifies a log you were given and caches it, so later verification works offline.trust did webvh create --domain HOST[:PORT] [--path P] [--prerotate] [--portable] [--key NAME] [-o did.jsonl]makes key NAME sign as a did:webvh, and writes the log to publish.trust did webvh rotate [--key NAME]adds a version with a new key. With pre-rotation, it uses the committed next key and commits a fresh one. The old key is retired todids/NAME.retired-N.key.json.trust did web create …andtrust did show [NAME].trust atom --sign,trust signandtrust lensuse the key's did:webvh or did:web identity when it has one. The proof'sverificationMethodis that key's id in the document (did:webvh:…#key-N).trust verifyandtrust addresolve did:web and did:webvh issuers:ureq3.4 with rustls (HTTPS only, 20 s timeout, 8 MiB limit)cache/did/, kept for the did:webvhttlor 1 h for did:web, and re-verified every time it is read--offline/TRUST_OFFLINEuses the cache only, never the network.TRUST_DID_TEST_ORIGINis a hidden, loopback-onlyhttp://origin override, used by the tests.Docs
doc/identity.md: which DID method to use when, how creating and rotating work, what verification checks, the JavaScript usage, how to host on GitHub Pages (including the.nojekylltrap for/.well-known/), and the files in the trust home.Verified
cargo fmt --all --checkcargo clippy --workspace --all-targets --lockedon stable, and withRUSTFLAGS=-D warningson+1.99(workspace and-p trustgraph-core)cargo clippy --target wasm32-unknown-unknown -p trustgraph-core -p trustgraph-wasmRUSTDOCFLAGS=-D warnings cargo doc --workspace --no-deps --lockedscripts/check-core-purity.shcargo test --workspace --lockedon stable and on 1.85 (MSRV)7be2491, as bundled with didwebvh-rs 0.8.0): 12 scenarios, compared on the fulldidDocumentand on metadata. This includes pre-rotation, witnesses, portable moves, deactivation and services.pnpm run build:node && pnpm run test:node,scripts/build-wasm-package.sh, the smoke test on wasm-node and wasm-web, andpnpm run typecheck.Owner decisions / notes
witness-update: an entry lowers its own witness threshold and carries only one proof.{SCID}instead of the previousversionId.did/v1+multikey/v1contexts, as the did:webvh vectors do. DID 1.1 is still a Candidate Recommendation.Not in this PR
appendsupports all of these, and verification already handles them.did:webfrom a did:webvh.did:plc.credential.rsafter v1-formats lands.ureq, deduplicate the workspace entry (ureq = "3.4").🤖 Generated with Claude Code
https://claude.ai/code/session_01UdKneRqUnsbv1t7NyvcT68
Generated by Claude Code