ModulesPhase 2: Control

5. Permissions and isolation

/permissions/sandbox
The 30-second answer

"Claude Code decides what Claude may do in layers. A permission mode sets the baseline for the session: ask before almost everything (Manual), accept file edits, plan without editing, let a classifier review risky actions (auto), deny anything not pre-approved (dontAsk), or skip checks entirely (bypass, for containers only). Permission rules in settings then allow, ask about, or deny specific calls. They're checked deny first, and a deny in any settings file beats an allow in any other. /permissions is where you see and edit them. The catch: a Bash rule matches the text of the command, so a determined /bin/rm or bash -c gets past it. The hard boundary is the sandbox, which the operating system enforces around every shell command. /sandbox turns it on."

The sentence that marks you as an architect: rules decide what Claude may try, the sandbox decides what a command can actually touch.

Say it yourself first, then compare.
See it

7 pictures, in order.

Use the arrow keys or the dots. Tap a picture to see it full size.

Four layers, four different questions1 of 7
Know it

The facts someone can check.

The six permission modes
Mode (config value) Runs without asking Use it for
default, labeled Manual Reads only Sensitive work, unfamiliar code
acceptEdits Reads, file edits, and mkdir, touch, rm, rmdir, mv, cp, sed inside the working directories Iterating, then reviewing in git diff
plan Reads and exploring. No source edits until you approve the plan Exploring before changing anything
auto Everything, with a classifier reviewing risky actions Long tasks, cutting prompt fatigue
dontAsk Reads and pre-approved tools. Anything that would prompt is denied CI and scripts
bypassPermissions Everything, including protected paths Containers and VMs only
  • Switching. Shift+Tab cycles modes in the CLI. From auto, the cycle runs Manual, acceptEdits, plan, and back. bypassPermissions joins only if the session started with it enabled. dontAsk is never in the cycle: start with --permission-mode dontAsk.
  • Starting mode. From v2.1.283, auto is the built-in starting mode for interactive terminal and VS Code sessions. claude -p and Agent SDK runs start in Manual, and from v2.1.302 a call that needs approval is simply denied unless a rule, hook, or callback approves it.
  • A repo can't put you in auto or bypass. defaultMode: "auto" or "bypassPermissions" in .claude/settings.json or .claude/settings.local.json is ignored. Put it in ~/.claude/settings.json or managed settings.
  • Plan mode blocks source edits until you approve the plan. The approval offers "Yes, and use auto mode", "Yes, manually approve edits", or "No, keep planning". Ctrl+G opens the plan in your editor first. Typing /plan before a prompt also enters it.
  • Protected paths such as .git, .claude, .vscode, .husky, shell startup files, and .mcp.json are never auto-approved for writes, except in bypassPermissions. An allow rule doesn't change that.
  • Deny rules block in every mode, bypassPermissions included. Allow rules have no effect in bypassPermissions.
Permission rules: the syntax

Every rule is Tool or Tool(specifier), and the specifier means something different per tool.

