Enterprise Denies, You Allow — Who Wins? Claude Code Permission Precedence
▶ Watch on YouTube & subscribe to The Stack Underflow
You lock down Bash for the whole org through a managed enterprise policy. A week later a developer’s laptop has a personal settings.local.json with Bash explicitly allowed — maybe from an old project, maybe copy-pasted from a blog post, maybe deliberate. Does their local file win because it is “closer” to the agent, or does the org-wide policy hold the line? If you cannot answer that with certainty, you cannot reason about whether your Claude Code deployment is actually enforcing anything, or just enforcing things nobody happened to override.
The one-sentence version: Claude Code settings resolve through a fixed precedence ladder, and enterprise managed policy sits at the top — nothing below it, including a user’s own local settings, can override a deny.
The question
This is Q9 of 10 in the CCA Domain 3 practice set — Claude Code Configuration & Workflows (20% of the exam).
Enterprise managed policy DENIES Bash; your local settings ALLOW it. What happens?
- A) Local wins
- B) They merge
- C) Managed/enterprise policy wins — Bash stays denied
- D) It errors and won’t start
Pause here and pick an answer before you keep reading.
The answer
The correct answer is C — managed/enterprise policy wins. Bash stays denied.
The mechanism is a precedence ladder: Claude Code resolves permission settings from several sources, and when two sources disagree on the same rule, the source higher on the ladder wins outright. It is not a vote, it is not an average, and it is not “most specific file wins.” It is a strict top-down override, and enterprise managed policy occupies the top rung by design — because its entire purpose is to be un-overridable by anything running underneath it.
SETTINGS PRECEDENCE LADDER (top always wins)
┌───────────────────────────────────────────┐
│ MANAGED / ENTERPRISE POLICY │ ← IT admin, org-wide config
│ Bash: DENY ✗ │
└───────────────────┬───────────────────────┘
│ overrides everything below
▼
┌───────────────────────────────────────────┐
│ COMMAND-LINE FLAGS │
└───────────────────┬───────────────────────┘
▼
┌───────────────────────────────────────────┐
│ LOCAL PROJECT SETTINGS │
│ .claude/settings.local.json │
└───────────────────┬───────────────────────┘
▼
┌───────────────────────────────────────────┐
│ SHARED PROJECT SETTINGS │
│ .claude/settings.json │
└───────────────────┬───────────────────────┘
▼
┌───────────────────────────────────────────┐
│ USER SETTINGS │
│ ~/.claude/settings.json │
│ Bash: ALLOW ✓ │
└───────────────────────────────────────────┘
Result: a ✗ at the top propagates down through every
lower layer. Bash is denied for this developer, full stop.
Read the ladder as a resolution order, not a merge order. Claude Code does not combine an “allow” from one layer with a “deny” from another into some negotiated middle state — the highest layer that has an opinion on a given rule settles the question, and every layer beneath it is irrelevant for that rule. A local Bash: allow never even gets consulted once the managed policy has already said no, because the managed layer is checked first and its deny is final.
This is why “managed policy” exists as a distinct, separate concept from “shared project settings” in Claude Code’s configuration model in the first place. If a project-level .claude/settings.json committed to the repo could be silently overridden by anyone’s personal local file, it would not be a security boundary — it would be a suggestion. Enterprise managed policy is deployed outside the repo entirely (typically pushed by IT/security tooling to a fixed OS-level location), specifically so that no file a developer controls — not their user settings, not a project’s local override, not a command-line flag — can climb back over it.
Why the other options fail
- A) Local wins — this inverts the entire point of a managed policy. If the setting closest to the developer always won, “enterprise policy” would be a decorative label with no enforcement behind it. Anyone could
Bash: allowtheir way past a deny in seconds, in their own personal file, without even touching the shared project. - B) They merge — permission scopes do not blend allow and deny into a partial state for the same rule. There is no “sometimes allowed” outcome here. Each layer either has a rule for
Bashor it does not, and resolution picks a winner rather than averaging opinions. Merging does happen across different, non-conflicting rules from different layers — but when two layers name the exact same rule, precedence decides, not merge logic. - D) It errors and won’t start — a conflict between layers is not a fatal misconfiguration; it is the normal, expected case the precedence system exists to resolve. If Claude Code refused to launch every time a user’s settings disagreed with policy, it would be unusable in any org that actually enforces standards. The system is built to resolve the conflict silently and consistently, not to halt on it.
The concept behind it
Generalize past this one question: any configuration system with multiple scopes needs a documented, deterministic resolution rule, or “who wins” becomes a support ticket instead of a fact you can look up. Claude Code’s settings hierarchy is the same idea you already know from CLAUDE.md’s memory hierarchy — enterprise, project, and user layers stack in a fixed order — applied to permissions instead of instructions.
| Layer | Who controls it | Typical use | Can it override the layer above? |
|---|---|---|---|
| Managed / enterprise policy | IT / security admin | Org-wide hard limits (deny destructive tools, lock MCP servers) | — (top of the ladder) |
| Command-line flags | Whoever invokes claude | One-off session overrides | No |
| Local project settings | Individual developer, gitignored | Personal experiments on this repo | No |
| Shared project settings | Team, committed to the repo | Team-wide conventions for this repo | No |
| User settings | Individual developer, all repos | Personal defaults everywhere | No |
The design principle worth memorizing is: a scope can only tighten or extend permissions within the room the layer above leaves it. It can never widen past a deny set above it. That is a deliberate, security-shaped asymmetry — a deny should be able to come from any layer and hold, while an allow only holds if nothing above it says no. It mirrors the same logic covered in Allow npm test, Gate Destructive Git: Claude Code Permissions, where individual rules inside one settings file are already scoped as allow/ask/deny per tool pattern — precedence is that same allow/ask/deny logic, just applied across files instead of within one file.
It also explains why the personal-vs-shared split matters operationally, not just organizationally: a setting in .claude/settings.local.json genuinely can override the committed .claude/settings.json for that one developer’s convenience — but the moment a managed policy exists above both of them, that same local override stops mattering for anything the policy has already decided. Scope answers “who can change this,” and the ladder answers “who wins when two scopes disagree” — those are two different questions, and Domain 3 tests both.
FAQ
Does managed/enterprise policy require a paid or enterprise Claude plan? Managed policy is an organizational deployment concern, distributed by IT/security tooling rather than edited by individual developers — verify current plan requirements and deployment mechanics on Anthropic’s official Claude Code documentation, since packaging details change independently of the underlying precedence mechanism.
If enterprise policy denies a tool, can a developer still use it in some other way, like a raw shell outside Claude Code? Yes — permission precedence governs what Claude Code itself will execute on the model’s behalf, not the developer’s own terminal. It is a guardrail on the agent’s actions, not a system-wide lockdown of the machine.
What happens if two non-managed layers, like shared project settings and user settings, disagree on the same rule? The same top-down logic applies at the level directly below managed policy: local project settings outrank shared project settings, which outrank user settings. The ladder does not stop mattering once you are past the enterprise layer — it just keeps resolving downward.
Is the exact order of the ladder likely to change? The scope names (managed, project, user) and the “higher scope wins” principle are the durable mechanism. Exact flag names, file paths, and CLI syntax are far more likely to shift release to release — verify the current precise order against Anthropic’s official Claude Code docs before treating any one layer’s position as permanent.
Not affiliated with, authorized, or endorsed by Anthropic. “Claude” and “Claude Certified Architect” are trademarks of Anthropic. These are original practice questions for study, not real exam content — verify current exam details on Anthropic’s official pages.
Where this fits in the CCA series
This is Domain 3, question 9 of 10 — settings precedence is the sharper, adversarial cousin of the settings-location questions earlier in the set: A Rule for You, Not Your Team: Local vs Shared Claude Code Settings and The Setting You Must Not Commit: settings.local.json in Claude Code establish where a setting lives; this page establishes who wins when settings from different scopes collide. It pairs naturally with Allow npm test, Gate Destructive Git: Claude Code Permissions for the allow/ask/deny rule syntax itself, and with Where Does a Team Convention Live? Project CLAUDE.md Explained for the parallel memory hierarchy. Domain 3 covers Claude Code configuration and workflows broadly — for the full five-domain map of the exam, start with the Claude Certified Architect (CCA) Exam Guide. Browse all tutorials for the rest of the series.
Found this useful? The deep version lives on YouTube — new breakdowns of how AI dev tools actually work, weekly.
Subscribe on YouTube →