Mastering Claude Code · ~7 min
One drop-in file per team, composed at runtime — so security, platform, and product each own their policy without ever fighting over a shared config.
managed-settings.json becomes a contested file with one owner, one review queue, and one deploy. Every
rule change waits on that bottleneck. The drop-in directory dissolves it — and this lesson is how you ship it without
silently clobbering another team's rule.In the last lesson you tuned autonomy per session. Managed settings are the layer above that: the org floor a user can't override. The trick is letting several teams write to that floor at once.
The managed-settings.d/ directory follows the systemd drop-in convention: fragments in the .d/
directory are parsed and layered on top of the base managed-settings.json. Each team deploys its own fragment
through its own CI pipeline; Claude Code composes them when it starts.
00-security.json without touching the platform team's file.
Per-team ownership replaces a single shared resource — no coordination per change, and merge-conflict
risk drops from high to low because each team edits a separate file.The directory sits alongside managed-settings.json in the system directory for each platform — on
Linux/WSL that's /etc/claude-code/managed-settings.d/, on macOS
/Library/Application Support/ClaudeCode/managed-settings.d/. Because it's a system path, the OS can
protect it from user modification — which is why Anthropic positions endpoint-managed files as the stronger option on
MDM-enrolled devices.
managed-settings.json is always merged first as the base. Then every *.json in
managed-settings.d/ is applied in alphabetical order (hidden dot-files are ignored). What
"merge" means depends on the value's type:
| Value type | Merge behavior |
|---|---|
| Scalar (string, bool, number) | Later file wins |
| Array | Concatenated and de-duplicated |
| Object | Deep-merged recursively |
So a security fragment's deny rules and a product fragment's allow rules both
survive into the final permissions array — arrays accumulate. But for a scalar like
disableBypassPermissionsMode, only the alphabetically last fragment that sets it counts.
The one thing a fragment can do that a single file can't is overwrite another team's scalar without warning. A single file makes conflicts explicit in a diff; fragments make them implicit — whoever sorts later wins.
If 50-platform.json and 80-product.json both set the same scalar, the
alphabetically later file wins silently. Defend against it structurally: design fragments so
teams own non-overlapping settings domains, and enforce that boundary in policy review. Numeric
prefixes make the order explicit, but they don't make a collision loud.
One scalar earns special attention: allowManagedPermissionRulesOnly: true in a security fragment means
user and project settings cannot add their own permission rules — the merged managed policy becomes the
only one that applies. That's the guardrail that makes the whole layer a real floor rather than a suggestion.
managed-settings.d/
fragment. The two don't merge. Pick one delivery channel per org.
managed-settings.d/ — independent CI, no shared-file bottleneck.00- first, higher numbers win scalar ties.Retrieval practice — recall, don't peek
Question 1The core problem managed-settings.d/ solves is…
Question 2When two fragments set the same scalar key, the winner is…
Question 3When two fragments each add permission rules, an array value is…
Question 4If server-managed settings deliver a non-empty config, Claude Code…
Question 5 · spaced recall from an earlier lessonFrom Permission Modes: the hard floor on what an agent can never do is set by…