User deny permissions in settings.json ignored when command appears in allow list
Claude Code Bug Report: User Deny Permissions Ignored
Summary
User-defined deny permissions in ~/.claude/settings.json are being ignored when the same commands appear in an allow list (either system-level or project-level).
Environment
- OS: Pop!_OS 24.04 Cosmic (beta)
- Claude Code Version: Current (as of 2025-12-04)
- Model: claude-opus-4-5-20251101
Steps to Reproduce
- Add commands to deny list in
~/.claude/settings.json:
``json``
{
"permissions": {
"deny": [
"Bash(cat:*)",
"Bash(grep:*)",
"Bash(pgrep:*)"
]
}
}
- Start Claude Code session
- Observe that Claude still executes
Bash(cat:*)commands without user approval
Expected Behavior
User-defined deny permissions should take highest precedence and block the specified commands regardless of any other allow lists.
The permission hierarchy should be:
- User deny (highest - always blocks)
- User allow
- Project allow
- System defaults
Actual Behavior
The system prompt shows Bash(cat:*) in the "allowed without user approval" list despite being explicitly denied in user settings:
You can use the following tools without requiring user approval: Bash(docker logs:*), ... Bash(cat:*), ...
Claude then executes cat commands freely, ignoring the user's explicit deny.
Impact
- Security: Users cannot reliably restrict Claude's access to sensitive commands
- Trust: Users lose confidence that their security configurations are being respected
- Data exposure: Commands the user explicitly wanted blocked can still execute
Evidence
User settings file (~/.claude/settings.json) contains:
"permissions": {
"deny": [
"Bash(cat:*)",
"Bash(grep:*)",
"Bash(pgrep:*)"
]
}
Yet Claude executed cat ~/.claude.json and similar commands without requesting permission.
Suggested Fix
In the permission resolution logic, check user deny list FIRST before allowing any command, regardless of other allow sources.
Pseudocode:
if command in user_deny_list:
return DENIED # Stop here, don't check allow lists
elif command in user_allow_list:
return ALLOWED
elif command in project_allow_list:
return ALLOWED
else:
return PROMPT_USER
Workaround
None known. The deny list is simply ignored.
Reporter
Generated via Claude Code session on 2025-12-04
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