Claude Code

Permissions and modes

Permission rules, allow/ask/deny precedence, modes, Bash/Read/Edit/WebFetch/MCP patterns, and enforcement boundaries.

Claude Code's permission system controls commands, file edits, path access, and tools. CLAUDE.md provides guidance; permission rules provide enforcement.

#Default safety model

Tool categoryExamplesConfirmation by default
Read-only toolsRead, Grep, Glob, read-only shellUsually not required
Bash commandsnpm test, git push, scriptsRequired
File changesEdit, Write, NotebookEditRequired

“Yes, don't ask again” saves a rule in the project context or settings. Bash approvals are usually associated with the project and command; automatic file-edit approval often lasts only for the current session.

#Rule order

Three rule types:

  • allow: run without asking again.
  • ask: require confirmation.
  • deny: prohibit the operation.

Evaluation order is fixed:

  1. deny
  2. ask
  3. allow

A more specific allow rule cannot override a deny. To allow only selected commands by default, use dontAsk with allow entries rather than a blanket deny plus exceptions.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)",
      "Read(./en/docs/**)"
    ],
    "ask": [
      "Bash(git push *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

#Permission modes

ModeBehaviorUse
defaultAsk when neededEveryday default
acceptEditsAutomatically accept file edits and common filesystem operationsPersonal projects with Git recovery
planRead-oriented planning without source editsResearch before major changes
autoAutomatic mode with background safety classificationResearch preview; use deliberately
dontAskDeny tools without pre-approvalRestricted CI or scripts
bypassPermissionsSkip most permission promptsIsolated containers or VMs

Start from the CLI:

claude --permission-mode plan
claude --permission-mode acceptEdits

Use Shift+Tab or /permissions to adjust the mode in-session.

Bypass mode skips many prompts for sensitive directories such as .git, .claude, .vscode, and .husky. Reserve it for isolated or recoverable environments.

Modes determine whether a tool can run. Filesystem, network, and credential isolation after execution requires sandboxing. See Enterprise administration for centralized policy.

#Rule syntax

Tool
Tool(specifier)
RuleMatches
BashAll Bash calls
Bash(npm run build)Exact command
Bash(npm run *)Matching command prefix
Read(./.env)Current-directory .env access
Edit(/src/**)src under the settings source directory
WebFetch(domain:example.com)Specified domain
mcp__github__get_*GitHub MCP get tools

#Bash rules

Bash supports wildcard matching. Each subcommand in a compound command must independently pass permission checks.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(* --version)"
    ],
    "deny": [
      "Bash(git push *)",
      "Bash(rm -rf *)"
    ]
  }
}

Bash(ls *) differs from Bash(ls*): the former requires a word boundary after ls, while the latter can also match lsof.

Some read-only commands, including ls, cat, pwd, grep, find, wc, and read-only Git operations, may be treated as safe. Add ask or deny if you want those checked too.

#Read/Edit path patterns

PatternAnchorExample
//pathAbsolute filesystem pathRead(//home/alex/secrets/**)
~/pathUser homeRead(~/.zshrc)
/pathSettings source directoryEdit(/src/**)
path or ./pathCurrent working directoryRead(./.env)

In user settings, Read(/secrets/) refers to ~/.claude/secrets/, not every project's secrets directory. Use // or ~/ for the appropriate cross-project scope.

#WebFetch and networking

.claude/settings.json
{
  "permissions": {
    "allow": [
      "WebFetch(domain:docs.example.com)",
      "WebFetch(domain:*.example.com)"
    ],
    "deny": [
      "Bash(curl *)",
      "Bash(wget *)"
    ]
  }
}

Restricting WebFetch does not restrict all network access. An allowed Bash process can still use curl or scripts. Combine command rules, hooks, or an OS sandbox for strict boundaries.

#MCP rules

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__github__get_*"
    ],
    "ask": [
      "mcp__database__write_*"
    ],
    "deny": [
      "mcp__*"
    ]
  }
}

A blanket mcp__* deny removes all MCP tools, including ones matched by allow entries. Claude will not see those tools.

#Suggested configurations

#Personal development

~/.claude/settings.json
{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run typecheck)",
      "Bash(git status)",
      "Bash(git diff *)"
    ],
    "deny": [
      "Read(//**/.env)",
      "Read(//**/.env.*)"
    ]
  }
}

#Team repository

.claude/settings.json
{
  "permissions": {
    "ask": [
      "Bash(git push *)",
      "Bash(npm publish *)"
    ],
    "deny": [
      "Read(./production/**)",
      "Edit(./production/**)"
    ]
  }
}

#Official references

Support

Need help?

For setup, billing, or model issues, email us. Check the status page for uptime.

WeChat / QQ support is available at the bottom right.