Skip to main content

Permission Modes

Claude Code performs actions that affect your system — editing files, running commands, and more. The permission system controls how much freedom you give it.

Tool Approval Levels

Claude Code has different approval levels by tool type:

Tool TypeExamplesApproval"Don't ask again" Scope
Read-onlyFile read, Grep, GlobNot required-
Bash commandsShell executionRequiredPersisted per project directory
File modificationsEdit, WriteRequiredUntil session ends

6 Permission Modes

ModeDescriptionWhen to Use
defaultAsks for approval on first tool useNormal development
acceptEditsAuto-approves file editsTrusted local development
planAnalysis only, no edits/executionCode exploration, architecture review
autoClassifier auto-approves/blocksLong sessions, reducing prompt fatigue
dontAskOnly pre-approved tools, auto-denies restRestricted automation
bypassPermissionsSkips all approval checksIsolated containers/VMs only

Switching Modes in Real-Time

During a session, press Shift+Tab or Alt+M to cycle through modes:

Default → Shift+Tab → Auto Accept → Shift+Tab → Plan → Shift+Tab → Auto → ...
Auto Mode Visibility

For Auto mode to appear in the Shift+Tab cycle, you need the --enable-auto-mode flag at startup. Auto mode requires a Team plan or higher and Sonnet 4.6 or Opus 4.6 models.

Understanding Approval Options

In default mode, when Claude asks for approval:

Claude: I'll create auth/login.ts. Allow?
[y] Yes [n] No [a] Always allow this type [d] Don't allow
ChoiceMeaning
y (Yes)Allow this one time
n (No)Reject, Claude tries another approach
a (Always)Auto-allow this type for the session
d (Don't allow)Auto-reject this type for the session
bypassPermissions Warning

bypassPermissions disables all permission checks. Only use in isolated environments (Docker, VMs). Organization admins can block this mode via managed settings with disableBypassPermissionsMode: "disable".

Auto Mode — Classifier-Based Auto-Approval

Instead of manually approving every action, Auto mode uses a background classifier (Sonnet 4.6) to evaluate each tool call automatically. Unlike bypassPermissions, which allows everything, Auto mode judges whether each action fits the task context and only executes safe operations.

Requirements

RequirementDetails
PlanTeam (launched), Enterprise/API (rolling out). Pro/Max not currently supported
ModelSonnet 4.6 or Opus 4.6 only
ActivationCLI: --enable-auto-mode, Desktop/VS Code: enable in settings
# Start in Auto mode from CLI
claude --enable-auto-mode --permission-mode auto

# Or start with the flag, then switch via Shift+Tab
claude --enable-auto-mode

Evaluation Order

Each tool call is evaluated in this order:

1. Matches an allow/deny rule → immediately allow/block
2. Read-only + file edits within working directory → auto-approve
3. Everything else → classifier evaluation
4. Classifier blocks → Claude tries an alternative approach

Default Block List

Actions the classifier blocks by default:

  • Running downloaded code (curl | bash, scripts from cloned repos)
  • Sending sensitive data to external endpoints
  • Production deployments/migrations
  • Bulk deletion from cloud storage
  • IAM/repo permission changes
  • Direct push to main branch, force push
  • Irreversible deletion of files that existed before the session started

Actions the classifier allows by default:

  • File operations within the working directory
  • Installing dependencies declared in lock files
  • Reading .env and sending auth to those APIs
  • Read-only HTTP requests
  • Pushing to the current branch or branches created by Claude
Check Default Rules

Run claude auto-mode defaults to see the full list of rules used by the classifier.

Fallback Behavior

If the classifier blocks 3 consecutive times or 20 total times in a session, Auto mode pauses and switches to manual approval. After manual approval, the counter resets and Auto mode resumes.

Auto Mode vs bypassPermissions

AutobypassPermissions
Safety checksClassifier evaluates each actionNone
EnvironmentNormal developmentIsolated containers/VMs only
Token costAdditional cost from classifier callsStandard
PromptsOnly on fallbackNone
Auto Mode Caveat

Auto mode is a research preview. It provides less protection than manual review. Use default mode for sensitive operations. Admins can disable this mode with disableAutoMode: "disable".

Managing Permission Rules

Use the /permissions command to view and manage current rules:

/permissions

Allow:
- Read(*)
- Edit(/src/**)
- Bash(npm test *)

Deny:
- Bash(rm *)
- Bash(git push *)

Evaluation order: deny → ask → allow. Deny always takes priority.

Permission Rule Syntax

Basic Format

Rules use the format ToolName or ToolName(specifier).

{
"permissions": {
"allow": [
"Read", // Allow reading all files
"Bash(npm run *)", // Any command starting with npm run
"Edit(/src/**/*.ts)" // Only edit TypeScript files under src/
],
"deny": [
"Bash(rm *)", // Block rm commands
"Bash(git push *)" // Block git push
]
}
}

