Blog
Guides

Claude Code managed settings for a team: a working file, and what it can't do

A managed-settings.json for a small team: block secrets and force pushes, ask before git push, turn off bypass mode, and log each decision with OpenTelemetry.

Aadil Ghani
Aadil Ghani
Founder, Pushary
Nov 6, 20266 min read
Share

Managed settings are the Claude Code settings nobody on the team can override. You put them in one file on each machine, or, on Claude for Teams and Claude for Enterprise, an Owner sets them once in the claude.ai console. Below is a file a team of five can use today, how Claude Code reads it, where it leaks, and the part of the team problem it doesn't touch.

Everything here was checked against Anthropic's Claude Code docs on 6 November 2026. Claude Code ships most days, so read the managed settings docs before you copy anything into production.

Key takeaways

  • The file lives at /Library/Application Support/ClaudeCode/managed-settings.json on macOS, /etc/claude-code/managed-settings.json on Linux and WSL, and C:\Program Files\ClaudeCode\managed-settings.json on Windows.
  • Managed settings sit above every other level. A tool denied there can't be allowed anywhere else.
  • Claude Code checks deny, then ask, then allow. An ask rule still prompts when a narrower allow rule matches.
  • Every prompt still goes to the person at that terminal. Managed settings can't ask a lead first.

Where managed settings live

There are two ways to deliver them, and both sit at the top of the settings stack.

A file on each machine. The paths are in the takeaways above. You can also push the same JSON through MDM: the com.anthropic.claudecode preferences domain on macOS, or a Settings value under HKLM\SOFTWARE\Policies\ClaudeCode on Windows. If you deploy MCP servers centrally, managed-mcp.json sits next to the settings file, and Claude Code then stops loading MCP servers people add themselves.

Server-managed settings. On Claude for Teams and Claude for Enterprise, an Owner or Primary Owner sets them under Organization settings, Claude Code, Managed settings in the claude.ai console. Claude Code fetches them at startup and checks for changes every hour. Three things to know before you rely on them:

  • They apply the same way to everyone in the organization. Anthropic's docs say per-group settings are not supported yet.
  • They need a direct connection to api.anthropic.com. A session on Bedrock, Google Cloud, Foundry or a custom base URL skips them, and so does a CI job that signs in with a Console API key, because that key belongs to a different organization.
  • managed-mcp.json can't be delivered this way.

The full order, highest first: managed settings, JSON passed with --settings on the command line, .claude/settings.local.json, .claude/settings.json, then ~/.claude/settings.json.

A file a small team can use

{
  "permissions": {
    "deny": [
      "Read(**/.env)",
      "Read(**/.env.*)",
      "Read(**/secrets/**)",
      "Bash(rm -rf *)",
      "Bash(git push --force*)",
      "Bash(git push -f *)",
      "Bash(git push * --force*)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(npm run deploy*)"
    ],
    "disableBypassPermissionsMode": "disable"
  },
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "otlp",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel-collector.example.com:4317"
  }
}

Every key above checks out against the published settings schema. What each part does:

  • deny stops reads of .env files and anything under a secrets folder, rm -rf, and force pushes. Read(**/.env.*) also blocks .env.example, so drop it if your agents need that file.
  • ask makes Claude Code prompt before any git push and before your deploy script, even when someone has an allow rule for it. Swap npm run deploy for whatever your team runs.
  • disableBypassPermissionsMode set to "disable" makes Claude Code reject --dangerously-skip-permissions. Nobody can switch into bypass mode.
  • env turns on telemetry and sends it to your own OpenTelemetry collector. More on that below.

Two keys worth adding once the basics work. "allowManagedPermissionRulesOnly": true makes managed settings the only source of permission rules: Claude Code ignores allow, ask and deny rules in everyone's own files and hides the always-allow choice in prompts. And "disableAutoMode": "disable" takes auto mode out of the Shift+Tab cycle, which matters because on Team and Enterprise plans auto mode is available by default.

How Claude Code reads the rules

Rules are checked in a fixed order: deny, then ask, then allow. The first match decides, and a more specific rule doesn't jump the queue. Two consequences people trip on:

  • A tool denied at any level can't be allowed at any other level.
  • An ask rule prompts even when a more specific allow rule also matches. In the file above, git push --force matches a deny rule and the git push * ask rule, and deny is checked first, so it is refused. A plain git push matches only the ask rule, so it asks.

Where the rules leak

Bash rules match the text of the command, not what it does. Anthropic's own docs give the examples: Bash(rm *) stops rm -rf build/ but not /bin/rm -rf build/ or bash -c 'rm -rf build/', and Bash(git push *) doesn't stop git -C . push origin main. Against the file above, rm -fr and git push origin +main slip past the deny rules too (the push still hits the ask rule). Read deny rules don't cover a command like grep -r pattern . that reads files without naming them.

So treat the file as a seatbelt. For hard limits, turn on Claude Code's sandbox, or check commands in a PreToolUse hook that parses them.

Managed settings are also a client-side control. Anthropic says plainly that a developer who is an administrator on the machine can edit the managed file, and that managed settings bind Claude Code only. Someone calling the API from another tool isn't covered.

