Protocols¶
The DID WebVH Server implements three core protocols for DID management: connecting to witness services, requesting DID paths, and creating log entries.
Connecting to a Witness Service¶
Witnesses advertise their onboarding invitations through the server's DID document. This protocol enables controllers to discover and connect to witness services.
Protocol Flow¶
-
Collect Inputs
- WebVH server base URL (e.g.,
https://did.example.org) - Witness DID (
did:key:z6Mk...)
- WebVH server base URL (e.g.,
-
Resolve the Server DID
- GET
https://did.example.org/.well-known/did.json - The document contains a
servicearray generated from the known witness registry - Each service entry represents an available witness
- GET
-
Locate the Witness Entry
- Find the service object whose
idmatches the witness DID - Verify the service
typeisWitnessInvitation - Extract the
serviceEndpointURL
- Find the service object whose
-
Retrieve the Invitation
- The
serviceEndpointis a short URL:https://{domain}/api/invitations?_oobid={witness_key} - GET the short URL to retrieve the full invitation as JSON
- The invitation contains a DIDComm Out-of-Band invitation payload
- The
-
Establish Connection
- Use the invitation URL with your agent/connector to initiate the DIDComm relationship
- The witness service will handle the connection protocol
Example¶
# 1. Get server DID document
curl https://did.example.org/.well-known/did.json
# Response includes:
{
"service": [
{
"id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
"type": "WitnessInvitation",
"serviceEndpoint": "https://did.example.org/api/invitations?_oobid=z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
"name": "Example Witness Service"
}
]
}
# 2. Retrieve invitation from short URL
curl "https://did.example.org/api/invitations?_oobid=z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
# Returns full invitation JSON
{
"@type": "https://didcomm.org/out-of-band/1.1/invitation",
"@id": "inv-example-123",
"label": "Example Witness Service",
"goal_code": "witness-service",
"services": [...]
}
Requesting a DID Path¶
This protocol enables clients to request DID creation parameters from the server. The server returns policy-driven parameters that must be used when creating the DID.
Protocol Flow¶
-
Request Parameters
- GET
/?namespace={namespace}&alias={alias} - Both
namespaceandaliasare required query parameters - The server validates that the namespace is not reserved
- The server checks if the alias is already in use
- GET
-
Server Response
- Returns policy-driven parameters including:
versionId: SCID placeholder for the DIDversionTime: Current timestampparameters: Policy-driven configurationmethod: WebVH method versionwitness: Witness requirements (threshold and witness list)portable: Portability settingupdateKeys: Required update keysnextKeyHashes: Prerotation requirementswatchers: Optional watcher URLs
state: Initial DID document stateproof: Proof options for signing
- Returns policy-driven parameters including:
-
Use Parameters
- Client uses these parameters to construct the initial log entry
- Client must sign the log entry according to the proof options
- Client must obtain witness signatures if required by policy
Example¶
# Request DID path
curl "https://did.example.org/?namespace=example&alias=my-did"
# Response:
{
"versionId": "{SCID}",
"versionTime": "2024-01-15T10:30:00Z",
"parameters": {
"method": "did:webvh:1.0",
"witness": {
"threshold": 1,
"witnesses": [
{"id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"}
]
},
"portable": true,
"updateKeys": [],
"nextKeyHashes": []
},
"state": {
"@context": ["https://www.w3.org/ns/did/v1"],
"id": "did:webvh:{SCID}:did.example.org:example:my-did"
},
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"proofPurpose": "assertionMethod"
}
}
Error Cases¶
- 400 Bad Request: Missing namespace or alias
- 409 Conflict: Alias already exists
- 400 Bad Request: Namespace is reserved (e.g.,
admin,explorer,server,tails)
Creating a Log Entry¶
This protocol enables clients to create or update DIDs by submitting log entries. Each log entry represents a state change in the DID's history.
Protocol Flow¶
-
Prepare Log Entry
- Construct a log entry using parameters from "Requesting a DID Path"
- Include:
versionId: Unique identifier for this log entryversionTime: Timestamp for this entryparameters: Policy parameters (may differ from initial request for updates)state: DID document state at this pointproof: Data Integrity Proof signed by the DID controller
-
Obtain Witness Signature (if required)
- If server policy requires witnesses, request signatures from witness services
- Witness signs the log entry using their witness key
- Include witness signature in the request
-
Submit Log Entry
- POST
/{namespace}/{alias} - Body:
- POST
-
Server Processing
- Server validates the log entry structure
- Server verifies the controller's proof
- Server verifies witness signatures (if required)
- Server enforces policy compliance
- Server updates or creates the DID record
-
Response
- 201 Created: New DID created successfully
- 200 OK: DID updated successfully
- 400 Bad Request: Validation error or policy violation
Example¶
# Create initial log entry
curl -X POST "https://did.example.org/example/my-did" \
-H "Content-Type: application/json" \
-d '{
"logEntry": {
"versionId": "abc123",
"versionTime": "2024-01-15T10:30:00Z",
"parameters": {
"method": "did:webvh:1.0",
"witness": {
"threshold": 1,
"witnesses": [{"id": "did:key:z6Mk..."}]
}
},
"state": {
"@context": ["https://www.w3.org/ns/did/v1"],
"id": "did:webvh:abc123:did.example.org:example:my-did",
"verificationMethod": [...]
},
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"proofPurpose": "assertionMethod",
"verificationMethod": "...",
"proofValue": "..."
}
},
"witnessSignature": {
"versionId": "abc123",
"proof": [{
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:key:z6Mk...#witness",
"proofValue": "..."
}]
}
}'
Policy Enforcement¶
The server enforces policies during log entry creation: - Witness Requirements: Validates witness signatures match policy requirements - Method Version: Ensures correct WebVH method version - Portability: Validates portability settings - Prerotation: Checks next key hashes if prerotation is required - Update Keys: Validates update key authorization - Deactivation: Handles DID deactivation requests
Update vs. Create¶
- Create: First log entry for a namespace/alias combination
- Update: Subsequent log entries that modify the DID state
- The server automatically determines create vs. update based on existing records