Rule What it matches
Bash Every Bash command. As a deny, it removes the tool from Claude's context entirely
Bash(npm run *) npm run build, npm run test --watch, and plain npm run
Bash(ls *) ls -la and ls, but not lsof: the space before * is part of the rule
Read(./.env), Edit(/src/**) gitignore patterns. // is absolute, ~/ is home, / is relative to the settings file, ./ to the current folder
WebFetch(domain:example.com) That host only. domain:*.example.com covers subdomains but not the bare domain
mcp__github__* Every tool on the github MCP server
Agent(Explore) The Explore subagent
  • Put the * after the subcommand. Bash(git log *) allows only git log. Bash(git *) allows all of git, and Bash(git * main) lets git push origin main through.
  • Compound commands are split. Bash(safe *) doesn't approve safe && other. Every part has to match on its own. Approving a compound command saves at most 5 rules, one per part.
  • A Bash rule matches the text Claude writes, after stripping a fixed set of wrappers like timeout and nohup. Bash(rm *) in deny stops rm -rf build/, not /bin/rm -rf build/ or bash -c 'rm -rf build/'. The docs say it plainly: a deny rule covers the usual invocation and isn't a security boundary around the program.
  • A Read deny also blocks Edit and Write on the same path, but only for Claude's own tools and file commands Claude Code recognizes. A Python script that opens the file itself isn't covered. That's the sandbox's job.
How rules decide
  • Evaluation order is deny, then ask, then allow. The first match decides. Specificity changes nothing: a broad Bash(aws *) deny beats a narrow Bash(aws s3 ls) allow.
  • No match means the permission mode decides.
  • An ask rule prompts even in auto mode and bypassPermissions.
Settings precedence, highest first
Level File Notes
Managed managed-settings.json, MDM, or server-managed settings Nothing overrides it, not even --allowedTools
Command line --settings for one session --disallowedTools can add limits beyond managed
Project local .claude/settings.local.json Where "Yes, don't ask again" saves, at the repo root
Shared project .claude/settings.json, committed Its allow rules wait until you accept workspace trust
User ~/.claude/settings.json Your rules for every project
  • Rule lists merge. permissions.allow from every file is combined, and a deny at any level blocks an allow at any other level, in both directions.
  • Locks for an organization: allowManagedPermissionRulesOnly makes managed settings the only source of rules. permissions.disableBypassPermissionsMode: "disable" and permissions.disableAutoMode: "disable" remove those modes.
  • Workspace trust. A cloned repo's allow rules and extra directories don't apply until you accept the trust dialog. Its deny and ask rules apply at once, since they only restrict.
Auto mode

A second model, the classifier, reviews actions instead of you. The order for every action:

  1. Your allow, ask, and deny rules resolve first.
  2. Read-only actions and file edits in the working directory are approved outright.
  3. Everything else, mostly shell commands and network calls, goes to the classifier.
  4. A block sends Claude the reason, and the action shows under Recently denied in /permissions, where r retries it.
  • Blocked by default: download-and-run like curl | bash, sending sensitive data out, production deploys, force push, git reset --hard, granting IAM or repo permissions, printing a live credential. Allowed by default: local file work, installing what your lock files declare, read-only HTTP, pushing to a branch of the repo you're in.
  • 3 blocks in a row, or 20 in a session, pause auto mode and Claude Code goes back to prompting. Neither number is configurable.
  • The classifier never sees tool results. It reads your messages, the tool calls, and CLAUDE.md, so hostile text in a file or web page can't argue with it.
  • Broad allow rules are dropped on entry: Bash(*), wildcarded interpreters like Bash(python*), package-manager run rules, and Agent and Monitor allow rules. They come back when you leave auto mode.
  • "Don't push" in chat counts, but only until compaction drops that message. A deny rule is the durable version.
  • Trusted infrastructure goes in autoMode.environment in user or managed settings, never project settings. claude auto-mode defaults prints the built-in rules; claude auto-mode config prints what the classifier actually uses.
The sandbox
Access Default inside the sandbox Change it with
Writes Working directory, a per-user temp directory, added directories. Protected config files stay blocked filesystem.allowWrite, denyWrite
Reads Most of the machine, including ~/.ssh and ~/.aws/credentials filesystem.denyRead, credentials
Network No direct route. A local proxy checks each host against allowed domains, which start empty network.allowedDomains, deniedDomains
Environment Inherited from Claude Code, secrets included credentials
  • Off by default. Turn it on with /sandbox (saved to .claude/settings.local.json) or sandbox.enabled: true in settings.
  • macOS uses Seatbelt, Linux and WSL2 use bubblewrap and socat. Native Windows runs commands unsandboxed.
  • What it covers: Bash, PowerShell, and Monitor commands and every process they start. What it doesn't: Read, Edit, and WebFetch (rules govern those), hooks, local MCP servers, the status line, commands you type after !, and anything in excludedCommands.
  • Two sandbox modes. Auto-allow runs sandboxed commands without a prompt, even in Manual mode. Regular permissions keeps every prompt. The boundary is the same in both.
  • The escape hatch. When a command fails inside, Claude can ask to retry it with dangerouslyDisableSandbox. allowUnsandboxedCommands: false turns that off.
  • If the sandbox can't start, commands run unsandboxed unless failIfUnavailable: true.
  • For an organization, deliver three keys in managed settings: enabled: true, failIfUnavailable: true, allowUnsandboxedCommands: false. That last one also makes the sandbox admin-required, so a repo's settings can't loosen it.
/fewer-permission-prompts

A bundled skill. It scans your transcripts for common read-only Bash and MCP calls and adds a prioritized allowlist to the project's .claude/settings.json. It's the deliberate, shareable version of clicking "don't ask again" a few hundred times.

What /permissions actually does

Opens a dialog listing every rule with the settings file it came from. You can add or remove rules, manage working directories, review recent auto mode denials, and view the auto mode classifier rules on the Auto mode tab. Since v2.1.234 you can open it while Claude is working, and changes apply from Claude's next tool call. Its alias is /allowed-tools.

Rules vs the sandbox

Permission rules are judged before anything runs, from the command string. The sandbox is enforced by the operating system on the running process, so it holds even when an allowed command does more than its name suggests, or when a prompt injection gets past the model. Use both: rules to shape what Claude attempts and keep prompts sensible, the sandbox for what must never be reachable.

Quiz

Answer out loud, then flip the card.

Mark each one honestly. Cards you miss stay flagged for review, in this browser.

0 of 8 right
Question 1

A customer says "we added Bash(curl *) to deny, so Claude can't reach the internet." Is that enough?

No. A Bash rule matches the command text Claude writes. /usr/bin/curl, sh -c 'curl ...', or a Python script that opens a socket all get past it, and WebFetch is a separate tool with its own rules. For a real network boundary, turn on the sandbox: allowed domains start empty, and every connection goes through a proxy that checks the host. At org scale, set allowManagedDomainsOnly in managed settings so only the organization's domain list counts.

Question 2

Developers say they're drowning in permission prompts. What do you recommend, in order?

First, run /fewer-permission-prompts to turn the read-only calls they keep approving into a shared allowlist in project settings. Second, turn on the sandbox in auto-allow mode, so sandboxed commands run without prompts inside an OS boundary. Third, auto mode, which is already the default in current versions, with autoMode.environment listing the repos, buckets, and domains the company trusts so routine work stops getting blocked. Never bypassPermissions on a real machine.

Question 3

Security wants a guarantee that nobody uses bypassPermissions, and that one team can't use auto mode. How?

Managed settings: permissions.disableBypassPermissionsMode: "disable" and permissions.disableAutoMode: "disable". Managed settings sit above every other level, including command-line flags, so a developer can't undo them. Deliver them by MDM as managed-settings.json or through server-managed settings.

Question 4

Project settings allow Bash(npm *). A developer's user settings deny Bash(npm publish *). Can Claude run npm publish? npm test?

npm publish is denied: rules from every file are pooled and deny is checked first, so a user-level deny blocks a project-level allow. npm test runs, because only the allow matches it.

Question 5

What's the difference between auto mode and the sandbox's auto-allow mode?

Auto mode is a permission mode: a classifier model reviews actions across all tools before they run. Auto-allow is a sandbox mode: Bash commands run without a prompt because the OS boundary already contains them. They're independent and combine well. This session runs auto mode with the sandbox on: when a sandboxed command needs a new host, Claude names the host on the command and the classifier reviews the two together.

Question 6

A CI job should let Claude run the test suite and nothing else, unattended. What's the setup?

claude -p "run the test suite" --permission-mode dontAsk --allowedTools "Bash(npm test)" "Read", inside the CI runner's container. dontAsk denies anything that would prompt, so the run never hangs on a question. Don't reach for bypassPermissions: it skips checks rather than limiting them.

Question 7

Someone runs claude -p over a repo they just cloned. What does the repo get to do?

-p never shows the workspace trust dialog, and it treats the folder as trusted for hooks, the env block, and .mcp.json servers, which all run. The repo's permissions.allow rules don't apply; Claude Code prints a "not trusted" warning instead. To be safe, pass --setting-sources user or --bare, or --settings '{"disableAllHooks": true}', and reject unknown servers with disabledMcpjsonServers.

Question 8

Why use plan mode instead of just telling Claude "don't edit anything yet"?

Plan mode is enforced by Claude Code: edits stay blocked until you approve the plan, whatever Claude decides. "Don't edit yet" is an instruction Claude tries to follow. Same lesson as Module 1: guidance versus enforcement. The approval step also gives you a clean handoff into auto mode or manual edit review.

Traps

Wrong answers that sound right.

Before you tap, say why each one is wrong.

Try it

Three moves in a fresh project.

Facts checked against code.claude.com/docs/en/permissions, permission-modes, sandboxing, settings, auto-mode-config, security, and commands on 2026-10-25. Claude Code ships fast: confirm anything that matters against the official docs.