Agent identity
Creating, managing, and rotating agent identities in KavachOS.
What is an agent identity
AgentIdentity is the primary entity in KavachOS. It represents a single AI agent, a process acting on behalf of a human user.
Agents are not users. No passwords, sessions, or OAuth flows. Just tokens and permissions.
Prop
Type
Agent types
Lifecycle
Creating an agent
const agent = await kavach.agent.create({
ownerId: 'user-123', // ID from your auth provider
name: 'github-reader',
type: 'autonomous',
permissions: [
{ resource: 'mcp:github:*', actions: ['read'] },
],
expiresAt: new Date(Date.now() + 7 * 24 * 3_600_000), // optional
metadata: { purpose: 'nightly PR review' },
});
console.log(agent.token); // kv_a3f8c2e1... — only shown hereThe token is returned once at creation. KavachOS stores only the SHA-256 hash, so the plaintext cannot be recovered later. Save it immediately or rotate to get a new one.
Tokens
Tokens use the kv_ prefix followed by 32 cryptographically random bytes encoded as 64 hex characters:
kv_a3f8c2e1d4b5... (64 hex chars after the prefix)Authenticate by passing the token as a Bearer credential:
Authorization: Bearer kv_a3f8c2e1d4b5...The hash-only storage model means a full database dump cannot reveal active tokens. There are no secrets to rotate after a DB breach, only the tokens themselves.
Token rotation
Rotation issues a new token and immediately invalidates the old one. The operation is atomic: there is no window where both tokens are valid.
const rotated = await kavach.agent.rotate(agentId);
// rotated.token is the new plaintext token
// The old token is rejected on all subsequent callsRotate tokens on a schedule, or any time you suspect a token has been exposed.
Token-based authorization
When a caller only has a raw bearer token (for example, in HTTP middleware), use authorizeByToken instead of authorize:
const token = request.headers.get('Authorization')?.replace('Bearer ', '');
if (!token) return new Response('Unauthorized', { status: 401 });
const result = await kavach.authorizeByToken(token, {
action: 'read',
resource: 'mcp:github:repos',
});
if (!result.allowed) {
return new Response(result.reason ?? 'Forbidden', { status: 403 });
}This performs a single database lookup (hash comparison), then evaluates permissions in memory. No JWTs, no network calls.
Listing and filtering agents
// All agents owned by a user
const agents = await kavach.agent.list({ userId: 'user-123' });
// Only active autonomous agents
const active = await kavach.agent.list({
userId: 'user-123',
status: 'active',
type: 'autonomous',
});Updating an agent
const updated = await kavach.agent.update(agentId, {
name: 'github-reader-v2',
permissions: [
{ resource: 'mcp:github:*', actions: ['read', 'comment'] },
],
});Permission updates take effect immediately. In-flight requests that have already passed authorization are not affected.
Revoking an agent
await kavach.agent.revoke(agentId);
// All future authorize() or authorizeByToken() calls return allowed: false
// The agent's token is also invalidated immediatelyRevocation is permanent. There is no un-revoke. To restore access, create a new agent.
Agent limits
The default limit is 10 active agents per user. Raise it at initialization:
const kavach = createKavach({
database: { provider: 'sqlite', url: 'kavach.db' },
agents: {
maxPerUser: 50,
},
});Attempts to create agents beyond the limit return an error with code AGENT_LIMIT_EXCEEDED.