Skip to main content
Every tool invocation in Claude Code goes through a permission check before execution. The permission system is designed to give you full control over what Claude does, while offering flexible automation modes for trusted workflows.

Permission Modes

The active permission mode is stored in ToolPermissionContext.mode and determines how permission prompts are resolved.

default

The standard interactive mode. Claude prompts you before running potentially impactful operations — bash commands, file writes, web requests. Read-only operations (file reads, searches) are generally auto-approved.

plan

Claude can analyze, plan, and reason — but cannot execute any tool that requires permission. Use this when you want to review a plan before committing to it.

bypassPermissions

All permission prompts are auto-approved without user interaction. Enabled by the --dangerously-skip-permissions CLI flag. See the warning below before using this.

auto

Automated mode for headless / non-interactive sessions. A classifier and hook system attempt to auto-resolve permissions; prompts that cannot be auto-resolved are rejected rather than displayed.
The ToolPermissionContext also carries per-session rule lists that refine behavior regardless of mode:
Rule listEffect
alwaysAllowRulesPatterns that are always approved without prompting
alwaysDenyRulesPatterns that are always rejected
alwaysAskRulesPatterns that always prompt, even in auto mode

The Permission Check Flow

Every tool invocation follows this sequence before call() runs:
1

checkPermissions() on the tool

The tool’s own checkPermissions() method runs first. It returns a PermissionResult that may be allow, ask, or deny based on tool-specific logic.
2

Rule matching

The result is checked against alwaysAllowRules, alwaysDenyRules, and alwaysAskRules in ToolPermissionContext. Matching rules short-circuit the remaining checks.
3

Hook execution (runHooks)

Any registered PermissionRequest hooks run next. A hook can allow, deny, or pass through to the next step. Hooks are defined in .claude/settings.json or via the hooks API.
4

Classifier (BASH_CLASSIFIER feature gate)

When enabled, the BashTool classifier runs for bash commands, consulting a prompt-rule model to auto-approve safe commands.
5

User prompt or auto-resolution

If no prior step resolved the decision, the system either shows an interactive confirmation dialog (interactive mode) or auto-denies (non-interactive / shouldAvoidPermissionPrompts).

What Triggers a Permission Prompt

All shell commands require a permission prompt in default mode. The prompt shows the exact command Claude intends to run. You can approve, deny, or modify the command before it executes.
Creating or modifying files always asks for confirmation. The prompt shows the file path and, for edits, a diff of the proposed change.
Fetching URLs or performing web searches triggers a prompt so you can verify the destination before data leaves your machine.
Spawning a sub-agent prompts for approval in default mode. Sub-agents run with their own permission context and may prompt you independently.
Tools that declare isDestructive() returning true are always highlighted in the UI, regardless of mode.

Approving and Denying

When a permission prompt appears in the REPL:
  • Approve — Claude executes the tool with the shown input.
  • Approve always — adds the pattern to alwaysAllowRules, persisted to ~/.claude/settings.json so the same class of action is auto-approved in future sessions.
  • Deny — the tool receives a REJECT_MESSAGE result and Claude is informed the action was not permitted. Claude will typically offer an alternative approach.
  • Deny with feedback — you can type a reason alongside the denial. The reason is included in the rejection message so Claude can adjust its approach.
When a permission is denied in a sub-agent context, the sub-agent receives a SUBAGENT_REJECT_MESSAGE and the rejection is propagated up to the parent.

Plan Mode

Plan mode lets Claude think and plan without executing anything. You can enter it manually or Claude can enter it autonomously via EnterPlanModeTool.
/plan        # enter plan mode from the REPL
While in plan mode:
  • Claude can call read-only tools (file reads, searches).
  • Any tool that would normally require a permission prompt is blocked.
  • Claude presents its proposed steps as a plan for you to review.
  • ExitPlanModeTool (or your /plan toggle) restores the previous permission mode.
The previous permission mode is stored in ToolPermissionContext.prePlanMode and restored exactly on exit.

Bypass Permissions

--dangerously-skip-permissions disables all permission prompts. Claude will execute bash commands, write files, and make web requests without asking. Only use this in fully isolated environments (e.g., containers, sandboxed VMs) where unreviewed execution is acceptable.
claude --dangerously-skip-permissions "refactor the entire auth module"
The isBypassPermissionsModeAvailable field on ToolPermissionContext controls whether this mode can be activated. Organization policy can lock this to false.

Organization Policy Limits

The policyLimits service (src/services/policyLimits/) enforces org-level restrictions. Policies are delivered via remoteManagedSettings and can:
  • Force a specific permission mode.
  • Disable bypassPermissions mode entirely (isBypassPermissionsModeAvailable: false).
  • Populate alwaysDenyRules with patterns your organization has blocked.
  • Strip dangerous rules that would otherwise be inherited from user settings (strippedDangerousRules).
Policy settings take precedence over user settings and cannot be overridden locally.

Tips for Safe Use

Use alwaysAllowRules for commands you run constantly in a project (e.g., npm test, git status). Add them once via the “Approve always” dialog and Claude will never ask again.
Run Claude in plan mode first for large refactors. Review the plan, ask clarifying questions, then exit plan mode to let Claude execute.
In CI pipelines, use --dangerously-skip-permissions only inside ephemeral containers. Never run it on a developer machine with access to production credentials.
When shouldAvoidPermissionPrompts is true (set automatically for background agents that have no UI), any tool requiring a prompt is auto-denied rather than hanging indefinitely.

Build docs developers (and LLMs) love