Paths Subjects Questions Quizzes Pricing Search
Intermediate Open Free

Debugging a Permission Rule That Won't Take Effect

Your team's .claude/settings.json contains:

{
  "permissions": {
    "allow": ["Bash(aws s3 ls)"],
    "deny": ["Bash(aws *)"]
  }
}

An engineer reports that aws s3 ls still prompts for approval every time, even though they explicitly allowed it.

  1. Explain exactly why the allow rule has no effect here.
  2. Rewrite the configuration so that aws s3 ls runs without a prompt while every other aws subcommand still requires approval.
  3. A teammate suggests moving the allow rule into .claude/settings.local.json instead, reasoning that local settings have higher precedence than project settings. Would that fix it? Why or why not?
Solution

1. Why the allow rule has no effect:

Claude Code evaluates permission rules in a fixed order — deny, then ask, then allow — and the first match in that order wins regardless of how specific a lower-priority rule is. Bash(aws *) is a deny rule that matches aws s3 ls (the wildcard covers any aws subcommand, including this one). Because deny is checked first and it matches, the call is blocked before Claude Code ever consults the allow list. A broad deny rule cannot carry allowlist exceptions — there is no way for a narrower allow to punch a hole in a broader deny.

2. Fix — narrow the deny rule instead of trying to except the allow:

{
  "permissions": {
    "allow": ["Bash(aws s3 ls)"],
    "deny": ["Bash(aws s3 rm *)", "Bash(aws ec2 terminate-instances *)"]
  }
}

The general fix is to invert the approach: rather than denying broadly and trying to carve out an allow exception (which doesn't work), deny only the specific dangerous subcommands and let everything else fall through to the normal ask/allow flow. If the intent really is "block all of aws except read-only listing," an equally valid approach is to keep the broad deny and add a narrower deny is not what's needed here — the fix is recognizing that allow can never override a matching deny, so the deny rule itself must be made precise enough to not catch the commands that should be allowed.

3. Would moving the allow rule to local settings help? No.

This is a common misconception. Precedence-by-scope governs most settings (a higher-precedence scope's value replaces a lower one's), but permissions rules are the explicit exception to that model: they merge across every scope rather than override. A deny rule set in project settings stays in effect no matter what a local or user-scope file says — you cannot un-deny something from a lower-priority perspective, and local settings are not "higher priority" for the purposes of permission evaluation the way they would be for, say, the model field. The engineer's assumption conflates the general settings precedence model with the permissions-specific merge behavior. The only way to allow aws s3 ls here is to change the deny rule so it no longer matches that specific command.

Share this question

← Back to Settings, Permissions & Hooks practice

We use cookies for product analytics to improve OmniAtlas. See our Privacy Policy.