kavachOS
Core concepts

W3C DID identity

Portable, cryptographic agent identity using W3C Decentralized Identifiers.

What are DIDs

W3C Decentralized Identifiers give agents a portable, cryptographic identity that works across services. Instead of an opaque token tied to one KavachOS instance, an agent gets a DID like did:key:z6Mk... backed by an Ed25519 keypair.

The agent can prove its identity to any service by signing a payload with its private key. The verifier resolves the DID to get the public key and checks the signature. No shared secrets, no central registry.

DIDs are optional. Regular kv_ bearer tokens work fine for single-service deployments. Use DIDs when agents need to prove identity across organizational boundaries.

Two DID methods

KavachOS supports two W3C DID methods:

MethodFormatBest for
did:keydid:key:z6Mk...Self-contained identity. No server needed. Key is embedded in the identifier.
did:webdid:web:auth.example.com:agents:agt_123Organization-backed identity. DID document hosted at a well-known URL.

Generate a DID for an agent

const { agentDid, privateKeyJwk } = await kavach.did.generateKey(agent.id);

console.log(agentDid.did);
// did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK

// Store privateKeyJwk securely — it's shown once and never stored in the database

Configure your domain first:

const kavach = await createKavach({
  database: { provider: 'sqlite', url: 'kavach.db' },
  did: {
    web: { domain: 'auth.example.com', path: 'agents' },
  },
});

const { agentDid, privateKeyJwk } = await kavach.did.generateWeb(agent.id);

console.log(agentDid.did);
// did:web:auth.example.com:agents:agt_abc123

Host the DID document at the resolved URL:

did:web:auth.example.com:agents:agt_abc123
→ https://auth.example.com/agents/agt_abc123/did.json

The private key is returned once and never stored in the database. Only the public key and DID document are persisted. Treat the private key like a bearer token.

Sign and verify payloads

An agent can sign a payload to prove it authored a request:

// Agent signs a payload
const signed = await kavach.did.sign(agent.id, {
  action: 'deploy',
  environment: 'staging',
  timestamp: new Date().toISOString(),
}, privateKeyJwk);

console.log(signed.jws);    // compact JWS string
console.log(signed.issuer); // did:key:z6Mk...

A receiving service verifies the signature:

const result = await kavach.did.verify(signed.jws, agentDid.did);

if (result.valid) {
  console.log(result.payload);  // { action: 'deploy', ... }
  console.log(result.issuer);   // did:key:z6Mk...
}

Verifiable presentations

A presentation is a signed JWT that bundles an agent's identity with its capabilities. Use this when an agent needs to prove both who it is and what it can do.

// Create a presentation
const jwt = await kavach.did.createPresentation({
  agentId: agent.id,
  did: agentDid.did,
  privateKeyJwk,
  capabilities: ['mcp:github:read', 'mcp:linear:write'],
  audience: 'https://mcp.partner.com',
  expiresIn: 300, // 5 minutes
});

// Verify on the receiving end
const result = await kavach.did.verifyPresentation(jwt);

if (result.valid) {
  console.log(result.agentId);      // agt_abc123
  console.log(result.capabilities); // ['mcp:github:read', 'mcp:linear:write']
}

DID document structure

Every agent DID resolves to a W3C DID document:

{
  "@context": ["https://www.w3.org/ns/did/v1"],
  "id": "did:key:z6MkhaXg...",
  "controller": "did:key:z6MkhaXg...",
  "verificationMethod": [{
    "id": "did:key:z6MkhaXg...#key-0",
    "type": "JsonWebKey2020",
    "controller": "did:key:z6MkhaXg...",
    "publicKeyJwk": {
      "kty": "OKP",
      "crv": "Ed25519",
      "x": "..."
    }
  }],
  "authentication": ["did:key:z6MkhaXg...#key-0"],
  "assertionMethod": ["did:key:z6MkhaXg...#key-0"],
  "capabilityInvocation": ["did:key:z6MkhaXg...#key-0"],
  "capabilityDelegation": ["did:key:z6MkhaXg...#key-0"]
}

Retrieve a stored DID

const agentDid = await kavach.did.getAgentDid(agent.id);

if (agentDid) {
  console.log(agentDid.did);       // did:key:z6Mk...
  console.log(agentDid.method);    // 'key' or 'web'
}

Resolve any DID

// Resolve did:key (local, no network)
const doc = await kavach.did.resolve('did:key:z6Mk...');

// Resolve did:web (fetches from HTTPS)
const doc = await kavach.did.resolve('did:web:auth.example.com');

Prop

Type

On this page