CCLearn

The Six Modes and What Each One Actually Permits

verified against Claude Code 2.1.261 · 2026-09-0912 min

By the end you can

  • Name what each of the six permission modes runs without a prompt
  • Pick a mode deliberately for a given piece of work
  • Explain why a mode is a baseline that permission rules sit on top of
  • Recognise the actions no mode auto-approves
  • Say where a session's mode came from and which files can set it

Nine levels in, you have never once chosen a permission mode. You inherited one — from your plan, from a settings file somebody checked in, from a Shift+Tab you pressed to stop the prompts. Lesson 1.3 told you to press it back to Manual and said Level 10 is where you pick on purpose. This is that lesson. A mode is not a preference; it is the answer to one question, settled before the work starts: which actions run in this session without you seeing them.

The six modes, side by side

This is the documented table, with the doc's own words in the middle column (Choose a permission mode). That column summarises — the etc. in row two is hiding something — and the rest of this lesson is mostly what each row leaves out.

ModeWhat runs without askingBest for
defaultReads onlyReviewing every action yourself, sensitive work
acceptEditsReads, file edits, and common filesystem commands (mkdir, touch, mv, cp, etc.)Iterating on code you're reviewing
planReads, plus classifier-approved commands when auto mode is availableExploring a codebase before changing it
autoEverything, with background safety checksLong tasks, reducing prompt fatigue
dontAskOnly pre-approved toolsLocked-down CI and scripts
bypassPermissionsEverythingIsolated containers and VMs only

Two rows say "Everything" and they are not the same thing. That difference is most of this level. And one sentence frames all six:

Modes set the baseline. Layer [permission rules] on top to pre-approve or block specific tools. Deny rules block in every mode, including bypassPermissions. […] Allow rules have no effect in bypassPermissions. — Choose a permission mode

A mode is a floor, not a fence. Lesson 10.2 is about what you build on top of it, and about that asymmetry: deny survives everything, allow does not.

Manual is the mode called default

The name you type is not the name you see. The mode that reviews every action is default in config — which is what hooks and SDK integrations use — and is labelled Manual in the CLI, in claude --help, in the VS Code and JetBrains extensions and in the desktop app, with manual accepted as an alias wherever you type the value. Before v2.1.200 there was no Manual label and no alias: you saw and typed default everywhere except the desktop app, whose label the docs note does not depend on your CLI version. Lesson 1.3 builds that gate in full. What the mode permits is the shortest entry in the docs: prompts for permission on first use of each tool (Configure permissions).

acceptEdits, and the trap in its name

From Choose a permission mode: the auto-approved commands are mkdir, touch, rm, rmdir, mv, cp and sed; they stay auto-approved when prefixed with safe environment variables such as LANG=C, or with process wrappers such as timeout, nice or nohup, so a wrapper does not restore the prompt; and with the PowerShell tool enabled, Set-Content, Add-Content, Clear-Content and Remove-Item join them.

The boundary is what makes the mode usable:

Like file edits, auto-approval applies only to paths inside your working directory or additionalDirectories. Paths outside that scope, writes to [protected paths], rm and rmdir removals targeting a [critical path], and all other Bash commands except the [built-in read-only set] still prompt. — Choose a permission mode

So the honest description is: this directory tree is yours, everything else still asks. Use it when you intend to review the result as a diff afterwards — Lesson 4.5's habit — rather than as a replacement for reviewing.

plan is not one behaviour

Lesson 4.2 covered plan mode's mechanics. What belongs here is how it changes with the session around it. When auto mode is available and useAutoModeDuringPlan is on — the default — the classifier reviews shell commands during planning instead of prompting you; approved commands run, rejected ones are blocked. Otherwise, commands outside the built-in read-only set prompt.

At the other end, in a session where bypass permissions are available, Claude Code does not enforce plan mode's blocks: Claude is still instructed to plan without editing, but a file edit or shell command it attempts during planning runs without prompting. Two things still stop it, and the docs name both: an explicit ask rule, and an rm or rmdir aimed at a critical path. So plan mode is a harness gate everywhere except there, where it is an instruction with two circuit breakers behind it.

