Short answers to what readers ask most about this topic.
01Where does the Claude Code managed-settings.json file go?
In the system directory for the operating system: /Library/Application Support/ClaudeCode/ on macOS, /etc/claude-code/ on Linux and WSL, and C:\Program Files\ClaudeCode\ on Windows. The legacy Windows ProgramData path is no longer read. The same directory also holds an optional managed-settings.d drop-in directory and managed-mcp.json.
02Why is my Claude Code managed settings file being ignored?
Almost always because a higher-priority managed source is present. Claude Code uses the first source that delivers at least one policy key — remote settings, then MDM or OS policy, then files, then the user registry — and ignores the rest without any warning. Run /status and read the Setting sources line to see which source it actually selected.
03Do Claude Code managed settings from different sources merge?
No, with a small exception. Claude Code selects one source and ignores the others rather than merging. A few cross-source keys are read from every admin source anyway — the sandbox locks, some sandbox controls, and since v2.1.223 the env block, which merges per variable so lower sources fill in variables the higher ones leave unset.
04Can a developer override Claude Code managed settings?
Not through settings files, but four things sit outside the rule. A managed model value is a default rather than a lock, so use availableModels to restrict choice. A local administrator can edit the managed source itself. An edit to the server-managed cache lasts until the next fetch. And managed settings bind Claude Code, not other tools calling the API.
05What happens when a managed settings value is invalid?
Claude Code repairs individual entries where it can, drops top-level keys that still fail, and keeps enforcing everything valid. Several enforcement keys fail closed instead — an invalid MCP or model allowlist is enforced as empty. The version floor and ceiling deliberately fail open, so a bad policy push cannot stop Claude Code from starting.
Claude Code Managed Settings: Policy That Actually Holds
Claude Code picks the first managed source that delivers a policy key and ignores the rest — it does not merge them. That one rule explains most policy that silently fails.
Claude Code managed settings apply above every other settings level, so no user, project or local value overrides them. When more than one managed source delivers a policy, Claude Code uses the first one that contains a policy key and ignores the others entirely rather than merging them, and it shows no warning for the sources it skipped.
An administrator I spoke to had deployed a careful managed settings file to every machine, verified the JSON, verified the path, and could not work out why none of it applied. The file was fine. Their organisation had also configured server-managed settings months earlier, and that source outranks a file — so Claude Code was reading the remote policy and silently ignoring the one they had just shipped.
Managed settings are the mechanism that makes Claude Code deployable in an organisation with rules, and the thing that makes them confusing is that they do not behave like the rest of the settings system. This post covers the four delivery mechanisms, the winner-takes-all precedence and its exceptions, the keys only a managed source can set, what happens when a value is invalid, and the two commands that answer whether a policy is actually in force.
Four ways to deliver the same keys
Every mechanism carries the same policy keys as an ordinary settings file, so the settings reference applies to all of them. What differs is where the policy is stored and when Claude Code reads it. The file and MDM rows are together called endpoint-managed, because the policy sits on the device; server-managed is the row where Claude Code fetches it instead.
Pick by how you already manage devices:
Mechanism
When Claude Code reads it
Use it when
Server-managed settings
Fetched at startup, polled hourly
You want one place to change policy without touching machines
MDM or OS-level policy
At startup, rechecked every 30 minutes
You already run Jamf, Intune or Group Policy
A managed settings file
At startup, reloaded when the file changes
Machines without MDM, Linux hosts, images you build
The user registry on Windows
At startup, rechecked every 30 minutes
You cannot write the machine-level key
# managed-settings.json goes in the system directory for the OS.
# Note that the legacy Windows ProgramData path is NOT read.
macOS /Library/Application Support/ClaudeCode/
Linux and WSL /etc/claude-code/
Windows C:\Program Files\ClaudeCode\
# Same directory also holds an optional drop-in directory and
# the managed MCP configuration:
# managed-settings.d/*.json
# managed-mcp.json
# Drop-ins let several teams own parts of one policy. Claude Code
# merges managed-settings.json first, then every .json file in the
# directory in ALPHABETICAL order — so prefix them:
# 10-telemetry.json
# 20-security.json
The precedence rule that catches everyone
This is the section worth reading twice. Claude Code checks the sources in a fixed order and uses the first that delivers at least one policy key. It does not merge the rest — it ignores them, without a warning:
Remote settings, from claude.ai or a Claude apps gateway. Only fetched when the session authenticates to the Anthropic API directly with an eligible login, so on another provider Claude Code starts at the next source.
MDM or OS-level policy — the macOS managed preferences domain or the machine-level Windows registry key.
Managed settings files, with the drop-in directory merged in.
The user-writable Windows registry, read only when nothing above it delivered a policy key.
A source that contains only the WSL inheritance control does not count as delivering a policy key, and Claude Code moves on to the next source. That is the one deliberate exception to the counting rule, and it exists so the control can be set without accidentally claiming the whole policy slot.
The keys that are read from every source anyway
A small set of keys breaks the winner-takes-all rule, because they are locks or safety controls where a stricter value from anywhere should win. Claude Code reads these from every admin source — which excludes the user-writable registry:
The sandbox locks for managed domains and managed read paths. A true in any admin source turns the lock on, and while it is on the allowlists union across every admin source.
Several sandbox controls and binary paths, plus the flag that forces a fresh remote-settings fetch at startup.
The environment block, merged per variable since v2.1.223 — each variable comes from the highest-priority source that defines it, so lower sources fill in the gaps rather than being discarded.
Writing a policy that constrains something
Most managed-only keys are locks. The value a lock governs — permission rules, sandbox domains — is an ordinary key any level can set; the lock tells Claude Code to honour only the managed value. Deploying rules without the corresponding lock is the most common way a policy ends up advisory rather than binding.
// A managed policy that actually constrains something.
{
"permissions": {
"deny": ["Read(./.env)", "Read(./secrets/**)"],
"disableBypassPermissionsMode": "disable"
},
// Without this, a developer's own allow rules still apply
// alongside yours. With it, ONLY managed rules count — and
// --allowedTools is ignored too.
"allowManagedPermissionRulesOnly": true
}
# Confirm it landed on one machine before the fleet:
/status # look for the "Setting sources" line
# Enterprise managed settings (file)
# ... (remote) (plist) (HKLM) (drop-ins) (HKCU)
# ... (parent process) (helper)
claude doctor # lists every entry Claude Code DROPPED, with
# its source and field
There is a long list of managed-only keys beyond permissions: controls for which hooks may run, which MCP servers are admitted, which plugin marketplaces are permitted, whether command-sourced plugins run at all, whether the sideload flags are rejected at startup, and whether skills, agents, hooks and MCP servers may come from user and project sources at all. The settings reference marks each one, and the scope line is the field to read.
Invalid values do not all fail the same way
Claude Code is deliberately tolerant with managed settings: it repairs what it can, drops top-level keys that still fail, and keeps enforcing everything valid. A handful of enforcement keys refuse to be dropped, because dropping them would be the insecure outcome:
An invalid MCP server allowlist is enforced as an empty allowlist, so no servers are admitted until it is fixed.
An invalid model allowlist is enforced as empty too, leaving only the default model available.
The managed-hooks-only, managed-MCP-only and command-plugin-source keys are all treated as true when invalid.
The version floor and ceiling deliberately fail open instead, so a bad policy push cannot stop Claude Code from starting at all.
That last one is the design decision worth appreciating. Every other enforcement key fails closed, but the version constraints fail open, because a typo in a minimum-version field that bricked every developer's CLI would be a far worse outcome than a temporarily unenforced version floor. It is a good instinct to copy in your own policy tooling.
What a developer can still change
Managed settings are strong, and it is worth being honest about the four things that sit outside them, because a security review will ask:
The model for a session. A managed model value is a default, not a lock — the flag and the environment variable still pick the model, so deploy the model allowlist to restrict the choice.
Local administrator rights. Someone who is an admin on the machine can edit the managed source itself, which is exactly why MDM tooling redeploys on a schedule.
The server-managed cache, where a local edit lasts only until the next successful fetch.
Other tools entirely. Managed settings bind Claude Code, not a developer calling the API from something else.
If several teams own parts of one policy, use the drop-in directory rather than a shared file. Claude Code merges the main file first, then every JSON file in the directory alphabetically, so numeric prefixes control the order. Lists combine with duplicates removed, nested blocks merge key by key, and single values are replaced by the later file — which means two teams can own genuinely separate concerns without editing the same file.
Answering whether it is actually in force
Two commands settle every version of this question. The status command's setting-sources line names the managed source Claude Code selected, in parentheses, so you learn both that a policy is active and which of your four mechanisms won. A missing line means no source delivered a policy key at all; a line naming a different source means a higher-priority one was present and yours was ignored.
The doctor command answers the other half: what got dropped. When a file, profile, registry value or server payload fails schema validation, Claude Code skips the individual entries it can repair with a warning each, then drops any top-level key whose value still fails. Interactive sessions show a dialog at startup, non-interactive runs print to standard error, and the doctor command lists each invalid entry with its source and field.
The rule to carry away is that managed settings are not a merge, they are a selection. Decide which of the four mechanisms is your source of truth, deploy only through it, and verify with the status line on one machine before touching the fleet. Then pair every rule with the lock that makes it binding, because a permission rule without its lock is a suggestion — and a suggestion is not what anyone deploying managed settings is trying to ship.