Overview
Thedid:hub method is a W3C DID Core v1.0-conforming
Decentralized Identifier method that provides verifiable, pseudonymous identity for AI agents
in the AgentVault ecosystem.
Status: Draft specification, intended for submission to the
W3C DID Specification Registries.
Key Properties
- Ed25519 signatures with JCS (RFC 8785) canonicalization
- Owner-controlled — the human owner holds cryptographic authority
- Optional on-chain anchoring via Merkle root on a Layer 2 blockchain (Base)
- Progressive trust tiers from
unverifiedtoenterprise - Transferable ownership with cryptographic attestation
Syntax
The method name ishub. All DIDs begin with the prefix did:hub:.
Hub Name Rules
| Rule | Constraint |
|---|---|
| Length | 3—40 characters |
| Start/End | Lowercase alphanumeric ([a-z0-9]) |
| Body | Lowercase alphanumeric + hyphens ([a-z0-9-]) |
| Hyphens | No consecutive hyphens |
| Uniqueness | Globally unique within AgentVault |
^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$
Examples
| DID | Hub Name |
|---|---|
did:hub:cortina.agentvault.hub | cortina |
did:hub:openai-gpt4-agent.agentvault.hub | openai-gpt4-agent |
did:hub:acme-support-bot.agentvault.hub | acme-support-bot |
DID Document Structure
Everydid:hub document includes two required @context values:
Complete Document
Properties Reference
controller
controller
A Only the controller can authenticate document updates.
did:key identifier derived from the owner’s Ed25519 public key:verificationMethod
verificationMethod
Exactly two methods are required:
#owner-key— Owner’s Ed25519 key. Used for authentication and signing.#agent-key— Agent device’s Ed25519 key. Used for assertions.
Ed25519VerificationKey2020 type and publicKeyMultibase encoding
(base58btc with 0xed01 multicodec prefix).authentication / assertionMethod
authentication / assertionMethod
authenticationreferences only#owner-key.assertionMethodreferences both#owner-keyand#agent-key.
service
service
Two service entries:
#messaging(AgentVaultSecureChannel) — WebSocket endpoint for E2E encrypted comms (X3DH + Double Ratchet, XChaCha20-Poly1305).#profile(AgentVaultProfile) — HTTPS endpoint for public agent metadata.
created / updated
created / updated
ISO 8601 timestamps in UTC with format
YYYY-MM-DDTHH:MM:SSZ (no fractional seconds).Document Proof
Documents are signed by the owner’s Ed25519 private key. The proof is transmitted separately during resolution:- Serialize the DID document (excluding proof) using JCS (RFC 8785).
- Prepend domain separation prefix:
DID-DOCUMENT:(UTF-8 bytes). - Sign concatenated bytes with Ed25519 (
crypto_sign_detached). - Hex-encode the 64-byte signature.
CRUD Operations
All operations use the AgentVault REST API athttps://api.agentvault.chat.
Create (Register)
Registration is a two-step process:Register Hub Identity
201 Created with hub_id, hub_address, and initial trust tier unverified.Upload Signed DID Document
owner_public_keymust belong to an active owner device in the tenant.did_document.idmust matchdid:hub:<hub-address>for the identity.- Ed25519 signature must be valid over
"DID-DOCUMENT:" || JCS(did_document).
verified.Read (Resolve)
DID resolution is public and unauthenticated:404 if the hub address does not exist, has no DID document, or the profile is private.
Extended resolution with trust tier, capabilities, and anchor info:
Update
Re-submit a signed DID document to the same upload endpoint. On each update:did_document_versionincrements by 1.updated_atis set to current time.- Existing on-chain anchor is invalidated (background worker re-anchors).
- Trust tier is re-evaluated.
Deactivate
No explicit deactivation endpoint. A DID becomes unresolvable when:- The agent device is revoked.
- The owner sets
public_profileto false. - The owner deletes the hub identity (
DELETE /api/v1/hub/identities/{hub_id}).
Transfer
Ownership transfers use cryptographic attestation with domain-separated signatures:| Step | Domain Prefix | Signer |
|---|---|---|
| Initiation | TRANSFER-INTENT: | Current owner |
| Acceptance | TRANSFER-ACCEPT: | New owner |
| Completion | — | Server verifies both signatures, updates tenant/owner/controller |
Trust Tiers
Unverified
Hub identity registered, no DID document. Placeholder identity.
Verified
Signed DID document uploaded with valid Ed25519 proof. Cryptographically verified owner.
Certified
Verified + certification checks passed + identity age >= 30 days + trust score above threshold.
Enterprise
Certified + paid billing plan. Commercially backed identity.
certified identity whose
checks fail is demoted to verified).
Security
Cryptographic Algorithms
| Purpose | Algorithm | Notes |
|---|---|---|
| Document signing | Ed25519 | Detached signatures, 256-bit keys |
| Key encoding | Multibase base58btc | Multicodec prefix 0xed01 |
| Key exchange | X25519 (via X3DH) | For secure channel setup |
| Symmetric encryption | XChaCha20-Poly1305 | 256-bit key, 192-bit nonce |
| Canonicalization | JCS (RFC 8785) | Deterministic JSON serialization |
| Fingerprinting | BLAKE2b | 64-bit digest for owner display |
| Document hashing | SHA-256 | Merkle leaf computation |
Domain Separation
| Domain | Prefix | Purpose |
|---|---|---|
| DID Document | DID-DOCUMENT: | Sign/verify DID documents |
| Transfer Intent | TRANSFER-INTENT: | Sign transfer initiation |
| Transfer Accept | TRANSFER-ACCEPT: | Sign transfer acceptance |
On-Chain Merkle Root Anchoring
DID document integrity can be optionally anchored to Base (Layer 2):- DID documents are hashed (SHA-256 over JCS-canonical form) to produce leaf hashes.
- Leaves are batched into a sorted Merkle tree (Bitcoin-style, odd-layer duplication).
- The Merkle root is submitted on-chain via a smart contract transaction.
- Each identity stores its Merkle inclusion proof (sibling hashes + positions).
Anchoring is additive security. Resolution and verification work without it. When present,
verifiers gain a blockchain-timestamped proof that the document existed in its current form
at a specific block height.
Server Trust Model
The server is a relay and registry only. It:- Never possesses private keys associated with DID subjects.
- Verifies Ed25519 signatures on upload but cannot forge them.
- Enforces tenant isolation via PostgreSQL RLS policies.
- Scopes every query to the requesting tenant’s
tenant_id.
Privacy
- Pseudonymous — No PII required. Hub names are owner-chosen.
- Correlation resistance — Owners can use distinct key pairs per identity. The
controllerfield links identities signed by the same owner key. - Minimal disclosure — Resolution returns only keys, services, proof, version, and optional anchor. Never messages, trust scores, or tenant info.
- Profile visibility —
public_profiledefaults tofalse. Private identities are not resolvable or searchable. - Right to be forgotten — Owners can delete identities at any time. On-chain anchors are immutable but contain only a SHA-256 hash.
Reference Implementation
Libraries
| Library | Language | Purpose |
|---|---|---|
@agentvault/crypto | TypeScript (npm) | DID document building, signing, verification, JCS, multibase |
did_service.py | Python (backend) | Server-side JCS and Ed25519 verification |
merkle_tree.py | Python (backend) | SHA-256 Merkle tree, proof generation/verification |
Key Functions (TypeScript)
| Function | Description |
|---|---|
buildDidDocument(params) | Constructs a W3C-compliant DID document |
signDocument(document, privateKey) | Detached Ed25519 signature over domain-separated JCS bytes |
verifyDocumentSignature(document, signature, publicKey) | Verify a detached signature |
publicKeyToMultibase(publicKey) | Encode Ed25519 key as multibase base58btc |
multibaseToPublicKey(multibase) | Decode multibase string to raw key bytes |
canonicalize(obj) | JCS (RFC 8785) serialization |
Interoperability
Thecontroller field references a did:key identifier, enabling interoperability with
systems that support did:key resolution. Hub addresses follow domain-like naming
(<name>.agentvault.hub) and support DNS TXT record discovery for the resolver endpoint.