auto and dontAsk: two different kinds of hands-off

These look adjacent in the table and are opposites. auto auto-approves tool calls with background safety checks; a separate classifier model reviews actions before they run. Lesson 10.3 is that classifier in full. For now, the documented warning is the point:

Auto mode reduces permission prompts but does not guarantee safety. Use it for tasks where you trust the general direction, not as a replacement for review on sensitive operations. — Choose a permission mode

dontAsk inverts the default: it "auto-denies tools unless pre-approved via /permissions or permissions.allow rules" (Configure permissions). Claude runs only what your allow rules match, the read-only Bash commands, and calls a PreToolUse hook approves. The session never waits for input — which is what a CI pipeline needs, and which has two consequences: a matching ask rule is denied rather than prompted, and AskUserQuestion is denied even if your allow rules match it. dontAsk never appears in the Shift+Tab cycle. You set it with --permission-mode dontAsk, or as permissions.defaultMode in a settings file — never by pressing anything.

Hold the pairing: auto is everything runs, something else reviews it; dontAsk is nothing runs unless you wrote it down first.

bypassPermissions: what it skips, and what it does not

bypassPermissions mode disables permission prompts and safety checks so tool calls execute immediately, including writes to [protected paths]. — Choose a permission mode

Three documented facts that folklore gets wrong:

  • It is not reachable mid-session. "You can't enter bypassPermissions from a session you started without it enabled." Enable it at launch with --permission-mode bypassPermissions, the equivalent --dangerously-skip-permissions, or permissions.defaultMode in user, --settings, or managed settings.
  • Deny rules still block, in this mode as in every other — with one narrow exception Lesson 10.2 takes apart: neither a deny nor an ask rule applies to EndConversation while Claude still has some other tool it can call. Allow rules are the ones that stop mattering here.
  • It refuses to run as root. On Linux and macOS Claude Code refuses to start in this mode under root or sudo, printing --dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons. The check is skipped inside a recognised sandbox.

And the sentence that decides whether you should be in it at all:

bypassPermissions offers no protection against prompt injection or unintended actions. — Choose a permission mode

The documented requirement is a container, VM, or sandbox runtime. Lesson 10.4 is that requirement; Lesson 10.6 is the injection this mode does nothing against.

Actions no mode auto-approves

A fixed list outranks every mode, and knowing it is what stops you believing any flag makes prompts impossible. "Claude Code doesn't auto-approve the following in any mode, including bypassPermissions" (Choose a permission mode):

Tools matched by an explicit ask rule; connector tools your organisation set to ask, in sessions where that setting reaches Claude Code; tools requiring user interaction, meaning AskUserQuestion and MCP tools marked requiresUserInteraction; rm and rmdir removals targeting a critical path, which no allow rule and no PreToolUse hook "allow" approves; and the cross-session messaging safeguards. A sixth entry joined the list in v2.1.257: reads outside the working directories while permissions.blockReadsOutsideWorkingDirectories is on — a recognized file-reading Bash command, or an unsandboxed retry that needs approval to run outside the sandbox, prompts even in auto mode and bypassPermissions mode. Lesson 10.5 covers that setting, including the tools it stops outright.

"Not auto-approved" means asks you, which assumes there is somebody to ask. The docs are explicit about the case where there is not: in a -p run started with --dangerously-skip-permissions, the few calls that would still prompt are denied instead. Unattended, the list above stops being a set of questions and becomes a set of refusals.

Two path categories carry that list, and they end differently:

