# Claude Code Permissions and modes

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

URL: https://docs.passion8.cc/en/docs/claude-code/permissions
Language: en
Publisher: Passion8

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 category | Examples | Confirmation by default |
| --- | --- | --- |
| Read-only tools | Read, Grep, Glob, read-only shell | Usually not required |
| Bash commands | npm test, git push, scripts | Required |
| File changes | Edit, Write, NotebookEdit | Required |

“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.

```json title=".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

| Mode | Behavior | Use |
| --- | --- | --- |
| default | Ask when needed | Everyday default |
| acceptEdits | Automatically accept file edits and common filesystem operations | Personal projects with Git recovery |
| plan | Read-oriented planning without source edits | Research before major changes |
| auto | Automatic mode with background safety classification | Research preview; use deliberately |
| dontAsk | Deny tools without pre-approval | Restricted CI or scripts |
| bypassPermissions | Skip most permission prompts | Isolated containers or VMs |

Start from the CLI:

```bash
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](https://docs.passion8.cc/en/docs/claude-code/sandboxing). See [Enterprise administration](https://docs.passion8.cc/en/docs/claude-code/enterprise-admin) for centralized policy.

## Rule syntax

```text
Tool
Tool(specifier)
```

| Rule | Matches |
| --- | --- |
| `Bash` | All 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.

```json title=".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

| Pattern | Anchor | Example |
| --- | --- | --- |
| `//path` | Absolute filesystem path | `Read(//home/alex/secrets/**)` |
| `~/path` | User home | `Read(~/.zshrc)` |
| `/path` | Settings source directory | `Edit(/src/**)` |
| `path` or `./path` | Current working directory | `Read(./.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

```json title=".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

```json title=".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

```json title="~/.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

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

## Official references

- [Configure permissions](https://code.claude.com/en/docs/en/permissions.md)
- [Choose a permission mode](https://code.claude.com/en/docs/en/permission-modes.md)
- [Hooks reference](https://code.claude.com/en/docs/en/hooks.md)
