Skip to content

Server-managed settings

Push Claude Code policy from the claude.ai admin console with no MDM, and understand caching, approval dialogs, fail-closed startup and who actually receives it.

Server-managed settings let an organisation Owner write Claude Code policy once in the claude.ai admin console and have every eligible session pick it up. No MDM, no files to push, no registry keys. Claude Code fetches the policy when it starts and checks for changes every hour.

It is the quickest way to get a policy in front of a Teams or Enterprise organisation. It is also the softest: the policy is enforced by the client, so treat it as guard rails rather than a security boundary. This page explains how to set it up, how delivery and caching work, and where its limits are.

What you need

  • A Claude for Teams or Claude for Enterprise plan.
  • The Owner or Primary Owner role to view or change the configuration. Every change applies to the whole organisation, so keep that role tight.
  • Clients that can reach api.anthropic.com.

Server-managed or endpoint-managed?

Server-managedEndpoint-managed
Delivered byAnthropic's servers (or a Claude apps gateway)MDM profiles, registry policy or a file on disk
SuitsOrganisations without MDM, unmanaged or BYOD devicesFleets already under MDM
Tamper resistanceLow: a local cache the user can editHigher: the OS can lock the file or profile
Reaches Anthropic-hosted cloud sessionsYesNo

My usual answer for a managed fleet is both: endpoint-managed policy as the hard control on laptops, plus server-managed policy so that cloud sessions and the odd unmanaged machine are covered. Sessions in self-hosted environments also read a managed file baked into the runner image.

Setting it up

  1. Open Organization settings > Claude Code > Managed settings on claude.ai. If it says you lack access, ask an Owner.
  2. Paste in JSON. Any key valid in settings.json works, including hooks, env and the managed-only keys, apart from the few listed under limitations.
  3. Save. Clients pick it up at their next start or hourly poll.

A starter policy for a consultancy, say, that wants to stop Claude reading client secrets and make sure every session logs edits:

{
  "permissions": {
    "deny": [
      "Read(./**/*.pem)",
      "Read(./**/appsettings.Production.json)",
      "Bash(scp *)"
    ],
    "disableBypassPermissionsMode": "disable"
  },
  "allowManagedPermissionRulesOnly": true,
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          { "type": "command", "command": "/opt/acme/bin/log-change" }
        ]
      }
    ]
  }
}

Two cautions. First, a Bash rule like Bash(scp *) matches the command as Claude writes it, not every way of invoking the same binary. For network enforcement that cannot be sidestepped, use a sandbox with allowManagedDomainsOnly. Second, hooks run shell commands, so developers get an approval dialog before they apply (see approval dialogs).

You can deliver an autoMode block the same way to tell the auto mode classifier which repositories, buckets and domains you trust.

Checking delivery

Ask someone to restart Claude Code. If your policy contains anything that needs approval, they will see the dialog at that restart, or within an hour in a running interactive session. /permissions shows the effective permission rules.

For a definitive answer, run claude doctor (v2.1.248+) and read Managed settings (remote). It reports one of:

  • the settings loaded;
  • the organisation has none configured;
  • the fetch failed, with the cause and whether a cached copy still applies;
  • the fetch was skipped, with the reason.

/status shows the same line in a running session when the fetch failed or was skipped for certain reasons, such as a provider variable or custom ANTHROPIC_BASE_URL in the user's shell.

For deeper debugging, run claude --debug-file /tmp/cc-debug.log and search for Remote settings. I always test a new payload on one machine with claude doctor before saving it for everyone.

Limitations

  • One policy for everyone. Per-group policy is not supported yet. A Claude apps gateway can serve different policy per IdP group.
  • No managed-mcp.json. Use allowedMcpServers and deniedMcpServers instead, or (v2.1.259+) managedMcpServers, which accepts http and sse servers and supplements rather than replaces what users have. A managed-mcp.json deployed to disk is read separately and still applies. See managed MCP.
  • No OS-only keys. policyHelper and wslInheritsWindowsSettings are ignored here; put them in MDM or a system file.

How it fits with other managed sources

Server-managed and endpoint-managed settings share the top tier of the settings hierarchy. By default Claude Code uses the first source that has a policy key, checking server-managed first. The full ranking and the "merge" opt-in are on managed settings.

If server-managed settings deliver a policy key, a policyHelper in MDM or a file is not consulted. If a later fetch finds the server policy removed, the helper runs straight away.

If you clear the console policy intending to fall back to an MDM profile, remember the cached copy lingers on each client until its next successful fetch, and launch-time keys such as model stay until each client restarts.

Keys that combine across sources

