Log Every Permission Decision

A passive, observational record of every permission decision made during a session — not just the final tool-call log, but the decision point itself, including which rule matched. Purely additive; it never overrides the decision, just writes it down.

Audit & Compliance Logging Event: PermissionRequest Claude Code Open source · Free

1. Save this as the hook script

#!/usr/bin/env python3
"""PermissionRequest hook — logs every permission decision point to a
durable file. Observational only; does not emit a decision."""
import json, sys, datetime
from pathlib import Path

data = json.load(sys.stdin)
log_path = Path(data.get("cwd", ".")) / ".claude" / "permission_log.jsonl"
log_path.parent.mkdir(parents=True, exist_ok=True)

entry = {
    "ts": datetime.datetime.utcnow().isoformat() + "Z",
    "session_id": data.get("session_id"),
    "tool_name": data.get("tool_name"),
    "rules": data.get("rules"),
}

with open(log_path, "a") as f:
    f.write(json.dumps(entry) + "\n")

sys.exit(0)

Save to a path inside your project, e.g. .claude/hooks/log-every-permission-decision.sh, then chmod +x it.

2. Wire it into .claude/settings.json

{
  "hooks": {
    "PermissionRequest": [
      {
        "hooks": [
          {"type": "command", "command": "python3 .claude/hooks/log-every-permission-decision.py"}
        ]
      }
    ]
  }
}

Before you use this

A hook runs with your local shell's permissions — review the script above before adding it, the same way you'd review any script you didn't write yourself. See our guide on hook security risks for the specific CVEs this category of feature has already produced.

Related hooks

← All hooks
FEEDBACK