Privilege analyzer
Least-privilege analysis that compares granted permissions against actual audit log usage to find over-permissioned agents.
What it analyzes
Over time, agents accumulate permissions that drift from what they actually use. A wildcard granted at setup may cover dozens of resources the agent has never touched. A permission added for a one-off task may never run again.
The privilege analyzer compares each agent's declared permissions against its recent activity in the audit log. It surfaces wildcards, unused grants, and permissions that lack rate limits or approval gates — then suggests specific replacements.
The analyzer compares granted permissions against actual audit log usage. An agent with broad permissions but a narrowly consistent access pattern will show findings even if it has never been denied. The point is to tighten the grant, not penalize the agent.
PrivilegeAnalysis fields
Prop
Type
PrivilegeFinding fields
Prop
Type
Finding types
| Type | Severity | Description |
|---|---|---|
wildcard_permission | critical | Resource or action uses *. Grants access beyond what the agent needs. |
unused_permission | warning | Resource has not appeared in the audit log in the last 30 days. |
overly_broad | warning | Permission covers a namespace prefix when only specific sub-resources are used. |
no_constraints | info | Permission has no rate limit, time window, IP allowlist, or approval gate. |
no_expiry | info | The agent itself has no expiresAt date, meaning the credential never rotates. |
Privilege scores
| Score | Meaning |
|---|---|
minimal | No findings. The agent has exactly what it uses. |
appropriate | Minor findings only. Generally fine in production. |
over-permissioned | One wildcard, or two or more warnings. Worth tightening. |
wildcard-heavy | Multiple wildcards or any critical finding. Address before shipping. |
Code examples
Analyze a single agent
const report = await kavach.analyzer.analyzeAgent('agt_abc123');
console.log(report.score); // 'over-permissioned'
console.log(report.recommendations);
// [
// "Narrow `mcp:github:*` to `mcp:github:repos`",
// "Add rate limits or approval gates to sensitive permissions",
// ]Analyze with a custom lookback window
By default, the analyzer looks at the last 30 days of audit data. Override this for quarterly reviews:
const since = new Date('2026-01-01');
const report = await kavach.analyzer.analyzeAgent('agt_abc123', { since });
for (const finding of report.findings) {
console.log(`[${finding.severity}] ${finding.description}`);
}Analyze all active agents
const reports = await kavach.analyzer.analyzeAll();
const critical = reports.filter((r) => r.score === 'wildcard-heavy');
console.log(`${critical.length} agents need immediate attention`);
for (const report of critical) {
console.log(`\nAgent: ${report.agentName}`);
for (const rec of report.recommendations) {
console.log(` → ${rec}`);
}
}Get a summary across all agents
const summary = await kavach.analyzer.getSummary();
console.log(`Total agents analyzed: ${summary.total}`);
console.log(`Critical findings: ${summary.criticalFindings}`);
console.log('Score breakdown:', summary.byScore);
// { minimal: 3, appropriate: 7, 'over-permissioned': 2, 'wildcard-heavy': 1 }Use getSummary for a dashboard widget or a health-check endpoint. It runs analyzeAll internally.
Act on findings programmatically
const reports = await kavach.analyzer.analyzeAll();
for (const report of reports) {
if (report.score === 'wildcard-heavy') {
// Alert the agent's owner
const agent = await kavach.agent.get(report.agentId);
if (agent) {
await notifyOwner(agent.ownerId, {
message: `Agent "${report.agentName}" has wildcard permissions that should be narrowed.`,
recommendations: report.recommendations,
});
}
}
}Handle a wildcard finding
When the analyzer detects a wildcard, its recommendation tells you exactly what to narrow it to, based on observed usage:
const report = await kavach.analyzer.analyzeAgent('agt_abc123');
const wildcards = report.findings.filter((f) => f.type === 'wildcard_permission');
for (const finding of wildcards) {
console.log(finding.description);
// "Permission resource `mcp:github:*` uses a wildcard"
}
// Apply the recommendation: update the agent's permissions
await kavach.agent.update('agt_abc123', {
permissions: [
{ resource: 'mcp:github:repos', actions: ['read'] },
// Replace the wildcard with only what was actually used
],
});