Permission audit logging: capture approval method (settings.json rule vs manual user approval)
Feature Request
Summary
When a permission request is evaluated, the final approval method — whether it was auto-approved by a matching rule in settings.json / settings.local.json, or manually approved by the user — is not captured anywhere in the audit log.
Current behaviour
The PermissionRequest hook fires and records its own decision (e.g. defer, allow, deny). When the hook defers to settings.json, Claude Code evaluates the allow/deny rules internally and either auto-approves or prompts the user. This final outcome is not written back to any log.
Available log files (/var/log/agents/ in our setup):
claude_permission_hook.log— records hook verdict only; showsDEFERfor everything that didn't match a hook ruleclaude_permission_metrics.jsonl— same;decision: unknownfor all deferred requestsclaude_hook.log— recordstool_completewith success/fail outcome, but no approval method- No log records whether the tool ran because a settings rule matched, or because the user clicked Approve
Impact
- Cannot audit how many operations in a session required manual user intervention vs were silently auto-approved
- Cannot tune
settings.jsonrules effectively without counting manual approvals per tool/command pattern - Cannot produce meaningful permission usage reports or detect over-permissioning
- A session with 266 permission requests has no way to distinguish "20 needed human review" from "266 needed human review"
Proposed behaviour
After settings.json evaluation, write a post-decision log entry that includes:
{
"timestamp": "...",
"session_id": "...",
"tool_name": "Bash",
"approval_method": "settings_rule", // or "manual_user", "hook_allow", "hook_deny"
"matched_rule": "Bash(git:*)", // the specific rule that matched, if any
"outcome": "allowed"
}
This could go to an existing log file (e.g. claude_permission_metrics.jsonl) as an additional event, or a new claude_permission_decisions.jsonl.
Why this matters
For users running Claude Code in high-autonomy / unattended modes with rich settings.json allow lists, understanding the actual approval breakdown is essential for:
- Security auditing (which operations truly ran without human review)
- Permission hygiene (identifying rules that are never matched, or commands that keep prompting)
- Compliance (demonstrating human oversight of specific operation classes)
Environment
- Claude Code CLI, macOS
- Custom permission hook writing to
/private/var/log/agents/ settings.local.jsonwith ~80+ allow rules across Bash, Read, Write, Edit, MCP tools
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