Protected pathsCritical paths
CoverRepository state and Claude's own config: .git, .claude, .vscode, shell rc files, .npmrc, .mcp.json, morerm/rmdir targets: filesystem root, top-level directories, your home directory, your working directory and its parents
default, acceptEditsPromptedPrompted
planAllowed where bypass permissions are available; otherwise routed to the classifier when auto mode is available during planning, and prompted when it is notPrompted; routed to the classifier with auto mode available during planning and no bypass permissions
autoRouted to the classifierRouted to the classifier
dontAskDeniedDenied
bypassPermissionsAllowedStill asks you

Memorise the last row. bypassPermissions will happily write to .git and .claude — that is what "skips safety checks" means — but it still stops for rm -rf ~. A circuit breaker against model error is not a guard on your repository, and only one survives the flag. An allow rule cannot buy you out of a protected-path write either: that safety check runs before Claude Code evaluates allow rules from settings, so an Edit(.claude/**) entry changes nothing in the table above.

Where a mode comes from

Asking Claude in chat does not change the mode — Lesson 1.3 quoted that. For a new terminal session, Claude Code takes the first of these that applies:

  1. The --permission-mode flag, or --dangerously-skip-permissions
  2. permissions.defaultMode in a settings file
  3. The built-in default

Step 3 is not one value, and the docs settle it with a table where the first matching row wins. claude -p and the Agent SDK start in Manual on every plan; a Pro, Max or Team terminal session starts in auto — but only when no earlier row claims it first. Any settings file setting disableAutoMode to "disable", feature-flag fetching being off, and your first session after an install or an upgrade to a version that adds this default (unless a fresh install fetches the flags in time) each land on Manual whatever the plan. Before v2.1.228 — v2.1.233 on native Windows — the built-in default was Manual everywhere. Lesson 1.3 carried that version note, and this is where it lands: once the flags do arrive, the session you did not configure is the one running with a classifier in front of it, and Manual is the mode you now have to ask for.

Step 2 is where teams get surprised, because not every value works from every file:

[permissions.defaultMode] values auto and bypassPermissions don't take effect from project or local settings; set them in user or managed settings instead, or pass --permission-mode for one session. — Settings

Read that as a security property, not a limitation: a repository you clone cannot be the thing that puts your session in auto or bypass mode. The two values are ignored differently, and the difference matters. A checked-in .claude/settings.json asking for bypassPermissions is ignored and the session starts in Manual. An auto in the same file drops you to the built-in default — and not to a defaultMode from your own ~/.claude/settings.json, which Claude Code skips in that case. So on an install and plan whose built-in default is auto, the session still starts in auto. The repository did not do that; your plan did.

When several files set defaultMode, ordinary settings precedence decides — managed, then command-line arguments, then project local, then shared project, then user settings — so a project or managed value outranks your ~/.claude/settings.json (Settings). Lesson 12.5 is that fact from the administrator's side, where permissions.disableBypassPermissionsMode sits among the managed locks. Its twin permissions.disableAutoMode, set to "disable", drops auto from the Shift+Tab cycle and starts a session launched with --permission-mode auto in Manual instead.

Choosing on purpose

The docs pair each goal with a starting point and the isolation it needs. The third column is Lesson 10.4, and it is not optional in the last row.

You want toStart withIsolation needed
Review every action yourselfclaude --permission-mode defaultNone
Iterate with fewer prompts, no classifierManual plus the Bash sandbox in auto-allow modeThe built-in Bash sandbox (macOS, Linux, WSL2)
Explore before changing anythingclaude --permission-mode planNone
Work hands-off in auto modeclaude --permission-mode autoNone; a sandbox or container adds defence in depth
Run in CI with an exact allowlistclaude -p "…" --permission-mode dontAsk --allowedTools "Bash(npm test)" "Read"None beyond the CI runner
Run fully unattended inside a containerclaude -p "…" --dangerously-skip-permissionsRequired: a container, VM, or sandbox runtime — and on Linux and macOS, run as a non-root user

Notice what the second row buys. If your actual problem is prompt fatigue, the documented remedies are narrower than the flag: allow rules for the commands you keep approving, the Bash sandbox in auto-allow mode, or auto mode. Reaching for --dangerously-skip-permissions because you are tired of pressing y does not make the prompts smarter — it removes the review, including for the one action you would have caught. So: pick the weakest mode that lets the work proceed, and change the isolation rather than the mode when it does not.

Checkpoint

  1. A colleague says "I run everything in acceptEdits, it only touches files." Name two things that mode auto-approves which are not file edits, and the one condition that limits all of them.

    Show answer

    rm and rmdir — deletion, with no prompt. They sit in the same documented auto-approved set as mkdir, touch, mv, cp and sed, and a wrapper does not restore the prompt: a safe environment prefix such as LANG=C, or timeout, nice or nohup, still runs silently. With the PowerShell tool enabled, Set-Content, Add-Content, Clear-Content and Remove-Item join the list.

    The condition on all of it is location. Auto-approval applies only to paths inside your working directory or additionalDirectories; paths outside that scope, writes to protected paths, rm and rmdir removals targeting a critical path, and every other Bash command outside the built-in read-only set still prompt. So the honest description of the mode is this directory tree is yours, everything else still asks — which is not the claim your colleague is making.

  2. You start an interactive session with --dangerously-skip-permissions in a container. Claude proposes rm -rf ~ and, separately, an edit to .git/config. Which one stops and asks you, and why that one? Then say what changes if the same session is a claude -p run.

    Show answer

    rm -rf ~ stops. Your home directory is a critical path, and rm and rmdir removals targeting one are on the fixed list of actions Claude Code does not auto-approve in any mode, bypassPermissions included — no allow rule and no PreToolUse hook approves them either. The .git/config edit runs without a word: .git is a protected path, and protected paths are the row of the table that reads Allowed under this mode. That is exactly what "skips safety checks" means, and it is why the flag is a circuit breaker against model error rather than a guard on your repository.

    In a -p run started with --dangerously-skip-permissions there is nobody to ask, so the few calls that would still prompt are denied instead. The rm -rf ~ is refused rather than put in front of you; the .git/config edit still goes through unchanged.

  3. You clone an unfamiliar repository whose .claude/settings.json sets "defaultMode": "auto". The value does not take effect — so name what decides the mode instead, and why that can still be auto. Then say what you would check before assuming the same repository could not set "bypassPermissions".

    Show answer

    The built-in default decides. An auto in project settings drops the session to step 3 of the resolution order — and Claude Code skips a defaultMode in your own ~/.claude/settings.json in that case, so your user file does not fill the gap. On a Pro, Max or Team terminal session where no earlier row claims it, the built-in default is auto, so the session still starts in auto. The repository did not do that; your plan did. Note the two ignored values are not ignored the same way: a checked-in bypassPermissions is dropped and the session starts in Manual.

    Before assuming the repo could not ask for bypass, check claude --version. The guarantee is younger than the flag — "Before v2.1.257, bypassPermissions took effect from any file" — so on a colleague's laptop, a pinned CI image or any install below that line, a checked-in project settings file can start the session in bypass mode. Read the mode indicator on your first turn in any repository you did not write.

  4. You want a long migration to run without babysitting, on a production-adjacent repo. Which mode, and what would have to be true about your environment first?

    Show answer

    Start with auto mode — claude --permission-mode auto — because it is the weakest mode that lets hands-off work proceed, and the docs attach no isolation requirement to it: a sandbox or container is defence in depth there, not a precondition. Auto mode reduces prompts without guaranteeing safety, so on a production-adjacent repo pair it with the deny and ask rules of Lesson 10.2 for the operations that deserve a human.

    Reach for claude -p "…" --dangerously-skip-permissions only if the run must be genuinely unattended, and then the environment column is not a preference: a container, VM or sandbox runtime is required, and on Linux and macOS you run as a non-root user — Claude Code refuses to start in that mode under root or sudo outside a recognised sandbox anyway. The rule to apply is the one the lesson closes on: pick the weakest mode that lets the work proceed, and change the isolation rather than the mode when it does not.

Sources