How Claude Code combines managed sources
When your organization delivers more than one managed source to the same machine, the managedSourcesBehavior key decides what Claude Code does with the others:
"first-wins", the default: Claude Code uses the highest-ranked source that delivers at least one policy key and ignores the rest rather than merging them, apart from the few keys in Keys read from every admin source. Claude Code shows no warning for the sources it skips;/statusnames the source it used and the ones it skipped."merge": Claude Code applies every admin source that delivers a policy key and combines them by kind of key: on most keys the higher-ranked source's value applies, lists union, and locks take the strictest value. Compose every managed source says where to set the key and how each kind of key combines. Requires Claude Code v2.1.242 or later.
Both settings rank the sources the same way. Two terms recur in this section:
- Policy key: any settings key other than the two control keys,
wslInheritsWindowsSettingsandmanagedSourcesBehavior. A managed settings file or MDM policy that contains only those doesn't count, and Claude Code moves on to the next source. - Admin source: one of the first three sources below. The HKCU registry is user-writable and isn't one.
Claude Code checks the sources in this order, highest priority first:
- Remote settings, delivered from claude.ai as server-managed settings or by a Claude apps gateway. Claude Code fetches this source only when the session authenticates to Anthropic's API directly with an eligible login or key, or signs in to a gateway with
/login. On other providers, or whenANTHROPIC_BASE_URLpoints somewhere other than Anthropic's API, it starts at the next source - MDM or OS-level policies: the macOS plist or the HKLM registry key
- Managed settings files,
managed-settings.d/*.jsonandmanaged-settings.jsonmerged together - The HKCU registry, on Windows, and on WSL once the HKLM registry or the Windows managed settings file turns
wslInheritsWindowsSettingson and the HKCU value also sets it. Claude Code reads it only when no source above it delivers a policy key and no host-supplied parent settings supply a restrictive key
This diagram shows the ranking, with examples of the cross-source keys Claude Code reads from the first three sources under either setting:
Keys read from every admin source
Under the default "first-wins" setting, Claude Code reads most keys only from the source it selected, and ignores a value in a lower-ranked source even when the selected source leaves that key unset.
A few keys work differently. Claude Code reads them from every admin source, so a lower-ranked MDM policy or managed settings file can still set them when the selected source doesn't. Claude Code leaves the user-writable HKCU registry out of that scan; when HKCU is the only source and no host supplies parent settings, HKCU applies like any selected source.
The cross-source keys include:
sandbox.network.allowManagedDomainsOnlyandsandbox.filesystem.allowManagedReadPathsOnly: atruein any admin source turns the lock on. While a lock is on, Claude Code unions the allowlist it locks,sandbox.network.allowedDomainstogether withWebFetch(domain:...)allow rules, orsandbox.filesystem.allowRead, across every admin source. Without the lock, Claude Code treats the allowlist like any other key, so under"first-wins"an unselected admin source's allowlist is ignoredallowAllClaudeAiMcps- The sandbox binary paths
sandbox.bwrapPathandsandbox.socatPath - The sandbox
ripgrepbinary,sandbox.ripgrep sandbox.filesystem.disabledandsandbox.network.strictAllowlistuseAutoModeDuringPlanandsyncClaudeAiSkills, where afalsefrom any admin source turns the behavior off. Afalsein the developer's user or local settings turns it off too; each key can only denyenableArtifact, where afalsefrom any admin source turns the Artifact tool off. Afalsein the developer's user, project, or local settings turns it off too, and no source turns it back on; see which lower-level values still count. Requires Claude Code v2.1.242 or latermaxEffortLevel, where the lowest cap in any admin source applies. If a developer sets a lower cap in their own settings or with--settings, Claude Code applies that one; no source can raise the cap. Requires Claude Code v2.1.267 or later- A commit-trailer opt-out in
attribution, or in the deprecatedincludeCoAuthoredBy, from any tier forceRemoteSettingsRefreshenv, merged per variable across the admin sources: each variable comes from the highest-priority source that defines it, so lower sources fill in variables the higher ones leave unset. A few variables follow their own rules; Per-key exceptions across managed sources names each one. Requires Claude Code v2.1.223 or later. Before v2.1.223, Claude Code applied the selected source's wholeenvblock only
Compose every managed source
To have Claude Code apply every admin source your organization delivers, set managedSourcesBehavior to "merge" in the highest-ranked source you deploy. Claude Code reads the key only from the highest-ranked source that carries either the key or a policy key, so a lower source can't opt itself into merging with the source above it, and a machine that never receives server-managed settings needs the key in its MDM profile too. The user-writable HKCU registry never merges with another source. Requires Claude Code v2.1.242 or later.
Under "merge", Claude Code adds a lower source's list entries, such as permissions.allow rules and hooks, to the policy, so turn it on only when every source ranked below your highest one is under an administrator's control.
This table shows how Claude Code combines each kind of key under "merge". The managedSourcesBehavior entry names every key in three of the rows: restriction allowlists, values taken whole, and keys read from the highest-ranked source only.
| Kind of key | How Claude Code combines it | Examples |
|---|---|---|
| Lists | Combines the entries from every source | permissions.allow, hooks, sandbox.network.allowedDomains, deniedMcpServers |
| Locks | Applies the strictest value any source sets; a looser value applies only from the highest-ranked source | allowManagedHooksOnly, permissions.disableBypassPermissionsMode, crossSessionInbound |
| Restriction allowlists | Takes the list whole from the highest-ranked source that sets it, without adding entries from lower sources | availableModels, allowedMcpServers, strictKnownMarketplaces, allowedChannelPlugins, and the fallbackModel chain |
| Values taken whole | Takes the value whole from the highest-ranked source that sets it, without combining entries or fields from lower sources | sandbox.credentials.awsPairs, sandbox.ripgrep |
| Provided MCP servers | Combines the server names from every source; when two sources set the same name, applies the higher-ranked source's whole entry | managedMcpServers |
| Keys read from the highest-ranked source only | Ignores the key in every lower source, even when the highest-ranked source leaves it unset | Credential helpers such as apiKeyHelper, login pins such as forceLoginOrgUUID, modelPicker, permissions.defaultMode |
env | Merges per variable across admin sources under either setting, as Keys read from every admin source describes | |
| Every other key | Takes the value from the highest-ranked source that sets it | model, cleanupPeriodDays |
To confirm which sources combined on a machine, read the Setting sources line in /status; that section says what each label means.
Compute the policy with a helper program
A policyHelper is an executable your MDM policy or managed settings file names, and Claude Code runs it to compute managed settings at startup. When the selected source configures one and the helper emits a managedSettings object, that output changes what Claude Code reads:
- The emitted
managedSettingsobject is the only managed settings for the session, including for the keys it otherwise reads from every admin source, apart fromforceRemoteSettingsRefresh, which has its own startup rule
For which helper runs fail, and what Claude Code does when one does, see Helper failures.
<span id="parent-settings-from-embedding-hosts" />
<span id="control-policy-from-an-embedding-host" />
<span id="merge-policy-from-an-embedding-host" />
Let an embedding host add policy
When another application launches Claude Code, such as Claude Desktop, an IDE extension, or an Agent SDK app, that host can pass its own managed settings through the SDK managedSettings option. Claude Code calls these parent settings.
By default, Claude Code ignores parent settings whenever an admin source is present: server-managed settings, an MDM or OS-level policy, or a managed settings file.
To have Claude Code merge parent settings alongside an admin source, set parentSettingsBehavior to "merge" in the highest-priority managed source; Claude Code reads the key from that source only.
Claude Code then keeps only the host's values that restrict what Claude can do, with one gap to know about: unless you also set the allowManaged*Only locks, the host's permission allow rules and sandbox allowlists still apply. See Restrict parent settings for the locks.
A policyHelper can turn parent merging off regardless of this key; its entry says when.
Claude Code also applies these checks to parent-supplied values on their own:
- When any admin source sets
allowManagedPermissionRulesOnly, Claude Code drops parent-supplied permission allow rules andadditionalDirectoriesas it reads them, even when a higher-priority source leaves the key unset. The key's effect on your own permission rules comes from the managed settings Claude Code applies, or from parent settings you've chosen to merge - Claude Code enforces the
forceLoginOrgUUIDorallowedMcpServersvalue in the managed settings it applies and blocks a parent-supplied one. A value in a lower admin source that Claude Code doesn't apply neither applies nor blocks the parent's. ThemanagedSourcesBehaviorentry says which source supplies each key under"merge". Before v2.1.223, a value in any admin source blocked the parent's - An
availableModelsvalue follows the same rule asallowedMcpServers
Keep Cowork folder access when only managed rules apply
Cowork in the Claude Desktop app runs its sessions on Claude Code and grants each session access to its working folders, such as the folder the user connects, through allow rules it supplies when it launches the session. When your managed policy sets allowManagedPermissionRulesOnly, Claude Code keeps only the allow rules in the managed policy: it drops allow rules a host supplies as parent settings, as --allowedTools, or in a settings file, so writes to those folders lose their pre-approval. In a Cowork session that asks before edits, Cowork can't show the prompt, and Claude reports each write as blocked because the path resolves to a protected location or a path outside the connected folder.
To restore the writes, add allow rules for those folders to the managed source Claude Code selects on those machines: on an MDM-managed fleet, that's the MDM policy rather than a separate managed settings file. This example uses the file form, and an MDM policy takes the same keys. It keeps allowManagedPermissionRulesOnly set and allows edits under a CoworkProjects folder in each user's home directory; replace the path with the folders your users connect:
{
"allowManagedPermissionRulesOnly": true,
"permissions": {
"allow": [
"Edit(~/CoworkProjects/**)"
]
}
}After you deploy the policy, Claude can save files under that folder in a new Cowork session. Read and Edit rules cover the path syntax, including the // form for absolute paths.
What a developer can change
A developer's own settings files, --settings values, and project files never override a managed value; the exceptions only let a stricter lower-level value count. Four things sit outside that rule:
- The model for a session: a managed
modelis a default, not a lock.--modelandANTHROPIC_MODELstill pick the model for that session, so deployavailableModelsto restrict the choice. - Local admin rights: a developer who is an administrator on the machine can edit the managed source itself, which is why MDM tooling can redeploy the profile or file on a schedule and why the HKLM registry and the macOS managed preferences domain exist.
- The server-managed cache: server-managed settings come from Anthropic's servers, and an edit to the local cache lasts only until the next successful fetch.
- Other tools: managed settings bind Claude Code only. A developer who calls the API from another tool isn't under them.
<span id="verify-enforcement" />
<span id="verify-that-a-policy-is-in-force" />