DID Document Management
The service can create Decentralized Identifiers (DIDs) and serve their DID documents. Two DID methods are created: did:key (a deterministic Ed25519 key-based DID) and did:web (a DID whose document is hosted by the service itself over HTTPS). A did:web document is stored server-side and published at a stable, UUID-keyed URL so that other parties can resolve it.
DIDs are used in two places:
Platform identities for issuers and verifiers, created via the admin DID endpoints under
/agent.Holder (cloud-wallet) identities, which are provisioned automatically when a holder is created.
All endpoints below require a valid OIDC JWT Bearer token (Authorization: Bearer <token>); the /agent/* routes additionally require the admin role. In development you can bypass auth with AUTH_DISABLED=true. The only exception is the public DID-document serving endpoint, which needs no auth.
Create a did:key
Creates a deterministic Ed25519 key-based DID. No body is required.
POST /agent/did/key
Response Body
did: the generated DID, e.g.
did:key:z6Mk....verificationMethodIds: verification method identifiers usable for signing and assertions.
curl -X POST http://localhost:3000/agent/did/key \
-H 'Authorization: Bearer <token>'{
"did": "did:key:z6MkfWg...abc",
"verificationMethodIds": ["did:key:z6MkfWg...abc#z6MkfWg...abc"]
}Create a did:web
Creates a DID whose document is hosted by the service. The DID is built as did:web:<domain>:<uuid>, where <uuid> is generated by the service and used as the public document path.
POST /agent/did/web
Request Body
domain: the hostname for the DID, without a scheme (e.g.
issuer.example.com, optionally with a port such asexample.com:8080). Required.
Response Body
did: the generated DID, e.g.
did:web:issuer.example.com:9b3c....didDocument: the full DID document JSON, including an Ed25519 verification method.
Resolve a DID
Returns the DID document for a DID created through this service (did:web or did:key). If the DID was not created here, the endpoint returns 200 with a null body — it does not resolve external DIDs.
GET /agent/did/:did
List created DIDs
Returns the DIDs created through the service.
GET /agent/dids
Holder DIDs
A holder is a per-user cloud-wallet tenant. Its DID is provisioned when the holder is created, so there is no separate DID-generation step for holders. Choose the method at creation time.
POST /agent/holder
Request Body
method:
keyorweb. Determines the DID method for the holder.domain: required when
methodisweb(hostname, e.g.example.com).label: optional human-readable label for the wallet.
Response Body
holderId: internal holder identifier (UUID) used in wallet API calls.
did: the holder's DID.
cryptographicBindingMethodsSupported, credentialSigningAlgValuesSupported: capabilities of the holder wallet.
didDocument: included only when
methodisweb.
Serve a hosted did:web document (public)
Every did:web created by the service (for an issuer, verifier, or holder) is published at a public, UUID-keyed path that matches the <uuid> segment of the DID. This endpoint requires no authentication and is exempt from rate limiting.
GET /:uuid/did.json GET /:uuid/.well-known/did.json
If no document exists for the given UUID, the service returns 404 with the standard error body { statusCode, message, path, timestamp }.
Notes
did:webdocuments are keyed by a service-generated UUID, not by any user identifier. The UUID is both the last segment of the DID and the document's public path.did:keyanddid:webverification methods use Ed25519 (EdDSA).The hostname for a
did:webcomes from thedomainfield of the create request, not from an environment variable (see Environment & Setup for the unusedDID_WEB_DOMAIN/DID_WEB_PATHvariables).did:webresolution requires HTTPS in production; for local testing only,ALLOW_INSECURE_HTTP=truepermits plain HTTP.
Last updated