[DOCS] Permission rule evaluation docs don't match observed behavior (deny → ask → allow precedence)

Resolved 💬 4 comments Opened Feb 12, 2026 by klondon-sc Closed Mar 13, 2026

Documentation Type

Unclear/confusing documentation

Documentation Location

https://docs.anthropic.com/en/docs/claude-code/permissions

Section/Topic

Managed permissions

Current Documentation

Summary

The permission docs state that rules are evaluated in order deny → ask → allow, with "the first matching rule wins" and that "managed settings have the highest precedence." In practice, user-level allow patterns override managed ask rules, contradicting both statements.

Documented Behavior

From Permissions docs:

Rules are evaluated in order: deny -> ask -> allow. The first matching rule wins, so deny rules always take precedence.
Permission rules follow the same settings precedence as all other Claude Code settings: managed settings have the highest precedence

What's Wrong or Missing?

Observed Behavior

Managed settings (/Library/Application Support/ClaudeCode/managed-settings.json):

{
  "permissions": {
    "ask": ["Bash"],
    "disableBypassPermissionsMode": "disable"
  }
}

User settings (~/.claude/settings.json):

{
  "permissions": {
    "allow": ["Bash(git:*)", "Bash(go:*)"]
  }
}

Result: go build ./... auto-approves without prompting when sandboxed, even though managed settings say ask for all Bash commands.

If the documented order (deny → ask → allow) were enforced, ask: ["Bash"] should match before allow: ["Bash(go:*)"] is checked. If managed precedence were enforced, the managed ask should override the user allow.

What seems to actually happen

  1. All rules from all scopes get merged into combined deny/ask/allow lists
  2. More specific patterns win regardless of category — Bash(go:*) beats Bash even across scopes
  3. The evaluation is specificity-based, not strictly category-based as documented

allowManagedPermissionRulesOnly gap

The docs mention allowManagedPermissionRulesOnly as a managed-only setting that "prevents user and project settings from defining allow, ask, or deny permission rules." Its existence confirms that by default, user rules DO merge with and can override managed rules — but this is all-or-nothing. An admin who wants managed ask rules to be authoritative (but still allow users to add deny rules) has no option between "users can override everything" and "users can override nothing."

Additionally: sandboxed vs unsandboxed inconsistency

The managed setting autoAllowBashIfSandboxed: true creates confusing behavior: a command like go build ./... auto-approves when sandboxed but prompts when unsandboxed — even if Bash(go:*) is in the user's allow list. The sandboxing docs confirm unsandboxed commands "go through the normal Claude Code permissions flow," but the interaction between allow patterns and sandbox state isn't documented.

Suggested Improvement

  1. Update the docs to accurately describe the actual evaluation order — it appears to be specificity-based, not strictly deny → ask → allow
  2. Document how rules merge across scopes — the current docs only say "managed has highest precedence" without explaining that user allow patterns can override managed ask
  3. Consider a strictAsk option — a middle ground between the current default and allowManagedPermissionRulesOnly that lets admins enforce ask rules while still allowing users to add deny rules
  4. Document the interaction between allow patterns, autoAllowBashIfSandboxed, and sandbox state

Impact

Medium - Makes feature difficult to understand

Additional Context

Environment

  • Claude Code CLI
  • macOS Darwin 25.2.0
  • Managed settings deployed to /Library/Application Support/ClaudeCode/managed-settings.json

View original on GitHub ↗

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