Six permission modes, one decision: how much do you trust the next tool call to be reversible? default is safe-by-default with a prompt on each new tool; bypassPermissions is the no-prompts opposite. The four in between trade off where the friction lands.
Side-by-side comparison
| Mode | Edit/Write/MultiEdit | Read-only Bash | Side-effecting Bash | Notes |
|---|---|---|---|---|
default | Prompts on first use | Auto-runs | Prompts | Standard new-session behavior. |
acceptEdits | Auto-runs (incl. mkdir, touch, mv, cp) | Auto-runs | Prompts | Skips the edit-prompt churn; Bash still gated. |
plan | Held until plan approval | Auto-runs | Prompts (normal rules) | Reads and explores; no source edits land before you approve. |
auto | Auto-approved if classifier passes | Auto-runs | Classifier-gated | Research preview. allow rules act as exceptions; soft_deny blocks first then can be overridden. |
dontAsk | Auto-denied unless pre-approved | Auto-runs | Auto-denied unless pre-approved | Anything not on the allow list fails fast, no prompt. |
bypassPermissions | Auto-runs | Auto-runs | Auto-runs | Even this mode blocks rm -rf / and rm -rf ~ as a circuit breaker. |
Eval order for explicit rules
Explicit permission rules evaluate deny → ask → allow in every mode except bypassPermissions, which skips the permission layer entirely (only the circuit-breaker on root or home wipes still fires). In auto mode, the classifier runs after the explicit rule check: a matching deny blocks before the classifier sees the call, an allow lets it through without classification, and unmatched calls go to the classifier. The first matching rule wins, so a managed deny always beats any later allow. Modes change the default behavior for tools with no matching rule. Rules and modes compose:
defaultmode +Bash(npm test*)allow →npm testruns without asking; anything else still prompts.acceptEditsmode +Read(.env*)deny → secret reads still refused; edits to other files still auto-run.dontAskmode +Bash(npm test*)allow →npm testruns; everything else fails fast with no prompt.
The mode is the floor; rules are the deltas. Reach for bypassPermissions only when you have decided that no rule should be allowed to interrupt you.
Pick a mode by workflow
Pair-programming, you watch every change. Use default. The friction is the feature.
Long sessions, lots of small edits, you trust Claude with files but not with Bash. Use acceptEdits. Drops the per-edit prompts; Bash still gated.
Unfamiliar codebase, ambiguous scope. Use plan. Force Claude to propose before any source touches disk.
Trusted environment, repeated tool calls you would otherwise approve every time. Use auto. The classifier does the safety work; supplement with explicit allow for routine commands.
CI or tightly-scoped automation. Use dontAsk plus a curated allow list. Anything not on the list fails fast instead of pausing for human input that will not come.
Disposable VM, isolated container, throwaway worktree. Use bypassPermissions. Nothing valuable to break; the circuit breaker still blocks accidental nukes of / or $HOME.
Footguns
acceptEdits includes more than just edits. The mode auto-approves mkdir, touch, mv, cp and similar common filesystem Bash commands. It is “auto-approve filesystem-shaped operations”, not strictly “auto-approve Edit/Write tool calls”. Bash(mv production-dump.sql /tmp) runs without asking under acceptEdits. Read the canonical doc’s mode description before choosing it for production-adjacent work.
Read-only Bash auto-runs in every mode. cat, grep, find, read-only git: none of these prompt regardless of which mode you picked. That includes cat .env. The mode does not protect you from secret-shaped reads; only deny rules do.
auto mode is opinionated about what is risky. The research-preview classifier decides, and the call can be a surprise. Common shapes: a git push to a fork that was added as a remote on this machine is treated as routine; an aws s3 cp to a non-listed bucket is not. Audit claude auto-mode config after enabling to verify what the classifier sees as in-scope.
dontAsk silently blocks anything you forgot to allowlist. New tool, no rule, no prompt, no progress. The model says “I tried to run X but it was denied” and stops. Treat the first week of dontAsk as a curation period; expect to add allow rules as Claude tries new commands.
bypassPermissions is exactly as dangerous as it sounds. The circuit breaker covers rm -rf / and similar root-or-home wipes; it does not cover git reset --hard, aws s3 rm --recursive, kubectl delete namespace prod, or npm publish. Crucially, your own deny rules do not apply in this mode either: bypassPermissions skips the permission layer entirely. The mode is for genuinely disposable environments. Anything else, pick a different mode.
Sandbox plus permissions changes the prompt rules. When /sandbox is active and autoAllowBashIfSandboxed: true (the default), sandboxed Bash runs without prompting even if your permissions otherwise say ask: Bash(*). The sandbox boundary substitutes for the per-command prompt. Explicit deny rules still apply.
Admin can disable auto and bypassPermissions from above. Set permissions.disableBypassPermissionsMode: true or permissions.disableAutoMode: true in managed settings; developers cannot relax that. Useful for orgs where the mode list is policy, not preference.
When NOT to use this
- Single task, single session. The mode you launched in is fine. Switching mid-task confuses the next decision.
- You are the only user, on a personal repo with no production credentials.
defaultworks. The other five modes earn their keep when default’s prompts start blocking a workflow you have already calibrated. - The work is supposed to fail loudly. A CI step that expects
Bash(rm -rf node_modules)to be denied is using the right mode (dontAskwith no allow). Do not “fix” the failure by switching tobypassPermissions. - You cannot articulate why the current mode is wrong. “It is asking too much” is a workflow complaint, not a mode complaint; the fix is usually
allowrules, not a mode change.