A few keys break the no-merge rule:

  • Cross-source locks such as the sandbox allowlist locks apply if any admin source sets them (HKCU excluded).
  • env merges per variable (v2.1.223+): each variable comes from the highest source that defines it. Two sub-rules stop unsafe mixing:
    • The telemetry unit (OTEL_EXPORTER_OTLP_*, OTEL_LOG_*, OTEL_LOGS_EXPORTER, ENABLE_BETA_TRACING_DETAILED, BETA_TRACING_ENDPOINT) is taken as a block from the highest source that sets any of them. A source delivering otelHeadersHelper claims the unit, but only supplies the variables when it is the selected source. So an exporter endpoint never pairs with another source's credentials.
    • Routing variables paired with a credential key like apiKeyHelper only come through from the source that wins that slot.
  • allowedProviders (v2.1.285+) has its own combination rule.
  • Gateway sign-in keys (forceLoginGatewayUrl, gatewayInternalNetworks, forceLoginMethod: "gateway") are never read from server-managed settings.

Fetching and caching

First launch, no cache. If the developer is signing in at startup (first run, or after /logout), Claude Code waits up to five seconds for the fetch so that policy and your companyAnnouncements are in place from the first screen. Otherwise, or if the wait runs out, the session opens and policy lands a moment later. If the fetch fails, the session continues without server policy (endpoint policy still applies) and warns you, unless forceRemoteSettingsRefresh is set, in which case it exits.

Later launches. The cache at ~/.claude/remote-settings.json applies immediately, a fresh fetch runs in the background, and the cache survives network outages. Some cached values wait until the server confirms the payload:

  • modelPricing: until then, /usage and the status line show list prices.
  • managedMcpServers (v2.1.259+): Claude Code waits up to 30 seconds before connecting MCP servers; on failure the session starts without them and they connect later.
  • Sensitive env variables (v2.1.198+), so a tampered cache cannot hijack the very fetch that would correct it:
    • proxy and TLS settings (HTTPS_PROXY, NODE_EXTRA_CA_CERTS, CLAUDE_CODE_CLIENT_CERT, CLAUDE_CODE_CLIENT_KEY);
    • routing and provider selection (ANTHROPIC_BASE_URL, CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX, ANTHROPIC_BEDROCK_BASE_URL and similar);
    • credentials (ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, CLAUDE_CODE_OAUTH_TOKEN);
    • CLAUDE_CONFIG_DIR;
    • from v2.1.223, federation variables (ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_IDENTITY_TOKEN), ANTHROPIC_PROFILE, ANTHROPIC_CONFIG_DIR, and HOME, XDG_CONFIG_HOME, APPDATA, USERPROFILE.

Federation variables and the profile selectors are only read at startup, so delivering them from the server never switches credentials mid-session. Deliver those through endpoint-managed settings.

Proxies. If clients need a proxy to reach api.anthropic.com, the server-delivered proxy cannot help with the first fetch. Set it in an endpoint-managed env block (v2.1.223+), the shell environment or user settings.

Most updates apply to running sessions. OpenTelemetry exporter settings, model, and removing a variable from env wait for the next launch.

Invalid entries

From v2.1.169 a partly invalid payload applies everything valid and reports the rest, following the rules in managed settings. Startups that run on the cache treat invalid entries exactly as the original fetch did. If every entry in a payload fails, none falls back to a stricter value, and the payload contains anything besides the two retention keys (cleanupPeriodDays, desktopSessionCleanupPeriodDays), nothing is applied, the cache is left alone, and you see no setting in the server response could be applied as written. Stripped entries are never shown in, or run after, the approval dialog.

Fail-closed startup

By default a failed startup fetch falls back to the cache, or to no server policy at all. To make clients refuse to start without a fresh policy:

{ "forceRemoteSettingsRefresh": true }

With this on, sessions that fetch server-managed settings block at startup until the fetch succeeds and exit if it fails. The flag caches itself, so later launches enforce it even before their first fetch. Put it in an MDM profile or system file as well to cover the very first launch; it is honoured from any admin source. Requests carry Cache-Control: no-cache so proxies do not serve stale policy.

Make sure api.anthropic.com is reachable first, or nobody can start Claude Code. claude auth subcommands are exempt so people can always re-authenticate.

Gateway clients always wait for their fetch. If the gateway returns 401 to an attended interactive launch and this flag is off, the session opens signed out of the gateway with a "Cloud gateway session expired" message telling the user to run /login to reconnect. Any other failure exits.

Approval dialogs

Interactive sessions ask the user before applying anything that could run code or redirect traffic:

  • settings that execute commands: apiKeyHelper, statusLine, otelHeadersHelper;
  • sandbox binaries: sandbox.bwrapPath, sandbox.socatPath, sandbox.ripgrep;
  • sandbox network and isolation changes (v2.1.251+): sandbox.network.tlsTerminate, httpProxyPort, socksProxyPort, sandbox.credentials (unless it only contains deny rules), allowAppleEvents, enableWeakerNestedSandbox, enableWeakerNetworkIsolation, filesystem.disabled, allowAllUnixSockets, allowUnixSockets, allowMachLookup;
  • certain env variables;
  • any hook.

Rejecting the dialog exits Claude Code. A managed CLAUDE.md delivered through the claudeMd key does not need approval (from v2.1.260), because it is text, not a command.

