Claude Code — Permissions
Claude Code asks before it acts. Permission modes set the overall posture; allow/ask/deny rules fine-tune individual tools; sandboxing isolates Bash commands at the OS level.
Permission modes
The current docs list six modes:
| Mode | Behavior |
|---|---|
default | Prompts on first use of each tool. Labeled Manual in CLI/IDE UIs; manual accepted as an alias (v2.1.200+) |
acceptEdits | Auto-accepts file edits and common filesystem commands (mkdir, touch, mv, cp) within the working directory / additionalDirectories |
plan | Read-only exploration; doesn’t edit source files (classifier-approved commands may still run) |
auto | Auto-approves tool calls, with a background safety classifier checking them. The default permission mode since August 2026 |
dontAsk | Auto-denies tools unless pre-approved via /permissions or permissions.allow |
bypassPermissions | Skips permission prompts (except actions no mode auto-approves; cross-session messaging safeguards still apply). Isolated environments only — see the warning below |
Switching modes:
- Shift+Tab cycles modes in-session (Auto-Accept / Plan / normal;
Alt+Min some configs). - Start in a mode with
claude --permission-mode <mode>or thepermissions.defaultModesetting. - Enterprises can hard-disable modes in managed settings:
permissions.disableBypassPermissionsMode: "disable"(also disables--dangerously-skip-permissions) andpermissions.disableAutoMode: "disable".
WARNING —
bypassPermissions/--dangerously-skip-permissionsThese skip all permission prompts, letting Claude Code run any command — including destructive ones — without asking. Use them only inside isolated, disposable environments (containers, VMs) with no credentials or data you care about. Never set them as your default, never commit them to shared config, and never recommend disabling protections to work around an annoying prompt — add a targeted
allowrule instead (it’s faster than recovering a deleted directory).
Allow / ask / deny rules
Rules live in settings.json under permissions, or are managed in-session with /permissions. Format: Tool or Tool(specifier).
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git log *)",
"Read",
"WebFetch(domain:docs.example.com)",
"mcp__notion__*"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Read(./.env)",
"Task(Explore)"
]
}
}
How matching works:
- Evaluation order: deny → ask → allow, first match wins.
Bashalone means all Bash commands;Bash(*)is equivalent. As a deny rule both remove the tool from the model’s context entirely.- Specifiers:
Bash(npm run build)is an exact match;Bash(npm run *)is a prefix match. The trailing-space-then-*also matches the bare command. The space matters:Bash(ls *)≠Bash(ls*)— the latter also matcheslsof. A:*suffix is equivalent to a trailing*(only at the end). - Parameter-style matching for deny/ask rules:
WebFetch(domain:example.com),Skill(name),Task(subagent-name),Agent(model:opus)—*wildcards allowed in values. - Tool-name globs in deny/ask:
"*","mcp__*". In allow, globs are only permitted after a literalmcp__<server>__prefix. - Compound commands: every subcommand separated by
&&,||,;,|,|&,&, or newlines must match an allow rule. - Wrappers stripped before matching:
timeout,time,nice,nohup,stdbuf,command,builtin, zshnoglob, barexargs. Environment runners (direnv exec,mise exec,npx,docker exec, …) are not stripped — write rules that include the runner. - Choosing “Yes, and don’t ask again” for Bash/WebFetch saves the rule permanently, per repository, to
.claude/settings.local.jsonat the repo root (since v2.1.211; earlier versions saved it in the starting directory). File-modification approvals last only until the session ends.
Sandboxing
Sandboxing runs Bash commands in an OS-level sandbox (macOS / Linux / WSL2). Configured under sandbox in settings.json:
| Setting | Purpose |
|---|---|
sandbox.enabled | Turn sandboxing on (default false) |
autoAllowBashIfSandboxed | Sandboxed Bash runs without prompting (default true; substitution skipped in plan mode since v2.1.212) |
excludedCommands | Commands that must run outside the sandbox |
allowUnsandboxedCommands | Default true; false disables the dangerouslyDisableSandbox escape hatch |
network.allowedDomains | Allowed network destinations (wildcards OK) |
network.allowUnixSockets / allowAllUnixSockets | Unix-socket access |
allowLocalBinding | Allow binding local ports (macOS) |
httpProxyPort / socksProxyPort | Proxy ports exposed to sandboxed commands |
enableWeakerNestedSandbox | Nested-sandbox fallback on Linux/WSL2 (reduces security) |
Filesystem and network restrictions are expressed with Read/Edit/WebFetch permission rules, not sandbox settings.
Last verified: 2026-09-07
Official sources:
- https://docs.claude.com/en/docs/claude-code/permissions
- https://docs.claude.com/en/docs/claude-code/settings
AI coding tools evolve quickly. If you find outdated information, please open an issue or pull request.