Bash Rules: Wildcard Matching

* works as a glob pattern and can be used anywhere in the command:

RuleMatches
Bash(npm run build)Exactly npm run build only
Bash(npm run *)npm run test, npm run lint, etc.
Bash(* --version)node --version, npm --version, etc.
Bash(git * main)git checkout main, git merge main, etc.
Space+* vs *

Bash(ls *) matches ls -la but not lsof. The space enforces a word boundary. Bash(ls*) matches both.

Shell Operator Awareness

Claude Code recognizes shell operators like &&. Bash(safe-cmd *) will NOT allow safe-cmd && dangerous-cmd.

Read/Edit Rules: Gitignore-Style Patterns

File path rules follow the gitignore spec:

PatternMeaningExample
//pathFilesystem absolute pathRead(//Users/alice/secrets/**)
~/pathHome directory relativeRead(~/Documents/*.pdf)
/pathProject root relativeEdit(/src/**/*.ts)
pathCurrent directory relativeRead(*.env)
{
"permissions": {
"allow": [
"Edit(/docs/**)", // Only allow editing under docs/
"Read(~/.zshrc)" // Allow reading home .zshrc
],
"deny": [
"Read(.env)", // Block reading .env files
"Edit(//etc/*)" // Block editing /etc/
]
}
}
* vs **

* matches files within a single directory, ** recursively matches through subdirectories.

MCP Tool Rules

{
"permissions": {
"allow": [
"mcp__puppeteer", // All tools from puppeteer server
"mcp__github__github_list_repos" // Only specific tool from github server
]
}
}

Sub-Agent (Task) Rules

{
"permissions": {
"deny": [
"Agent(Explore)" // Disable Explore sub-agent
]
}
}

settings.json Hierarchy

Permission rules can be defined in multiple locations, with this priority:

Managed (Org) → CLI args → Local project → Shared project → User global
LocationFilePriority
Organization managedMDM/server policiesHighest
CLI arguments--allowedTools, --disallowedToolsHigh
Local project.claude/settings.local.jsonMedium
Shared project.claude/settings.jsonMedium
Global user~/.claude/settings.jsonLowest

Project settings override user settings. Even if user settings allow a tool, project settings can deny it.

Additional Directory Access

By default, Claude only accesses files in the working directory. To open additional directories:

# Add at startup
claude --add-dir /path/to/other-project

# Add during session
/add-dir /path/to/other-project

Permissions vs Sandboxing

Permissions and sandboxing are complementary:

PermissionsSandboxing
Applies toAll toolsBash commands only
How it worksControls Claude's tool usageOS-level file/network isolation
Defends againstLimiting Claude's decisionsPrompt injection bypass prevention

Using both together implements defense-in-depth.

Get weekly Claude Code tips by email

Get weekly Claude Code tips by email — real usage insights, delivered free. Subscribe →

Mode Selection Guide

What are you doing?

├─ Exploring/understanding a new codebase
│ → Plan mode (read-only)

├─ Fast local development, solo
│ → acceptEdits or default (git commit first)

├─ Long refactoring session, reducing approval fatigue
│ → Auto mode (classifier decides for you)

├─ Team project, critical code
│ → Default mode + project settings.json rules

├─ CI/CD, automation scripts
│ → Headless mode + allowedTools specified

└─ Isolated Docker/VM test environment
→ bypassPermissions (caution!)

Practical Configuration Examples

Safe Development Environment

{
"permissions": {
"allow": [
"Read",
"Edit(/src/**)",
"Bash(npm test *)",
"Bash(npm run lint *)",
"Bash(git diff *)",
"Bash(git status *)",
"Bash(git log *)"
],
"deny": [
"Bash(rm *)",
"Bash(git push *)",
"Bash(curl *)",
"Bash(wget *)",
"Edit(*.env)"
]
}
}

CI/CD Environment (Headless)

claude -p "Review this code" \
--allowedTools "Read,Grep,Glob" \
--disallowedTools "Bash,Edit,Write"