did:webs - Web-based DIDs with KERI Security
The did:webs DID Method (did:web + Secure, like HTTPS) was developed to enable greater trust and security than did:web without compromising the simplicity and discoverability of web-based DIDs.
did:webs is a DID Method that combines the ease of use and discoverability of did:web with the cryptographic security of KERI (Key Event Receipt Infrastructure).
Like did:web, the did:webs method uses traditional web infrastructure to publish DIDs and make them discoverable. Unlike did:web, this method's trust is not rooted in DNS, webmasters, X.509, and certificate authorities. Instead, it uses KERI to provide a secure chain of cryptographic key events by those who control the identifier.
did:webs:example.com%3A3000:users:alice:EKYGGh-FtAphGmSZbsuBs_t4qpsjYJ2ZqvMKluq9OxmP
│ │ │ │ │ │
│ │ │ │ │ └─ AID (KERI identifier)
│ │ │ │ └─────── Path component
│ │ │ └───────────── Path component
│ │ └────────────────── Port (URL-encoded)
│ └──────────────────────────────── Host
└──────────────────────────────────────── Method
The did:webs method provides several key features that complement did:web:
- DID Portability - Move DIDs between web locations while preserving history
- DID-to-HTTPS transformation - Uses the same simple transformation as
did:web - Verifiable History - Complete cryptographic chain of key events from inception to present
- Self-Certifying Identifiers (SCIDs) - Globally unique identifiers derived from inception events
- Authorized Keys - DID document derived from KERI and ACDC artifacts from authorized keys, literally from a CESR stream.
- Pre-rotation Keys - Prevents loss of control if active keys are compromised
- End-Verifiable Data - Trust derives from cryptography, not web infrastructure
A did:webs identifier looks like this:
did:webs:example.com:alice:EKYGGh-FtAphGmSZbsuBs_t4qpsjYJ2ZqvMKluq9OxmP
This DID resolves to two files on the web:
did.json- The DID document (same asdid:web)keri.cesr- The KERI event stream that proves the DID document's authenticity
The transformation is simple:
did:webs:example.com:alice:EKYGGh-FtAphGmSZbsuBs_t4qpsjYJ2ZqvMKluq9OxmP- →
https://example.com/alice/EKYGGh-FtAphGmSZbsuBs_t4qpsjYJ2ZqvMKluq9OxmP/did.json - →
https://example.com/alice/EKYGGh-FtAphGmSZbsuBs_t4qpsjYJ2ZqvMKluq9OxmP/keri.cesr
See below for a sample did.json and keri.cesr stream to illustrate the nuts and bolts of how this works.
While did:web is wonderfully simple and familiar to developers, it has security limitations:
- Trust depends on DNS, TLS certificates, and certificate authorities
- Websites can be hacked or compromised
- DNS can be hijacked
- No cryptographic proof of key history
- Centralized trust in web infrastructure
did:webs separates discovery and publication from trust:
- Discovery and Publication: Still uses familiar web infrastructure (like
did:web) - Trust: Derives from KERI's cryptographic key event logs
This preserves the convenience of did:web while drastically upgrading security through authentic, end-verifiable data.
âś… Easy to Implement - No exotic cryptography or blockchain required
âś… Scalable - Uses standard web infrastructure
âś… Secure - Cryptographic proof of key history and updates
âś… Portable - DIDs can move between web locations
âś… Interoperable - Compatible with did:web and Universal Resolver
âś… Decentralized Trust - No dependence on certificate authorities
âś… Regulatory Friendly - No blockchain concerns
Like all DID methods, did:webs makes trade-offs:
Pros:
- Cheap and easy to deploy
- No blockchain required
- Strong cryptographic security
- Transparent governance
- Scalable through delegation
Cons:
- Depends on web for publication and discovery
- Requires learning KERI concepts
- Higher bar of accountability for users
Ready to dive in? Check out:
- Quick Start Guide - Get up and running quickly
- Specification - Read the full technical specification
- Implementer's Guide - Build with did:webs
- Deployments - Try live did:webs resolvers
Here's a real working example from the GLEIF testnet:
did:webs:hook.testnet.gleif.org%3A7702:dws:ED1e8pD24aqd0dCZTQHaGpfcluPFD2ajGIY3ARgE5Yvr
You can resolve this DID at:
Or use cURL and resolve it from the GLIEF Testnet resolver instance:
curl https://hook.testnet.gleif.org:7703/1.0/identifiers/did:webs:hook.testnet.gleif.org%3A7702:dws:ED1e8pD24aqd0dCZTQHaGpfcluPFD2ajGIY3ARgE5YvrThe did.json is the DID Document generated from the keri.cesr stream or local KERI controller data store.
A sample DID document is:
{
"id": "did:web:hook.testnet.gleif.org%3A7702:dws:ED1e8pD24aqd0dCZTQHaGpfcluPFD2ajGIY3ARgE5Yvr",
"verificationMethod": [
{
"id": "#DMxPdEQMvEE1y4SD2V9moEXpe6iCIpt_6yhbxxZ1VL81",
"type": "JsonWebKey",
"controller": "did:web:hook.testnet.gleif.org%3A7702:dws:ED1e8pD24aqd0dCZTQHaGpfcluPFD2ajGIY3ARgE5Yvr",
"publicKeyJwk": {
"kid": "DMxPdEQMvEE1y4SD2V9moEXpe6iCIpt_6yhbxxZ1VL81",
"kty": "OKP",
"crv": "Ed25519",
"x": "zE90RAy8QTXLhIPZX2agRel7qIIim3_rKFvHFnVUvzU"
}
}
],
"service": [
{
"id": "#BJqHtDoLT_K_XyOgr2ejBOqD9276TYMTg2EEqWKs-V0q/witness",
"type": "witness",
"serviceEndpoint": {
"https": "https://wit1.testnet.gleif.org:5641/",
"tcp": "tcp://wit1.testnet.gleif.org:5631/"
}
}
],
"alsoKnownAs": [
"did:web:hook.testnet.gleif.org%3a7702:ED1e8pD24aqd0dCZTQHaGpfcluPFD2ajGIY3ARgE5Yvr",
"did:webs:hook.testnet.gleif.org%3a7702:ED1e8pD24aqd0dCZTQHaGpfcluPFD2ajGIY3ARgE5Yvr",
"did:web:example.com:ED1e8pD24aqd0dCZTQHaGpfcluPFD2ajGIY3ARgE5Yvr",
"did:web:foo.com:ED1e8pD24aqd0dCZTQHaGpfcluPFD2ajGIY3ARgE5Yvr",
"did:webs:foo.com:ED1e8pD24aqd0dCZTQHaGpfcluPFD2ajGIY3ARgE5Yvr"
]
}The keri.cesr file contains cryptographic artifacts the diddoc is generated from
And CESR stream for the sample did:webs DID Doc above is shown below with whitespace added for readability. Actual CESR has no whitespace.
- Specification Repository: tswg-did-method-webs-specification
- Reference Implementation: did-webs-resolver
- KERI: keri.one
- Trust Over IP: trustoverip.org