12.2 Permission Modes
Claude Code defines 5 external permission modes and 2 internal modes:
| Mode | Behavior | Use Case |
|---|---|---|
default | Interactive confirmation when no rules match | Daily use |
acceptEdits | Auto-approve Edit/Write/NotebookEdit | High-trust projects |
plan | Pause for review before execution | Sensitive operation auditing |
bypassPermissions | Auto-approve everything | Full trust (dangerous) |
dontAsk | Auto-deny when no rules match | CI/CD environments |
auto (internal) | LLM classifier makes automatic decisions | Internal use |
bubble (internal) | Surfaces permission prompts to the parent terminal | (Implicitly forked) sub-Agent |
Below is a detailed explanation of each mode's behavior and design motivation:
default Mode
This is the most commonly used mode. The decision chain for tool calls is as follows: first check deny rules, if matched then directly deny; then check allow rules, if matched then auto-approve; when neither matches, a confirmation dialog pops up for the user to decide. In the dialog, the user can choose "allow once" or "always allow" (the latter persists the rule to the configuration file).
This mode embodies the "secure by default" principle: unknown operations always ask the user, rather than silently allowing or silently denying.
acceptEdits Mode
Auto-approves file editing tools (Edit, Write, NotebookEdit), as well as file operation commands in Bash (mkdir, touch, rm, rmdir, mv, cp, sed). Other Bash commands still require confirmation.
However, safety checks for dangerous files and directories are bypass-immune — even in acceptEdits mode, editing sensitive paths like .git/, .bashrc, .claude/settings.json still requires user confirmation. This design ensures that even when users choose a permissive mode, the security baseline is never breached (see 12.7 Dangerous File and Directory Protection for details).
plan Mode
The model generates an operation plan but pauses execution, requiring explicit user approval for each tool call. Suitable for reviewing sensitive operations or unfamiliar codebases. Plan mode can also be combined with auto mode: if the user was originally using bypassPermissions, the system remembers prePlanMode upon entering plan mode, and executes according to the original mode after plan review is approved.
bypassPermissions Mode
All tool calls are auto-approved — but this does not mean there are no restrictions at all. Deny rules and bypass-immune safety checks still take effect. The check order in the source code is critical:
1. Check deny rules first → Match means direct denial, regardless of mode
2. Check safety path checks first → .git/, .claude/ and other bypass-immune paths still require confirmation
3. Then check bypassPermissions → Only after passing the above two gates will it auto-allowThis means administrators can impose constraints on bypassPermissions mode through deny rules, for example deny Bash(rm -rf:*) will take effect even in bypass mode.
Source:
src/utils/permissions/permissions.ts:1262-1281
dontAsk Mode
The opposite of bypassPermissions: converts all decisions that would "ask the user" into "deny". Designed for CI/CD and unattended environments — no one is available to answer confirmation dialogs, so uncertain operations are better denied than left hanging waiting. Allow and deny rules still take effect; only ask is replaced with deny.
Internal Modes
auto Mode: Uses an LLM classifier (transcript classifier) to automatically make permission decisions without user interaction. The classifier analyzes the current conversation context and tool call intent to determine whether an operation is safe. This is a feature-gated internal capability (TRANSCRIPT_CLASSIFIER). When the classifier cannot determine or cumulative denials exceed a threshold, it falls back to interactive mode.
bubble Mode: Used by (implicitly forked) sub-Agents. When a sub-Agent hits a permission prompt it cannot auto-decide, it "bubbles" the prompt up to the parent terminal / parent Agent to be displayed and handled there (in the source, FORK_AGENT's permissionMode: 'bubble' is commented "surfaces permission prompts to the parent terminal").