Which env variables need approval

Applied silently: feature toggles, model and behaviour settings (ANTHROPIC_MODEL, DISABLE_PROMPT_CACHING, CLAUDE_CODE_EFFORT_LEVEL), compaction settings (DISABLE_AUTO_COMPACT), UI and accessibility options, numeric limits and timeouts.

Always need approval: any non-empty proxy, base URL or OTEL_EXPORTER_OTLP_ENDPOINT.

Decided by value:

VariableSilent whenOtherwise
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, DISABLE_ERROR_REPORTING, DISABLE_TELEMETRY, DO_NOT_TRACKTruthy (1, true)Dialog
API_FORCE_IDLE_TIMEOUTTruthyDialog
ENABLE_BETA_TRACING_DETAILED, OTEL_LOG_RAW_API_BODIESFalsy (0, false)Dialog
ANTHROPIC_CUSTOM_HEADERSOnly tagging headers such as Accept-LanguageDialog for anything that looks like a credential, tenant selector, routing override or API-behaviour header (Authorization, X-Api-Key, Host, anthropic-beta, X-Amzn-Bedrock-*), and for malformed lines. The check matches words in the name, so X-Client-Version also prompts.

How approvals are remembered

Approvals are stored in the config directory (~/.claude unless CLAUDE_CONFIG_DIR is set):

  • claude.ai login or keyless Console sign-in: one approval per organisation, owned by the account that last approved. Signing out and back in, or hopping organisations and returning, does not re-prompt unless the settings changed or another account approved in between. A different account in the same organisation is prompted again.
  • Gateway sign-in: one per gateway. Re-prompts when the settings change, the gateway changes or you accept a new certificate. Loopback HTTP development gateways never save approval.
  • Anything else (API key, CLAUDE_CODE_OAUTH_TOKEN): stored with the cache; re-prompts on change or after /logout / claude auth logout.

Approving sandbox.credentials or sandbox.network.tlsTerminate also covers the sandbox.network.allowedDomains in the same payload, so adding or removing a domain re-prompts.

When the dialog cannot be shown:

SituationWhat applies
Interactive session that cannot show it (v2.1.211+)Last-approved settings; dialog next time
claude install / claude updateLast-approved settings; dialog in your next interactive session. If startup waits for the fetch (fail-closed or gateway), the dialog appears during the command and piped installs fail.
Dialog closed by an errorLast-approved settings
Non-interactive (-p, Agent SDK, VS Code chat panel, desktop Code tab)Applied for that run only, not cached or recorded; fetched afresh each run until someone approves interactively

Who receives server-managed settings

Delivery needs a direct connection to api.anthropic.com and one of these credentials:

  • a Team or Enterprise OAuth login;
  • CLAUDE_CODE_OAUTH_TOKEN;
  • a directly configured API key;
  • a user_oauth Anthropic profile without a custom base_url (v2.1.257+).

Keys from apiKeyHelper and Workload Identity Federation credentials do not trigger a fetch. Cowork sessions never fetch from the console.

If a user has CLAUDE_CODE_USE_* or a non-default ANTHROPIC_BASE_URL exported in their shell, the fetch is skipped. You cannot undo that from the server (the fix would arrive through the skipped fetch), and an endpoint-managed env block does not restore it either, because eligibility is checked first. The user must remove the export or set the variable to "" in their user settings env. If you need enforcement that does not depend on users' shells, use endpoint-managed settings.

For Bedrock, Vertex AI, Foundry and Claude Platform on AWS, a Claude apps gateway provides equivalent delivery. The difference: a gateway client that cannot reach the gateway at startup exits rather than using the cache. Hourly refreshes fail open on both routes.

Auditing

Changes to settings are recorded and available through the compliance API or audit log export (ask your Anthropic account team). Events capture the action, the account and device, and references to old and new values.

To log local edits to settings files, including managed-settings.json, use a ConfigChange hook. It does not fire for server-managed refreshes or MDM changes, and it cannot block a policy_settings change.

Security realities

If a user...Then
Edits the cacheThe edit applies at startup (except withheld values) until the next fetch restores it. Launch-time keys persist until relaunch.
Deletes the cacheFirst-launch behaviour
Runs a modified binaryAny client-side control can be bypassed
Runs a very old versionNo server-managed settings at all
Cannot reach the APICache applies (minus withheld values), or nothing; fail-closed and gateway clients exit
Logs into another organisationNo settings delivered
Sets CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_MANTLE, CLAUDE_CODE_USE_VERTEX, CLAUDE_CODE_USE_FOUNDRY, CLAUDE_CODE_USE_ANTHROPIC_AWS or a custom base URLSettings bypassed
Intercepts traffic or disables TLS checksCan alter what is received

On unmanaged devices none of this needs admin rights. To limit which organisations credentials can reach, use network-level tenant restrictions; for real enforcement, use endpoint-managed settings on MDM-enrolled devices.