Part 2 · Determinism & Control

Mastering Claude Code · ~7 min

Managed Settings

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.

Why this, for you: the moment more than one team needs to add a Claude Code policy, the single 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.

1 One file per team, merged at runtime

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.

The security team can push 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.

2 How fragments merge — by value type

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 typeMerge behavior
Scalar (string, bool, number)Later file wins
ArrayConcatenated and de-duplicated
ObjectDeep-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.

# /etc/claude-code/managed-settings.d/ — numeric prefixes set merge order 00-security.json # deny rules, allowManagedPermissionRulesOnly 50-platform.json # MCP allowlist, telemetry, channelsEnabled 80-product.json # allow rules for known safe workflows # Lower numbers merge first; for a scalar, the higher number wins.

3 The gotcha: silent scalar conflicts

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.

Two teams, one scalar key, no error

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.

There is also a hard override above the files: Claude Code 2.1.30+/2.1.38+ supports server-managed settings from the admin console. If the server delivers any non-empty config, Claude Code ignores all endpoint-managed settings — including every managed-settings.d/ fragment. The two don't merge. Pick one delivery channel per org.

↪ Your win: a multi-owner policy floor

  • One fragment per team in managed-settings.d/ — independent CI, no shared-file bottleneck.
  • Merge by type — scalars: last file wins; arrays: concatenated and de-duped; objects: deep-merged.
  • Numeric prefixes set order00- first, higher numbers win scalar ties.
  • Avoid silent overrides — give each team a non-overlapping settings domain and review it.
  • Know the override — server-managed settings, if present, replace endpoint-managed entirely.

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…

Ask me anything. Want a worked three-fragment layout for your own security / platform / product split, or help deciding between endpoint-managed files and server-managed delivery? Next in Part 2: The Skill Eval Loop — measure a skill against evals and reload it mid-session to tighten it without restarting.
✎ Feedback