Permission cache bypass: In-memory cache persists after file-based allow rule cleanup
Summary
Claude Code caches permission decisions in memory for the duration of a session. Once a user approves a hook prompt, subsequent calls to the same command bypass the hook entirely - even if the file-based allow rule in settings.local.json is cleaned up.
Reproduction Steps
- Configure a hook in
~/.claude/settings.jsonthat prompts for approval:
``json``
{
"permissions": {
"allow": [],
"deny": [],
"ask": [
{
"bash": "~/scripts/commit-script.sh*",
"permissionDecision": "ask"
}
]
}
}
- User invokes a skill/command that runs the script
- Hook prompts for approval (e.g., "ONLY ALLOW if YOU typed /commit")
- User approves
- Script executes successfully
- External cleanup script removes the allow rule from
settings.local.json - AI proactively runs the same script again (without user invoking the skill)
- Expected: Hook prompts again
- Actual: Hook is bypassed due to in-memory cache, command proceeds without prompting
Root Cause
Claude Code's permission system appears to have two layers:
- File-based:
settings.local.jsonwithpermissions.allowarray - In-memory: Session cache of approved permissions
Cleaning up layer 1 (file) does not clear layer 2 (in-memory cache).
Impact
This defeats safety architectures that rely on per-invocation approval workflows. For example:
- A "quick-commit" hook designed to prompt users to confirm they intentionally requested a commit
- The prompt instructs users to DENY if the AI is acting proactively
- After one legitimate approval, the AI can commit proactively for the rest of the session
Suggested Solutions
- Single-use permissions: Add a flag for permissions that should be cleared after one use
- Cache invalidation API: Allow hooks/scripts to signal that the cache should be cleared
- Auto-expire permissions: Permissions from hooks could automatically expire after execution
- Sync with file: When
settings.local.jsonis modified, re-read and update the in-memory cache
Environment
- Claude Code CLI
- macOS/Linux
- Issue discovered while implementing a hook-based safety workflow
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