AI agents

Claude Code

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:

ModeBehavior
defaultPrompts on first use of each tool. Labeled Manual in CLI/IDE UIs; manual accepted as an alias (v2.1.200+)
acceptEditsAuto-accepts file edits and common filesystem commands (mkdir, touch, mv, cp) within the working directory / additionalDirectories
planRead-only exploration; doesn’t edit source files (classifier-approved commands may still run)
autoAuto-approves tool calls, with a background safety classifier checking them. The default permission mode since August 2026
dontAskAuto-denies tools unless pre-approved via /permissions or permissions.allow
bypassPermissionsSkips 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+M in some configs).
  • Start in a mode with claude --permission-mode <mode> or the permissions.defaultMode setting.
  • Enterprises can hard-disable modes in managed settings: permissions.disableBypassPermissionsMode: "disable" (also disables --dangerously-skip-permissions) and permissions.disableAutoMode: "disable".

WARNING — bypassPermissions / --dangerously-skip-permissions

These 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 allow rule 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.
  • Bash alone 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 matches lsof. 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 literal mcp__<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, zsh noglob, bare xargs. 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.json at 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:

SettingPurpose
sandbox.enabledTurn sandboxing on (default false)
autoAllowBashIfSandboxedSandboxed Bash runs without prompting (default true; substitution skipped in plan mode since v2.1.212)
excludedCommandsCommands that must run outside the sandbox
allowUnsandboxedCommandsDefault true; false disables the dangerouslyDisableSandbox escape hatch
network.allowedDomainsAllowed network destinations (wildcards OK)
network.allowUnixSockets / allowAllUnixSocketsUnix-socket access
allowLocalBindingAllow binding local ports (macOS)
httpProxyPort / socksProxyPortProxy ports exposed to sandboxed commands
enableWeakerNestedSandboxNested-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:

AI coding tools evolve quickly. If you find outdated information, please open an issue or pull request.