Claude Code Permission Modes: Auto, Plan, Accept Edits & More
Every Claude Code permission mode explained: Manual, acceptEdits, plan, auto, dontAsk and bypass, plus allow/ask/deny rules and safe defaults for local and CI.
By Claudekit Team Published 11 min read
Claude Code can read, edit and run commands on your machine, so it needs a policy for when to ask first. That policy is the permission mode. Pick the wrong one and you either click “Yes” two hundred times a day or let an agent rm things unsupervised.
This guide explains all six Claude Code permission modes, how to switch between them, and how permission rules layer on top. Everything here is checked against the official permission modes and permissions documentation as of October 2026.
The six permission modes at a glance
| Mode (config value) | Status bar | What runs without asking | Best for |
|---|---|---|---|
Manual (default) | ⏸ manual mode on | Reads only | Sensitive work, unfamiliar code |
acceptEdits | ⏵⏵ accept edits on | Reads, file edits, common filesystem commands | Iterating on code you review via git diff |
plan | ⏸ plan mode on | Reads, plus classifier-approved commands when auto mode is available | Exploring before changing anything |
auto | ⏵⏵ auto mode on | Everything, with background safety checks | Long tasks, reducing prompt fatigue |
dontAsk | ⏵⏵ don't ask on | Reads and pre-approved tools; everything else is denied | Locked-down CI and scripts |
bypassPermissions | ⏵⏵ bypass permissions on | Everything | Isolated containers and VMs only |
The mode labelled Manual everywhere in the UI has the config value default. Claude Code also accepts manual as an alias, so claude --permission-mode manual works.
How to switch modes
During a session: Shift+Tab
Press Shift+Tab to cycle. From auto, the first press goes to Manual, and the cycle then runs Manual → acceptEdits → plan → back to auto. The status bar shows the active mode.
Two modes are not in the default cycle:
bypassPermissionsonly appears if you started the session with--permission-mode bypassPermissions,--dangerously-skip-permissions,--allow-dangerously-skip-permissions, or adefaultModeofbypassPermissionsin user or managed settings. The--allow-variant adds it to the cycle without switching to it.dontAsknever appears in the cycle. Start with--permission-mode dontAsk.
At startup: —permission-mode
claude --permission-mode plan
claude --permission-mode acceptEdits
claude --permission-mode auto
claude --permission-mode dontAsk
As a default: permissions.defaultMode
{
"permissions": {
"defaultMode": "plan"
}
}
Claude Code picks the starting mode from the first of these that applies: the flag, then permissions.defaultMode in a settings file, then the built-in default. One important exception: auto and bypassPermissions don’t take effect from a project’s .claude/settings.json or .claude/settings.local.json. That stops a cloned repository from silently switching off your prompts. Put those two values in ~/.claude/settings.json instead.
The built-in default
| How you run Claude Code | Starting mode |
|---|---|
A settings file sets disableAutoMode to "disable" | Manual |
claude -p or the Agent SDK | Manual |
| Interactive terminal or VS Code extension (v2.1.283+) | auto |
If the chosen mode is auto but auto mode isn’t available (unsupported model, organization turned it off), the session starts in Manual instead.
In the VS Code extension you switch with the mode indicator under the prompt box, and the extension reads claudeCode.initialPermissionMode from your VS Code user settings rather than project settings. See our Claude Code VS Code guide for the details.
Manual mode (default)
Only file reads and a built-in set of read-only Bash commands run without asking. Every edit, other shell command and network request prompts.
Use it when you’re in code you don’t know, touching production config, or simply want to watch what the agent does. It is also what claude -p uses when you don’t specify a mode, which matters for scripts (see below).
acceptEdits: let edits through, review afterwards
acceptEdits auto-approves file creation and edits in your working directory plus a short list of filesystem commands: mkdir, touch, rm, rmdir, mv, cp and sed. Those commands are still auto-approved when prefixed with safe variables like LANG=C or wrappers like timeout and nohup.
It still prompts for:
- paths outside the working directory or
additionalDirectories - writes to protected paths (see below)
- recognized critical-path removals such as
rm -rf ~ - every other Bash command outside the read-only set
This is the mode for “go ahead and change the files, I’ll read the diff.” From Manual, one Shift+Tab gets you there.
Plan mode: research first, edit later
In plan mode Claude reads files, runs exploratory commands and writes a plan, but doesn’t edit your source. Enter it with Shift+Tab, by prefixing a single prompt with /plan, or with claude --permission-mode plan.
When the plan is ready you choose:
- Yes, and use auto mode: approve and continue in auto mode (the label changes if auto mode isn’t available to you)
- Yes, manually approve edits: approve and review each edit
- No, keep planning: stay in plan mode and refine
Press Ctrl+G to open the plan in your editor and change it before Claude proceeds. When auto mode is available and the useAutoModeDuringPlan setting is on (the default), the classifier reviews shell commands during planning instead of prompting you.
To make plan mode the default for a project’s terminal sessions, set "defaultMode": "plan" in .claude/settings.json.
Auto mode: a classifier instead of prompts
Auto mode removes routine prompts. A separate classifier model reviews actions before they run and blocks anything that escalates beyond your request, targets unrecognized infrastructure, or looks driven by hostile content Claude read. Explicit ask rules still force a prompt.
Auto mode needs a supported model. On the Anthropic API that means Claude Opus 4.6 or later, Sonnet 4.6 or later, Haiku 5.5, or a Fable model; on Bedrock, Google Cloud’s Agent Platform and Microsoft Foundry the list is narrower. Older models such as Sonnet 4.5 and Opus 4.5 aren’t supported anywhere. Team and Enterprise admins can turn it off with permissions.disableAutoMode.
What the classifier blocks by default includes things like curl | bash, sending sensitive data to external endpoints, production deploys and migrations, force pushes, and git reset --hard on uncommitted work. Run claude auto-mode defaults to print the full rule list.
Two behaviours worth knowing:
- Your words count. Say “don’t push” and the classifier treats pushing as blocked even if defaults allow it. Those boundaries live in the transcript, so they can be lost if compaction drops that message.
- Fallback. If the classifier blocks an action 3 times in a row or 20 times in a session, auto mode pauses and Claude Code goes back to prompting. Blocked actions appear in
/permissionsunder Recently denied, where you can pressrto retry with manual approval.
The docs are blunt: auto mode reduces prompts but doesn’t guarantee safety. Use it where you trust the general direction of the task.
dontAsk: an exact allowlist for automation
dontAsk auto-denies anything that would otherwise prompt. Reads in your working directories, read-only commands, permissions.allow rules and calls approved by a PreToolUse hook still run. It never waits for input, which is exactly what you want in CI:
claude -p "run the test suite" --permission-mode dontAsk --allowedTools "Bash(npm test)" "Read"
Our Claude Code headless mode guide covers claude -p in depth.
bypassPermissions: containers only
bypassPermissions (or --dangerously-skip-permissions) skips prompts and safety checks, including writes to protected paths. The official guidance: only use it in isolated containers, VMs or dev containers without internet access.
Guardrails that remain:
- Deny rules still block.
- A short list of actions is never auto-approved in any mode, including tools matched by an explicit
askrule,AskUserQuestion, and recognized critical-path removals. - On Linux and macOS it refuses to start as root or under
sudo(outside a recognized sandbox). - You can’t switch into it mid-session unless you enabled it at launch.
- Admins can block it with
permissions.disableBypassPermissionsMode: "disable".
Permission rules: allow, ask, deny
Modes set the baseline. Rules fine-tune it per tool. Manage them interactively with /permissions or write them into a settings file:
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)",
"WebFetch(domain:docs.example.com)"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Read(./.env)",
"Read(./secrets/**)",
"Bash(curl *)"
]
}
}
How they’re evaluated:
- Order is deny → ask → allow, and the first match wins. A broad deny like
Bash(aws *)beats a narrower allow likeBash(aws s3 ls). - Syntax is
ToolorTool(specifier). A bareBashmatches every command. Put the*after the subcommand:Bash(git log *)allows onlygit log, whileBash(git *)allows all of git. - Paths in
Read/Editrules use gitignore patterns.//pathis absolute,~/pathis from home,/pathis relative to the settings file’s location, and./pathis relative to the current directory. A single leading slash is not an absolute path. - MCP tools match as
mcp__server__*for a whole server ormcp__server__toolfor one tool. - Subagents match as
Agent(Name), for example"deny": ["Agent(Explore)"]. - Across scopes, a deny anywhere wins. A managed deny can’t be overridden by
--allowedTools, and a user-level deny blocks a project-level allow.
Settings precedence, highest first: managed settings, command-line --settings, .claude/settings.local.json, .claude/settings.json, then ~/.claude/settings.json.
Permission rules are enforced by Claude Code, not by the model. Writing “never touch .env” in CLAUDE.md shapes intent; a Read(./.env) deny rule actually stops it. For logic that a pattern can’t express, use a PreToolUse hook (see the hooks guide).
Protected and critical paths
Some locations are never auto-approved except in bypassPermissions: directories like .git, .vscode, .idea, .husky, .devcontainer and most of .claude/, and files like .gitconfig, shell RC files (.bashrc, .zshrc), .npmrc, .mcp.json and .pre-commit-config.yaml. In Manual and acceptEdits writes there prompt; in auto mode they go to the classifier; in dontAsk they are denied.
Critical paths are stricter. Recognized rm/rmdir removals of /, top-level system directories, your home directory or the working directory are never approved by an allow rule. Patterns like rm -rf "$DIR"/* with a possibly empty variable count too. Rewrite them with a guard such as "${DIR:?}" or a literal path.
Sandboxing: limit what commands can reach
Modes decide whether Claude asks. The Bash sandbox decides what a command can touch once it runs, with OS-level filesystem and network restrictions on macOS, Linux and WSL2. Turn it on with /sandbox or sandbox.enabled: true in settings. With auto-allow on, sandboxed Bash commands can run without prompting, while deny rules and command-specific ask rules like Bash(git push *) still apply. For defense in depth, the docs recommend combining permissions and sandboxing.
Recommended setups
| Goal | Setup |
|---|---|
| Review everything | claude --permission-mode default |
| Fewer prompts locally, no classifier | Manual mode plus /sandbox in auto-allow mode |
| Explore a new codebase | claude --permission-mode plan |
| Hands-off long task | claude --permission-mode auto with a supported model |
| CI with an exact allowlist | claude -p "..." --permission-mode dontAsk --allowedTools "Bash(npm test)" "Read" |
| Fully unattended | --dangerously-skip-permissions inside a container or VM, as a non-root user |
For PR automation on GitHub runners, see the Claude Code GitHub Actions guide.
Permissions in your Claude kit
A good Claude kit ships a .claude/settings.json with sensible allow and deny rules so every teammate starts from the same guardrails. Commit the shared rules, keep personal tweaks in .claude/settings.local.json, and keep bypassPermissions out of anything you share. For the rest of the kit, see skills vs subagents vs hooks and our Claude Code FAQ.
Frequently asked questions
What is the default permission mode in Claude Code?
With Claude Code v2.1.283 or later, interactive terminal and VS Code sessions start in auto mode when nothing else sets a mode and auto mode is available. claude -p and Agent SDK runs start in Manual mode, whose config value is default.
Why does defaultMode auto in .claude/settings.json not work?
auto and bypassPermissions don't take effect from .claude/settings.json or .claude/settings.local.json, so a repository can't switch them on for you. Put defaultMode auto in ~/.claude/settings.json, pass --permission-mode auto, or set it in managed settings.
Do deny rules still apply in bypassPermissions mode?
Yes. Deny rules block in every mode, including bypassPermissions. Allow rules, on the other hand, have no effect in bypassPermissions because everything is already allowed.
Which mode should I use in CI?
Use dontAsk with an explicit allowlist, for example claude -p with --permission-mode dontAsk and --allowedTools listing exactly the commands the job needs. Anything not pre-approved is denied instead of waiting for a prompt nobody will answer.
Can my organization turn off auto mode or bypass mode?
Yes. Setting permissions.disableAutoMode or permissions.disableBypassPermissionsMode to disable in managed settings removes those modes, and users can't override managed settings.