Seeing who said yes

With the env block above, Claude Code logs a claude_code.tool_decision event each time a tool call is accepted or rejected. Each event carries:

  • decision: accept or reject
  • source: config, hook, user_permanent, user_temporary, user_abort or user_reject
  • tool_name, plus user.email when the person signed in with OAuth. Anthropic's docs say the email goes only to the endpoint you configure, never to Anthropic.

Three catches. You run the collector and whatever reads it. The command itself isn't in the event unless you also set OTEL_LOG_TOOL_DETAILS=1, which adds each call's parameters, such as the full command and file paths. And an endpoint set from the claude.ai console needs each person to approve it in an interactive session, then takes effect at their next launch.

What managed settings can't do for a team

They decide what Claude Code may run. They don't decide who gets asked.

  1. Nobody else can be asked. A permission prompt goes to the person at that terminal. There is no setting that sends a git push in your infrastructure repository to a lead before it runs.
  2. Everyone gets the same rules. Settings from the claude.ai console apply to the whole organization. You can't give the payments team a stricter file than everyone else from there.
  3. Only Claude Code is covered. Codex, Cursor and Gemini CLI each read their own configuration. A team that runs all four keeps four sets of rules and four records, or none.

And the telemetry record says who accepted a prompt at their own terminal. It can't say a second person agreed, because no second person was asked.

Where Pushary fits

Pushary for Teams works on the second half. Once a second person joins, each person's agent asks that person, on their phone and in the Pushary dashboard. An owner or admin can write a routing rule that sends a matching step, such as a push to the infrastructure repository, to a lead or a role instead. The team sees one record of whose agent asked and who tapped yes, across Claude Code, Codex and Cursor. How Pushary for Teams decides who an agent asks covers the rules in detail.

Two limits, so nobody is surprised. A routing rule decides who Pushary asks, but it doesn't lock the terminal: the person whose agent asked can still say yes at their own agent's prompt, and that yes carries no name. An answer from a web link carries no name either. Answers in the Pushary phone app, Mac app and dashboard do.

Two settings to watch if you use both. Pushary's setup writes its Claude Code hooks to each person's ~/.claude/settings.json, so with "allowManagedHooksOnly": true those hooks stop running. Setup also adds an allow rule for Pushary's own tools, mcp__pushary__*, to the same file, so with "allowManagedPermissionRulesOnly": true put that rule in managed settings, or Pushary's tools will prompt every time.

Team is $59 a month for 5 people, plus $12 a month for each extra person, and new workspaces get 3 days free. The Team setup guide walks through connecting everyone.

Frequently asked questions

Where is managed-settings.json for Claude Code?

On macOS it is /Library/Application Support/ClaudeCode/managed-settings.json. On Linux and WSL it is /etc/claude-code/managed-settings.json. On Windows it is C:\Program Files\ClaudeCode\managed-settings.json; Claude Code no longer reads the old C:\ProgramData\ClaudeCode path. On Claude for Teams and Claude for Enterprise, an Owner can also set the same keys once in the claude.ai console, under Organization settings, Claude Code, Managed settings.

Can managed settings stop people using --dangerously-skip-permissions?

Yes. Set permissions.disableBypassPermissionsMode to the string "disable" in managed settings. Claude Code then rejects the --dangerously-skip-permissions flag and nobody can switch to bypass permissions mode. It is one key; there is no separate setting for the flag.

Can Claude Code send a permission prompt to a team lead instead of the developer?

Not on its own. A Claude Code permission prompt goes to the person at that terminal, and no managed setting sends it to someone else first. On the Pushary Team plan, an owner or admin can write a routing rule that sends a matching step, such as a push to the infrastructure repository, to a lead or a role instead.

Does Claude Code record who approved a tool call?

Only if you turn on telemetry. With CLAUDE_CODE_ENABLE_TELEMETRY and an OTLP exporter set, Claude Code logs a claude_code.tool_decision event for every accept or reject, with the decision, where it came from and, when the person signed in with OAuth, their email. It goes to the collector you run, not to Anthropic. The command itself is only included when OTEL_LOG_TOOL_DETAILS=1 is set.

Aadil Ghani
Aadil Ghani
Founder, Pushary

Building Pushary so an AI agent can reach you on your phone and wait for a yes before it does something you would not want.

Read next

Guides

What --dangerously-skip-permissions does, and a safer way to run unattended

Let routine work continue. Choose which commands need your answer, and know what an approval hook cannot protect.

Jun 13, 2026Updated Nov 2, 20264 min readAadil Ghani
Guides

Can an AI agent delete your files or drop your database?

Yes, an agent with shell or database access can delete your files, and it has happened in production. Here is how to gate it.

May 15, 20264 min readAadil Ghani
Guides

Who approved it? What Claude Code, Codex, Cursor and Copilot team plans record

Each tool lets the person running it say yes. None of them, on any team plan, documents asking a second person first. Here is what each one does record.

Nov 6, 20266 min readAadil Ghani

Let your agents work. Stay in control.

Get the questions that need you on your phone or Mac. Approve, reject, or answer so your agent knows what to do next.