Audit trail
Immutable logging of every authorization decision, with filtering, export, and compliance references.
How audit logging works
Every call to kavach.authorize() or kavach.authorizeByToken() writes an entry to the audit log, regardless of outcome. Allowed, denied, and rate-limited calls are all recorded. The log is append-only: entries are never updated or deleted.
authorize() returns an auditId linking the decision to its log entry:
const result = await kavach.authorize(agent.id, {
action: 'read',
resource: 'mcp:github:repos',
});
console.log(result.auditId); // "aud_3f8a..."Querying logs
AuditEntry type
Prop
Type
Filtering
All filter fields are optional and combinable. Without filters, the query returns all entries up to the limit.
const logs = await kavach.audit.query({
agentId: 'agt_...',
userId: 'user-123',
result: 'denied',
since: new Date('2025-01-01'),
until: new Date('2025-02-01'),
actions: ['write', 'delete'],
limit: 100,
offset: 0,
});Prop
Type
Exporting logs
// JSON export
const json = await kavach.audit.export({ format: 'json' });
// CSV export, suitable for spreadsheets and compliance tools
const csv = await kavach.audit.export({ format: 'csv' });
// Export a specific time range
const q4 = await kavach.audit.export({
format: 'csv',
since: new Date('2024-10-01'),
until: new Date('2025-01-01'),
});The CSV export includes a header row with field names matching the AuditEntry interface. Each row is one authorization decision.
Both since and until are optional on exports. Omitting both exports the entire log.
Compliance references
Usage patterns
Monthly access report for a user
const entries = await kavach.audit.query({
userId: 'user-123',
since: new Date('2025-03-01'),
until: new Date('2025-04-01'),
});Agents with repeated denials today
const denied = await kavach.audit.query({
result: 'denied',
since: new Date(new Date().setHours(0, 0, 0, 0)),
});
const countsByAgent = denied.reduce<Record<string, number>>((acc, entry) => {
acc[entry.agentId] = (acc[entry.agentId] ?? 0) + 1;
return acc;
}, {});High-frequency agent detection
const highActivity = await kavach.audit.query({
agentId: 'agt_...',
since: new Date(Date.now() - 3_600_000), // last hour
});
console.log(`${highActivity.length} calls in the last hour`);A sudden spike in call volume from a single agent often indicates a runaway loop. Use kavach.agent.revoke() to suspend the agent while you investigate.