W3C did:web
Overview
did:web is a Decentralized Identifier (DID) method that utilizes existing web infrastructure. This method enables organizations to represent their identifiers through their web domains without requiring a blockchain. The did:web method follows the did:web specification and leverages standard HTTPS and DNS infrastructure for DID resolution.
When working with TradeTrust documents, the did:web method's public key is used to validate the authenticity of any TradeTrust W3C signed document. This verification step is essential as it confirms the document's integrity by checking the digital signatures using the issuer's public key from their DID document. Since TradeTrust relies on these DID documents for verification, maintaining high availability of your did:web endpoint is critical - any downtime could prevent others from verifying your documents.
How did:web Works
did:webuses standard web domain names to create DIDs in the format:did:web:example.com- The method resolves DIDs by converting them into standard HTTPS URLs.
- The DID Document is hosted at a well-known HTTPS endpoint on the domain.
Requirements
- A web domain that you control.
- Ability to host files on your web server.
- HTTPS enabled on your domain.
- Ensure your domain has a valid SSL certificate.
- Set up proper CORS headers for cross-origin requests.
Setting up did:web
Create DID Document
Before you begin, ensure you have Node.js installed on your system.
- ECDSA-SD-2023 (Default)
- BBS-2023
- Using CLI
- Install the package:
npm install @trustvc/trustvc
- Create a script to generate the DID:
import { issuer } from "@trustvc/trustvc";
const { issueDID, CryptoSuite } = issuer;
const main = async () => {
// Generate DID document
const issuedDidWeb = await issueDID({
domain: "example.com",
type: CryptoSuite.EcdsaSd2023,
});
// Access the DID document
console.log(JSON.stringify(issuedDidWeb.wellKnownDid, null, 2));
// Store the key pairs securely
console.log("Key pairs:", issuedDidWeb.didKeyPairs);
};
main();
Important: Always securely store the generated key pairs (
didKeyPairs). They are required for signing Verifiable Credentials.
- Install the package:
npm install @trustvc/trustvc
- Create a script to generate the DID:
import { issuer } from "@trustvc/trustvc";
const { issueDID, CryptoSuite } = issuer;
const main = async () => {
// Generate DID document with BBS-2023
const issuedDidWeb = await issueDID({
domain: "example.com",
type: CryptoSuite.Bbs2023,
});
// Access the DID document
console.log(JSON.stringify(issuedDidWeb.wellKnownDid, null, 2));
// Store the key pairs securely
console.log("Key pairs:", issuedDidWeb.didKeyPairs);
};
main();
Important: Always securely store the generated key pairs (
didKeyPairs). They are required for signing Verifiable Credentials.
Note: The CLI supports both ECDSA-SD-2023 and BBS-2023 key generation.
- Install the CLI:
npm install -g @trustvc/trustvc-cli
- Generate a key pair:
trustvc w3c key-pair-generation
You will be prompted to:
? Select an encryption algorithm for your new key pair:
❯ ECDSA-SD-2023 (Generate KeyPair for ECDSA-SD-2023 suite)
BBS-2023 (Generate KeyPair for BBS-2023 suite)
? Enter a seed in base58 format (optional): [only for BBS-2023]
? Enter a directory to save the generated key file (optional): .
✔ success Generated key pair successfully
ℹ info Saved to: ./keypair.json
⚠ warning IMPORTANT: Never share this file publicly - it contains secret keys!
- Generate the DID document:
trustvc w3c did-web
You will be prompted to:
? Enter the path to your key pair JSON file: ./keypair.json
? Enter the domain where your did:web public key will be hosted (e.g., https://example.com/.well-known/did.json): https://example.com/.well-known/did.json
? Enter a directory to save the generated DID token file (optional): .
✔ success Generated DID files successfully
ℹ info ./wellknown.json → Publish at /.well-known/did.json
ℹ info ./didKeyPairs.json → Keep private (contains secret keys)
⚠ warning IMPORTANT: Never share didKeyPairs.json publicly!
Host the Document
- Place the generated DID document at
/.well-known/did.jsonon your web server. - Configure your web server to:
- Serve the file over HTTPS.
- Set appropriate CORS headers.
- Set proper content-type headers (
application/json).
Example DID Document
{
"id": "did:web:example.com",
"verificationMethod": [
{
"type": "Multikey",
"id": "did:web:example.com#keys-1",
"controller": "did:web:example.com",
"publicKeyMultibase": "..."
}
],
"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1"],
"authentication": ["did:web:example.com#keys-1"],
"assertionMethod": ["did:web:example.com#keys-1"],
"capabilityInvocation": ["did:web:example.com#keys-1"],
"capabilityDelegation": ["did:web:example.com#keys-1"]
}
Adding Keys to an Existing did:web
Before adding new keys:
- Your
did:webdocument must be hosted and publicly accessible - The CLI or code will fetch the existing DID document and append the new key-pair
- Ensure you have access to update the hosted document after modification
Adding Multiple Keys
- ECDSA-SD-2023 (Default)
- BBS-2023
- Using CLI
- Install the package:
npm install @trustvc/trustvc
- Create a script to generate and add a new key:
import { issuer } from "@trustvc/trustvc";
const { issueDID, CryptoSuite } = issuer;
const addNewKey = async () => {
// Issue new DID document with additional key
const updatedDid = await issueDID({
domain: "example.com",
type: CryptoSuite.EcdsaSd2023,
});
console.log("Updated DID document:", JSON.stringify(updatedDid.wellKnownDid, null, 2));
console.log("New key pair to store:", updatedDid.didKeyPairs);
};
addNewKey();
- Install the package:
npm install @trustvc/trustvc
- Create a script to generate and add a new BBS-2023 key:
import { issuer } from "@trustvc/trustvc";
const { issueDID, CryptoSuite } = issuer;
const addNewKey = async () => {
// Issue new DID document with additional BBS-2023 key
const updatedDid = await issueDID({
domain: "example.com",
type: CryptoSuite.Bbs2023,
});
console.log("Updated DID document:", JSON.stringify(updatedDid.wellKnownDid, null, 2));
console.log("New key pair to store:", updatedDid.didKeyPairs);
};
addNewKey();
Note: The CLI supports both ECDSA-SD-2023 and BBS-2023 key generation.
- Generate a new key pair:
trustvc w3c key-pair-generation
You will be prompted to:
? Select an encryption algorithm for your new key pair:
❯ ECDSA-SD-2023 (Generate KeyPair for ECDSA-SD-2023 suite)
BBS-2023 (Generate KeyPair for BBS-2023 suite)
? Enter a seed in base58 format (optional): [only for BBS-2023]
? Enter a directory to save the generated key file (optional): .
✔ success Generated key pair successfully
ℹ info Saved to: ./keypair.json
⚠ warning IMPORTANT: Never share this file publicly - it contains secret keys!
- Add the new key to your existing
did:web, providing the samedid:web:
trustvc w3c did-web
You will be prompted to:
? Enter the path to your key pair JSON file: ./keypair.json
? Enter the domain where your did:web public key will be hosted (e.g., https://example.com/.well-known/did.json): https://example.com/.well-known/did.json
? Enter a directory to save the generated DID token file (optional): .
✔ success Generated DID files successfully
ℹ info ./wellknown.json → Publish at /.well-known/did.json
ℹ info ./didKeyPairs.json → Keep private (contains secret keys)
⚠ warning IMPORTANT: Never share didKeyPairs.json publicly!
After generating the updated DID document, you'll need to deploy it to your web server to replace the existing one.
Example DID Document with Multiple Keys
{
"id": "did:web:example.com",
"verificationMethod": [
{
"type": "Multikey",
"id": "did:web:example.com#keys-1",
"controller": "did:web:example.com",
"publicKeyMultibase": "zDnaekGZTbQBerwcehBSXLqAg6s55hVEBms1zFy89VHXtJSa9"
},
{
"type": "Multikey",
"id": "did:web:example.com#keys-2",
"controller": "did:web:example.com",
"publicKeyMultibase": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}
],
"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1"],
"authentication": ["did:web:example.com#keys-1", "did:web:example.com#keys-2"],
"assertionMethod": ["did:web:example.com#keys-1", "did:web:example.com#keys-2"],
"capabilityInvocation": ["did:web:example.com#keys-1", "did:web:example.com#keys-2"],
"capabilityDelegation": ["did:web:example.com#keys-1", "did:web:example.com#keys-2"]
}
Use Cases for Multiple Keys
- Key Rotation: Maintain multiple keys to facilitate smooth key rotation
- Different Purposes: Use different keys for different types of operations
- Backup Keys: Have backup keys ready in case primary keys are compromised
Managing Multiple did:web Identifiers
You can host multiple did:web identifiers on a single domain by using paths in your DID identifier. This allows organizations to manage multiple DIDs under the same domain.
Path-based did:web format
The format for path-based did:web is:
did:web:<domain-name>:<path>
Examples
-
Root Domain DID:
did:web:example.comDocument location:
https://example.com/.well-known/did.json -
Subdirectory DID:
did:web:example.com:department-aDocument location:
https://example.com/department-a/did.json -
Deep Path DID:
did:web:example.com:users:aliceDocument location:
https://example.com/users/alice/did.json
Setting Up Path-based DIDs
- Using CLI
- Using Code
# Generate DID for a specific path
trustvc w3c did-web
const issuedDidWeb = await issueDID({
domain: "example.com/department-a",
...keyPair
});
Directory Structure Example
example.com/
├── .well-known/
│ └── did.json # Root DID
├── department-a/
│ └── did.json # Department A's DID
├── department-b/
│ └── did.json # Department B's DID
└── users/
├── alice/
│ └── did.json # Alice's DID
└── bob/
└── did.json # Bob's DID
Use Cases
| Use Cases | Purpose |
|---|---|
| Organizational Structure | 📂 Different departments having their own DIDs 👥 Team-specific DIDs 📋 Project-based DIDs |
| User Management | 🔑 Individual user DIDs 👔 Role-based DIDs ⚙️ Service-specific DIDs |
| Environment Separation | 🛠️ Development DIDs 🧪 Staging DIDs 🚀 Production DIDs |
Security Considerations
Private Key Management
-
Key Separation
- Maintain separate signing keys for different document types
- Use distinct keys for different departments or teams
- Keep development and production keys strictly separated
-
Key Rotation
- Establish regular key rotation schedules
- Maintain overlap period during rotation for smooth transition
- Document key expiry and rotation procedures
-
Active Key Security
- Use secure key management services that support high-frequency signing
- Implement key access audit trails for compliance
- Set up automated key usage monitoring and alerts
Note: Since these keys are used frequently for document signing, ensure your application has appropriate access controls and authentication mechanisms to access the keys while maintaining security.
DID Document Hosting
- HTTPS Infrastructure
- Configure automatic SSL/TLS certificate renewal
- Enable CORS only for required origins
- Set up proper caching with cache-control headers
Document Access Control
- Change Management
- Implement version control for DID documents
- Establish a review process for document changes
- Set up automated validation checks
- Maintain an audit trail of all modifications