---
title: "管理权限"
description: "Claude Code 权限不是一个总开关，而是控制 Bash、Read、Edit、WebFetch、MCP、Subagents 等工具调用的边界。学会六种模式、deny/ask/allow、路径规则和 sandbox（沙盒）配合。"
canonical: "https://xiangyugongzuoliu.com/tag/claude-code"
verifiedAt: "2026-05-08"
---

权限配置的目标不是让 Claude Code 少问，而是让它在低风险动作上少问，在高风险动作上必须停下。少弹窗只是结果，边界清楚才是目的。——Aaron

> [!NOTE]
> **这一章用 15 分钟换什么**：上一章讲 settings（设置）放在哪里。这一章讲 settings 里最重要的一类配置：permissions（权限）。读完你应该能为一个项目写出低风险 allow、高风险 ask、敏感路径 deny，并知道 Bash、WebFetch、MCP 和 sandbox（沙盒）的边界差异。

## 1. 权限管的是“工具调用”，不是 Claude 的想法

Claude Code 做事靠工具。

它读文件、改文件、运行命令、抓网页、调用 MCP、派 subagent，本质上都是一次 tool call。权限系统管的就是这些 tool call 能不能发生、要不要问你。

官方 [Configure permissions](https://code.claude.com/docs/en/permissions) 文档给了一个基础分层：

| 工具类型 | 例子 | 默认是否需要批准 |
|------|------|------|
| Read-only | file reads、Grep | 通常不需要 |
| Bash commands | shell execution | 需要 |
| File modification | Edit / Write | 需要 |

所以不要把权限理解成“信任 Claude 还是不信任 Claude”。更准确是：

> [!IMPORTANT]
> **第一性原理**：权限系统在回答“这次动作一旦发生，能不能自动承担后果”。读文件、改文件、跑命令、访问外部系统的后果不一样，边界也应该不一样。

| 阶段 | Claude Code 在判断什么 | 可能结果 |
|------|-------------------------|----------|
| 1 | Claude 准备调用某个工具 | 进入权限匹配 |
| 2 | 匹配 `deny`、`ask`、`allow` 规则 | 拒绝、询问或允许 |
| 3 | 命中 `ask` | 等你确认后再执行 |
| 4 | 命中 `allow` | 直接执行 |
| 5 | 命中 `deny` | 直接阻止 |

## 2. 六种权限模式：先定整体姿态

权限模式决定一场会话里 Claude Code 多常停下来问你。

| 模式 | 不问就能做什么 | 适合什么 |
|------|------|------|
| `default` | 读文件 | 新手、敏感项目、需要逐步审查 |
| `acceptEdits` | 读文件、文件编辑、常见文件系统命令 | 熟悉仓库、愿意事后看 diff |
| `plan` | 读文件、探索，不直接改源码 | 复杂任务、陌生仓库、先审方案 |
| `auto` | 大多数动作自动执行，但有后台安全检查 | 长任务、减少提示疲劳 |
| `dontAsk` | 只允许预批准工具，其他自动拒绝 | CI、脚本、锁死环境 |
| `bypassPermissions` | 跳过权限提示和安全检查 | 仅限隔离容器 / VM |

CLI 里可以启动时指定：

```bash
claude --permission-mode plan
```

也可以写默认模式：

```json
{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}
```

`Shift+Tab` 默认循环 `default` → `acceptEdits` → `plan`。`dontAsk` 不在循环里；`auto` 和 `bypassPermissions` 需要满足条件或显式启用。

> [!CAUTION]
> **`bypassPermissions` 不是高手模式**：它会跳过权限层，v2.1.126 起也包括写 `.git`、`.claude`、`.vscode`、`.idea`、`.husky` 等 protected paths。只在坏了也无所谓的隔离环境用。

## 3. 三类规则：deny / ask / allow

模式是整体姿态，规则是具体边界。

| 规则 | 含义 | 适合什么 |
|------|------|------|
| `allow` | 匹配后自动允许 | 稳定、低风险、重复动作 |
| `ask` | 匹配后每次询问 | 需要上下文判断的动作 |
| `deny` | 匹配后直接阻止 | 密钥、危险命令、敏感路径、不可信工具 |

官方规则顺序是：

```text
deny -> ask -> allow
```

第一条匹配规则生效，所以 deny 永远优先：

```mermaid
flowchart TD
    Call[Claude 准备调用工具]
    Call --> CheckDeny{命中 deny?}
    CheckDeny -->|是| Block[直接阻止]
    CheckDeny -->|否| CheckAsk{命中 ask?}
    CheckAsk -->|是| Prompt[弹窗等你确认]
    CheckAsk -->|否| CheckAllow{命中 allow?}
    CheckAllow -->|是| Run[直接执行]
    CheckAllow -->|否| ModeFallback[按权限模式默认行为]

    style Block fill:#fee2e2,stroke:#dc2626,stroke-width:2px
    style Prompt fill:#fef3c7,stroke:#d97706,stroke-width:2px
    style Run fill:#dcfce7,stroke:#16a34a,stroke-width:2px
    style ModeFallback fill:#e0e7ff,stroke:#4f46e5,stroke-width:2px
```

一个项目级示例：

```json
{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)",
      "Bash(git diff *)",
      "WebFetch(domain:docs.anthropic.com)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(npm publish *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Bash(rm -rf *)",
      "Bash(curl *)",
      "Bash(wget *)"
    ]
  }
}
```

这份配置表达：

- lint / test / diff 可以自动做。
- push / publish 必须问。
- secrets、危险删除、直接网络拉取默认拒绝。

> [!TIP]
> **新手写法**：先写 deny，再写 ask，最后只给最确定的低风险动作 allow。不要为了省弹窗从 allow 开始写。

## 4. 规则语法：`Tool` 或 `Tool(specifier)`

权限规则格式只有两类：

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

例子：

常见规则写法：

- `Bash`：匹配所有 Bash。
- `Bash(*)`：等价于 `Bash`。
- `Bash(npm run build)`：精确匹配该命令。
- `Read(./.env)`：匹配当前目录 `.env`。
- `WebFetch(domain:example.com)`：匹配 example.com 的 WebFetch。
- `Agent(Explore)`：匹配 Explore subagent。

Bash wildcard 细节：

- `Bash(ls *)`：匹配 `ls -la`，不匹配 `lsof`。
- `Bash(ls*)`：既可能匹配 `ls -la`，也可能匹配 `lsof`。
- `Bash(ls:*)`：结尾 `:*` 等价于尾部 ` *`。
- `Bash(git * main)`：一个 `*` 可以跨多个参数。

> [!WARNING]
> **空格很重要**：`Bash(ls *)` 和 `Bash(ls*)` 风险不同。写 Bash 规则时不要随手省空格。

## 5. Bash 是最容易误配的工具

Bash 不是普通工具。它可以：

- 读文件。
- 改文件。
- 删除文件。
- 联网。
- 执行脚本。
- 调 docker、npx、devbox、mise 等二级执行器。

官方文档里有几个关键事实。

**复合命令会拆开检查。**

这些分隔符会拆成多个子命令：

```text
&&  ||  ;  |  |&  &  newline
```

规则必须匹配每个子命令。也就是说，允许 `safe-cmd` 不等于允许：

```bash
safe-cmd && rm -rf .
```

**Claude Code 会剥掉部分 process wrappers。**

内置识别：

```text
timeout, time, nice, nohup, stdbuf, bare xargs
```

所以 `Bash(npm test *)` 也可能匹配：

```bash
timeout 30 npm test
```

但这些不在可剥离列表里：

```text
direnv exec, devbox run, mise exec, npx, docker exec
```

如果你写：

```text
Bash(devbox run *)
```

它可能覆盖 `devbox run rm -rf .`。更好的写法是精确到内部命令：

```text
Bash(devbox run npm test)
```

> [!IMPORTANT]
> **Bash 规则原则**：能精确就精确，能 ask 就别 allow。尤其不要给执行器、包管理器、容器命令写过宽前缀。

## 6. Read / Edit 路径规则怎么写

`Read` 和 `Edit` 路径规则遵循 gitignore 风格，并有四类路径。

四类路径写法：

- `//path`：文件系统绝对路径。
- `~/path`：home 目录相对路径。
- `/path`：project root 相对路径。
- `path` 或 `./path`：当前目录相对路径。

最容易错的是绝对路径。

```text
Read(/Users/alice/file)
```

这不是文件系统绝对路径，而是项目根目录下的 `Users/alice/file`。

真正的绝对路径要写：

```text
Read(//Users/alice/file)
```

Windows 会被规范化成 POSIX 风格，比如：

```text
C:\Users\alice
```

会变成：

```text
/c/Users/alice
```

所以跨盘匹配 `.env` 可以用：

```text
Read(//**/.env)
```

还有 symlink 规则：

symlink 规则：

- allow：symlink 路径和目标都匹配才允许，否则提示。
- deny：symlink 路径或目标任一匹配就阻止。

> [!CAUTION]
> **路径 deny 不是系统沙盒**：`Read(./.env)` 阻止 Claude 的 Read tool，不阻止 Bash 子进程运行 `cat .env`。高敏感文件要配合 Bash deny、sandbox 和系统权限。

## 7. WebFetch 不等于网络隔离

`WebFetch(domain:example.com)` 只控制 Claude Code 的 WebFetch 工具。

它不控制 Bash 里的：

```bash
curl
wget
python -c 'requests.get(...)'
node fetch(...)
```

官方文档也明确提醒：using WebFetch alone does not prevent network access。

可靠做法是组合：

- WebFetch：只允许可信域名。
- Bash deny：禁止 `curl`、`wget` 等网络工具。
- PreToolUse Hook：对 Bash 里的 URL 做更细检查。
- sandbox network：从 OS / proxy 层限制网络域名。

> [!WARNING]
> **不要用 `Bash(curl https://github.com *)` 当网络白名单**：curl 参数、重定向、变量、协议变化都可能绕过你的直觉。更稳的是禁 Bash 网络工具，用 WebFetch 或 sandbox 网络规则。

## 8. MCP 和 Subagents 也要写权限

MCP server 可能连接数据库、issue 系统、云服务、浏览器和内部 API。不要因为它不是 Bash，就默认安全。

MCP 规则示例：

- `mcp__github`：匹配 github server 的所有工具。
- `mcp__github__*`：同样匹配该 server 所有工具。
- `mcp__github__create_issue`：只匹配一个具体工具。

更稳的做法：

- 探索型只读工具可以 allow。
- 写远端状态的工具先 ask。
- 删除、发布、授权类工具尽量 deny 或 managed。
- 不要对整个 MCP server 粗暴 allow，除非你确认所有 tool 都低风险。

Subagent 用 `Agent(AgentName)` 控制：

```json
{
  "permissions": {
    "deny": ["Agent(Explore)"]
  }
}
```

> [!TIP]
> **判断标准**：凡是能改变远端系统、创建 PR、发布内容、修改数据库、操作浏览器登录态的 MCP tool，都不应该默认 allow。

## 9. sandbox（沙盒）和 permissions（权限）怎么配合

Permissions 和 sandbox 是两层。

两层边界：

- Permissions：管理所有工具，包括 Bash、Read、Edit、WebFetch、MCP、Agent。
- sandbox：管理 Bash 及其子进程的文件系统和网络访问。

官方 sandbox 文档说，sandboxed bash tool 使用 OS-level primitives：

- macOS：Seatbelt。
- Linux / WSL2：bubblewrap。

它能限制 Bash 子进程能读写哪些路径、能访问哪些网络域名。

关键交互：

- deny rules 仍然生效。
- sandbox 文件系统限制使用 Read / Edit deny rules，不是完全独立的一套文件规则。
- 网络限制组合 WebFetch permission rules 和 sandbox `allowedDomains` / `deniedDomains`。
- `autoAllowBashIfSandboxed: true` 默认启用时，sandboxed Bash 命令会自动允许，即使 `ask: Bash(*)` 存在。
- `rm` / `rmdir` 指向 `/`、home 或关键系统路径时仍会触发提示。

> [!IMPORTANT]
> **一句话理解**：permissions 决定 Claude 能不能尝试调用工具；sandbox 决定 Bash 真跑起来后能不能越界。两者不是替代关系。

## 10. `additionalDirectories` 只加文件访问，不加完整配置根

你可以扩展 Claude Code 的文件访问范围：

```bash
claude --add-dir ../shared
```

会话中：

```text
/add-dir ../shared
```

持久配置：

```json
{
  "additionalDirectories": ["../shared"]
}
```

但官方权限文档有一个重要边界：additional directories grant file access, not configuration。

这意味着：

`--add-dir` 的加载边界：

- `.claude/skills/`：会加载，支持 live reload。
- `.claude/settings.json` 里的 plugin settings：只加载 `enabledPlugins` 和 `extraKnownMarketplaces`。
- `CLAUDE.md` / `.claude/rules/` / `CLAUDE.local.md`：需要 `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1`。
- subagents / commands / output styles / hooks / 其他 settings：不会加载。

> [!WARNING]
> **不要误会 add-dir**：它主要是“多给 Claude 看一个目录”，不是“把另一个项目的 `.claude/` 完整挂进来”。

## 11. Managed policy：团队安全底线

团队和企业不要只靠个人自觉。

managed settings 可以强制：

- 禁止 bypass。
- 禁止 auto。
- 只允许 managed permission rules。
- 限制 MCP servers。
- 限制 channel plugins。
- 限制 marketplace。
- 只允许 managed hooks。

示例：

```json
{
  "permissions": {
    "deny": [
      "Bash(curl *)",
      "Bash(wget *)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ],
    "disableBypassPermissionsMode": "disable"
  },
  "allowManagedPermissionRulesOnly": true
}
```

> [!CAUTION]
> **managed 适合底线，不适合细节**：全组织禁止危险动作很合理；把某个项目的临时 lint 命令写进 managed 就会污染所有团队。

## 12. 本章自检

试着用自己的话回答：

1. 权限系统管的是 Claude 的想法，还是 tool call？对应 §1。
2. `default`、`acceptEdits`、`plan`、`auto`、`dontAsk`、`bypassPermissions` 各适合什么？对应 §2。
3. 为什么 `Bash(devbox run *)` 比 `Bash(devbox run npm test)` 风险更高？对应 §5。
4. `Read(//Users/alice/file)` 和 `Read(/Users/alice/file)` 有什么区别？对应 §6。
5. WebFetch、Bash 网络命令和 sandbox 网络规则分别管什么？对应 §7-§9。

> [!IMPORTANT]
> **过关标准**：你能为一个真实项目写出三条 allow、两条 ask、三条 deny，并能解释每条规则对应的风险边界。

<details id="glossary">
<summary><b>本篇术语速查表</b></summary>

- Permission：权限。控制 Claude Code tool call 能不能执行的规则体系。
- Permission mode：权限模式。一场会话的整体审批策略。
- `allow`：允许规则。匹配后自动执行，不询问。
- `ask`：询问规则。匹配后要求人工确认。
- `deny`：拒绝规则。匹配后直接阻止。
- Bash rule：Bash 权限规则。控制 shell 命令是否能执行。
- Read / Edit rule：文件路径规则。控制文件读写工具能访问哪些路径。
- WebFetch：网页抓取工具。Claude Code 内置的网页读取工具，不等同于全局网络控制。
- MCP permission：MCP 权限。控制 MCP server 或具体 MCP tool 是否可用。
- Agent permission：Subagent 权限。控制 Claude 能否调用指定 subagent。
- sandbox：沙盒。OS 层限制 Bash 及其子进程文件和网络访问。
- Protected paths：受保护路径。`.git`、`.claude`、`.vscode` 等不应自动修改的位置。
- Managed policy：管理策略。企业或组织下发的不可覆盖安全边界。

</details>

## 官方来源

- [Configure permissions](https://code.claude.com/docs/en/permissions)
- [Choose a permission mode](https://code.claude.com/docs/en/permission-modes)
- [Sandboxing](https://code.claude.com/docs/en/sandboxing)
- [Security](https://code.claude.com/docs/en/security)
- [Claude Code settings](https://code.claude.com/docs/en/settings)

## 接下来去哪

<Cards>
  <Card href="/docs/claude-code/official/01-core-capabilities/memory" title="使用记忆机制" description="权限决定 Claude 能做什么，记忆决定 Claude 每次开始时知道什么。下一章讲 CLAUDE.md 和 auto memory。" />
  <Card href="/docs/claude-code/official/01-core-capabilities/settings" title="配置 Claude Code（上一篇）" description="权限规则写在哪个 scope（作用域），直接决定团队能不能复现、管理员能不能强制执行。" />
  <Card href="/docs/claude-code/understanding/11-permissions" title="深度理解：该给 AI 多少权限" description="如果想看权限背后的信任层级和成本边界，读理解篇的 Permissions。" />
</Cards>

如果只记一个判断：**权限不是为了少弹窗，而是为了把 Claude Code 的每一次工具行动放在可解释、可审查、可强制的边界里。**
