[DOCS] Permission rule evaluation docs don't match observed behavior (deny → ask → allow precedence)
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
- All rules from all scopes get merged into combined deny/ask/allow lists
- More specific patterns win regardless of category —
Bash(go:*)beatsBasheven across scopes - 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
- Update the docs to accurately describe the actual evaluation order — it appears to be specificity-based, not strictly deny → ask → allow
- Document how rules merge across scopes — the current docs only say "managed has highest precedence" without explaining that user
allowpatterns can override managedask - Consider a
strictAskoption — a middle ground between the current default andallowManagedPermissionRulesOnlythat lets admins enforceaskrules while still allowing users to adddenyrules - Document the interaction between
allowpatterns,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
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