Expose permission decision context to PostToolUse hooks

Resolved 💬 3 comments Opened Mar 30, 2026 by curtiskelsey Closed Apr 3, 2026

Summary

PostToolUse (and PostToolUseFailure) hooks currently receive tool_name, tool_input, and tool_output/error, but they do not include any information about how the tool call was authorized — whether it was auto-approved by a permission rule, explicitly approved by the user at a prompt, or denied (in the failure case).

Use Case

I have a tool-audit plugin that logs all tool and command usage via PostToolUse hooks to JSONL files for later review. Being able to distinguish between auto-approved and user-prompted calls would be valuable for:

  • Security auditing — understanding which calls bypassed user review
  • Permission tuning — identifying tools that are frequently prompted for but always approved (candidates for allow-listing)
  • Usage analytics — separating autonomous vs. interactive tool usage patterns

Proposed Solution

Add a field to the hook input, e.g.:

{
  "tool_name": "Bash",
  "tool_input": { "command": "ls" },
  "tool_output": "...",
  "permission_decision": "auto_approved" | "user_approved" | "user_denied"
}

Alternatively, a permission_rule field showing which rule matched (e.g. "allowlist:Bash(ls)") would be even more useful for tuning.

Current Workaround

None — the permission decision is internal to Claude Code and not exposed to hooks. Denied calls can be inferred from PostToolUseFailure with empty params, but auto-approved vs. user-approved cannot be distinguished.

🤖 Generated with Claude Code

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