---
title: "11 · 该给 AI 多少权限"
description: "Claude Code 权限不是安全感按钮，而是把读、写、运行命令、联网和成本拆成不同信任层级。学会用六种模式、Allow/Ask/Deny、沙盒和预算边界。"
canonical: "https://xiangyugongzuoliu.com/tag/claude-code"
verifiedAt: "2026-05-08"
---

权限不是让 Claude Code 变弱，而是让它在正确的地方自动做事，在危险的地方停下来问你。真正的问题不是“给不给权限”，而是“什么操作值得信任，什么操作必须留给人判断”。——Aaron

> [!NOTE]
> **这一篇用 15 分钟换什么**：第 10 篇讲 Hooks，让 Claude Code 到点自动检查。第 11 篇讲 Permissions：当 Claude Code 想读文件、改文件、跑命令、联网、调用 MCP 工具时，哪些可以自动放行，哪些必须询问，哪些应该永远拒绝。

## 1. 从一个 `git push` 开始

你让 Claude Code 修一个小 bug。

它读了几份文件，改了一行逻辑，跑了测试，最后准备执行：

```bash
git push origin main
```

这时弹窗出现了。

很多新手第一反应是烦：刚才都让你修了，为什么还问？

但换一个角度看，这个弹窗正是权限系统最有价值的地方。读文件不会改变世界；改文件能回滚；跑测试通常安全；直接推到远程分支，影响就变大了。

> [!IMPORTANT]
> **第一性原理**：权限系统不是在判断 Claude Code 聪不聪明，而是在判断某个动作一旦发生，代价由谁承担。

Claude Code 官方 [Permission modes](https://code.claude.com/docs/en/permission-modes) 文档说得很直接：当 Claude 想编辑文件、运行 shell 命令或发起网络请求时，会暂停并请求批准；permission mode 决定这种暂停出现得有多频繁。

所以权限不是“限制 AI”，而是把动作按风险分层。

```mermaid
flowchart LR
    Read["读文件<br/>低风险"]
    Edit["改文件<br/>可审查"]
    Bash["跑命令<br/>看命令"]
    Network["联网 / MCP<br/>看目标"]
    Remote["推送 / 部署 / 删除<br/>高影响"]

    Read --> Edit --> Bash --> Network --> Remote

    style Read fill:#dcfce7,stroke:#22c55e,stroke-width:2px
    style Edit fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
    style Bash fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
    style Network fill:#ffedd5,stroke:#f97316,stroke-width:2px
    style Remote fill:#fee2e2,stroke:#ef4444,stroke-width:2px
```

## 2. 先分清三层边界

很多人把 Claude Code 的安全能力混成一团：权限、沙盒、Hooks、`CLAUDE.md` 都往一个篮子里放。

先拆开：

| 层 | 管什么 | 典型问题 |
|------|------|------|
| `CLAUDE.md` | 让 Claude 知道你希望怎么做 | “这个项目用 pnpm，不用 npm” |
| Hooks | 某个事件点必须自动检查 | “写 `.env` 前拦住” |
| Permissions | 某个工具调用能不能发生 | “能不能运行 `git push`？” |
| Sandbox | Bash 进程能碰到哪里 | “命令就算跑了，能不能读 SSH key？” |

一句话：

- `CLAUDE.md` 是说明书。
- Hooks 是检查点。
- Permissions 是访问边界。
- Sandbox 是操作系统围栏。

> [!TIP]
> **新手判断法**：如果问题是“Claude 应该记住什么”，写 `CLAUDE.md`；如果问题是“到点必须查什么”，用 Hook；如果问题是“这个工具能不能用”，配 Permission；如果问题是“命令即使跑起来也不能越界”，开 Sandbox。

## 3. 六种权限模式，不是越松越好

Claude Code 当前有六种 permission mode。旧教程里常说“五种”，现在已经不够了，因为官方把 `auto` 模式单独放进了权限模式体系。

| 模式 | 不问你就能做什么 | 适合什么 |
|------|------|------|
| `default` | 读文件 | 新手上手、敏感项目 |
| `acceptEdits` | 读文件、改工作目录内文件、常见文件命令 | 你愿意事后看 diff |
| `plan` | 读文件、探索、提出方案，不直接改源码 | 多文件任务、先审方案 |
| `auto` | 大多数操作自动执行，但经过后台安全分类器 | 长任务、减少确认疲劳 |
| `dontAsk` | 只允许预先批准的工具和只读 Bash | CI、脚本、锁死环境 |
| `bypassPermissions` | 基本全部放行 | 只限隔离容器 / VM |

最容易误解的是这三个：

**`acceptEdits` 不是全自动。**

它主要是自动接受文件编辑和一些常见文件系统命令，比如 `mkdir`、`touch`、`mv`、`cp`、`sed`。但作用范围仍然受 working directory、`additionalDirectories` 和 protected paths 约束。

**`plan` 不是“不能看代码”。**

它正适合看代码。Claude Code 可以先读文件、跑探索命令、写计划，然后让你选择怎么执行。多文件改动、陌生仓库、生产风险高的任务，先用 `plan` 往往更省时间。

**`bypassPermissions` 不是高手模式。**

它跳过权限提示和安全检查。官方明确建议只在隔离环境里用，比如容器、VM、无互联网访问的 dev container。不要在你的日常开发机上把它当省事开关。

> [!CAUTION]
> **最危险的误解**：`bypassPermissions` 不是“我很信任 Claude”。它是“这个环境坏了也无所谓”。如果环境不是一次性的，就不要把它当默认工作模式。

切换方式也别记错：

```bash
claude --permission-mode plan
claude --permission-mode acceptEdits
claude --permission-mode dontAsk
claude --permission-mode bypassPermissions
```

CLI 里 `Shift+Tab` 默认循环 `default` → `acceptEdits` → `plan`。`dontAsk` 不在循环里；`auto` 和 `bypassPermissions` 只有满足条件或用启用参数启动后才会出现。

## 4. `auto` 模式：减少弹窗，不等于没有风险

`auto` 是这篇必须单独讲的新模式。

它的目标不是"全部放开"，而是让 Claude Code 少问你，同时让后台 classifier（安全分类器）检查动作是不是超出了你的请求、是不是碰了不认识的基础设施、是不是像被恶意内容带偏。

**classifier 怎么"判"**：底层是 Anthropic 训练的一个专用安全分类模型——每次 Claude 决定动手前，把"动作 + 当前上下文"送给 classifier 二次判断。它不是规则引擎（写死哪些命令禁止），是模型（看动作语义和当前任务的相关性）。**为什么这样设计**：规则引擎覆盖不了"组合危险"——`rm -rf` + 当前在 `/` 是危险，但在临时目录是正常；规则引擎只看命令字符串两者一样，模型能看上下文区分。代价：classifier 本身要花推理时间 + token——这是 auto 模式跟 bypassPermissions 在体感上"似乎都没弹窗" 但底层完全不同的原因。

官方当前文档列了几个关键边界：

官方当前文档列了几个关键边界：

- 状态：research preview，不保证绝对安全。
- 账号：不是所有计划都可用，Pro 不可用。
- 模型 / 供应商：有模型和 Anthropic API 条件限制。
- 默认信任：工作目录、本仓库 remote、只读 HTTP、声明依赖安装等更容易放行。
- 默认阻止：`curl | bash`、外发敏感数据、生产部署、云存储批量删除、IAM / repo 权限变更、force push 等。
- 会话边界：你在对话里说“不要 push”，classifier 会把它当阻止信号。

这就是 `auto` 跟 `bypassPermissions` 的核心差别：

| 模式 | 表面体验 | 底层含义 |
|------|------|------|
| `auto` | 少弹窗 | 仍有后台安全判断 |
| `bypassPermissions` | 不弹窗 | 跳过权限层和安全检查 |

> [!IMPORTANT]
> **一句话理解**：想减少弹窗，优先考虑 `auto` 或 sandbox；想完全跳过检查，只有一次性隔离环境才考虑 `bypassPermissions`。

## 5. 细粒度规则：Allow / Ask / Deny

权限模式是“整体姿态”，规则才是“具体边界”。

官方 [Permissions](https://code.claude.com/docs/en/permissions) 文档把规则分成三类：

| 规则 | 含义 | 例子 |
|------|------|------|
| `allow` | 自动允许，不弹窗 | `Bash(npm test)` |
| `ask` | 每次询问 | `Bash(git push *)` |
| `deny` | 直接拒绝 | `Read(./.env)` |

顺序也很重要：`deny` → `ask` → `allow`。第一条匹配的规则生效，所以拒绝永远优先。

一个新手可直接照着改的配置：

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

这份配置表达的是：

- 测试、lint、看 diff，可以自动做。
- push、publish，必须问我。
- 读 `.env`、读 secrets、跑 `rm -rf`，直接拒绝。

> [!WARNING]
> **不要写过宽的 allow**：`Bash(*)` 看起来省事，实际是在把 shell 的风险整体交出去。能写窄，就写窄到具体命令。

**新手最常见的两类配置失控**：

1. **嫌弹窗烦直接 `bypassPermissions`**：第一周用 Claude Code 觉得弹窗烦，改默认模式为 bypassPermissions——结果某天 Claude 在 `~/Documents` 里跑了 `rm -rf node_modules` 但目录算错位置，删了真实数据。**修复**：日常 `acceptEdits` 而不是 bypassPermissions——前者编辑自动通过但 Bash / 网络仍受 ask 约束，后者是"全部跳过"。
2. **写 `Bash(*)` 当 allow**：嫌每次确认烦，写 `allow: ["Bash(*)"]` 把所有 shell 命令都通过——等于 sudo all 给 Claude，连 `rm -rf` 都不弹。**修复**：allow 只列**频繁 + 安全**的具体命令（`Bash(npm test)` / `Bash(git diff *)` / `Bash(ls *)`），频繁但有风险的（`git push`）放 ask，永远不该的（`rm -rf`）放 deny。

## 6. Protected paths：有些地方默认更敏感

Claude Code 对一些路径有特殊保护，因为这些路径一旦被改坏，会影响仓库状态、编辑器配置或 Claude 自己的配置。

典型 protected paths 包括：

典型 protected paths 包括：

- 仓库状态：`.git`、`.gitmodules`。
- 编辑器 / Git hooks：`.vscode`、`.idea`、`.husky`。
- Claude 配置：`.claude`、`.claude.json`、`.mcp.json`。
- Shell 启动文件：`.bashrc`、`.zshrc`、`.profile`。
- 搜索配置：`.ripgreprc`。

这里有一个容易过时的细节：官方当前说明是，除了 `bypassPermissions` 之外，protected paths 都不会被自动批准；在 `default`、`acceptEdits`、`plan` 里会询问，在 `auto` 里走 classifier，在 `dontAsk` 里拒绝。

而 `bypassPermissions` 从 v2.1.126 起也会放行 protected paths。只有类似 `rm -rf /`、`rm -rf ~` 这种指向根目录或 home 目录的删除，仍然会触发最后的断路保护。

> [!CAUTION]
> **这就是为什么旧经验不可靠**：权限细节会随版本变。写教程时不能只靠印象，必须按当前官方文档核对。

## 7. Sandbox：权限之外再加一圈围栏

权限规则是在 Claude Code 层面判断“这个工具调用可不可以发生”。沙盒是在操作系统层面限制“这个 Bash 进程和它的子进程能碰到哪里”。

官方 [Sandboxing](https://code.claude.com/docs/en/sandboxing) 文档的关键点是：

两者的边界：

- 作用对象：权限规则覆盖 Bash、Read、Edit、WebFetch、MCP 等所有工具；Sandbox 主要覆盖 Bash 和它启动的子进程。
- 执行层级：权限规则在 Claude Code 应用层；Sandbox 在操作系统层。
- 文件边界：权限规则用 Read / Edit / deny 等表达；Sandbox 限制进程读写路径。
- 网络边界：权限规则里 WebFetch 管 domain；Sandbox 通过代理和域名 allow / deny 限制网络。
- 典型价值：权限规则不让 Claude 尝试危险操作；Sandbox 让命令即使运行也不能越界。

在 macOS 上，沙盒使用 Seatbelt；Linux 和 WSL2 使用 bubblewrap。它不是 Claude 的“自觉”，而是系统级限制。

你可以在 Claude Code 里用：

```text
/sandbox
```

打开沙盒菜单。默认思路是：当前工作目录内可以更自由，越出边界就提示或阻止。

> [!TIP]
> **实操策略**：日常开发不要只靠权限弹窗。能开 sandbox 的场景就开 sandbox，再配少量 deny 规则，把弹窗留给真正高风险动作。

## 8. 成本也是一种边界

很多人讲权限只讲安全，不讲成本。

但对自动化 Agent 来说，成本边界和安全边界是一类问题：都是防止系统在无人盯着的时候跑出你能承受的范围。

官方 [Costs](https://code.claude.com/docs/en/costs) 文档里，现在推荐用 `/usage` 看当前会话的 token 和估算成本。旧稿里常见的 `/cost` 说法不适合继续写进新教程。

日常你记这三类就够：

日常你记这三类就够：

- 看当前用量：`/usage`。
- 降低思考成本：`/effort`、`/model`、`/config`、`MAX_THINKING_TOKENS`。
- SDK 自动化限额：`max_budget_usd` / `maxBudgetUsd`。

注意边界：

- `/usage` 里的金额是本地估算，不一定等于最终账单。
- Pro / Max 订阅用户看到的是订阅用量，不等同于 API 账单。
- `max_budget_usd` / `maxBudgetUsd` 是 Agent SDK 里的预算参数，不要把它误写成所有 CLI 场景都有的通用开关。

> [!IMPORTANT]
> **一句话理解**：权限防止 Claude Code 做错事，预算防止 Claude Code 做太久。两者都是边界设计。

## 9. 新手该怎么选

不用一开始就追求“最安全”或“最自动”。按项目风险选。

```mermaid
flowchart TD
    Start["这次任务风险高吗？"]
    Sensitive["会碰生产、密钥、部署、远程分支？"]
    Multi["会改很多文件或你不熟悉仓库？"]
    Review["你愿意事后看 diff 吗？"]
    CI["是不是无人值守脚本 / CI？"]
    Isolated["环境坏了也无所谓？"]

    Plan["用 plan 先审方案"]
    Default["用 default"]
    Accept["用 acceptEdits + 看 diff"]
    DontAsk["用 dontAsk + allowlist"]
    Bypass["隔离环境才用 bypassPermissions"]

    Start --> Sensitive
    Sensitive -->|是| Plan
    Sensitive -->|否| Multi
    Multi -->|是| Plan
    Multi -->|否| Review
    Review -->|是| Accept
    Review -->|否| Default
    CI --> DontAsk
    Isolated --> Bypass

    style Plan fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
    style Bypass fill:#fee2e2,stroke:#ef4444,stroke-width:2px
```

更具体一点：

更具体一点：

- 第一次用 Claude Code：`default`。
- 熟悉项目、频繁小改：`acceptEdits`。
- 多文件重构 / 陌生仓库：`plan` 开始，审完再执行。
- 想减少弹窗但还要安全检查：符合条件时用 `auto`。
- CI / 自动脚本：`dontAsk` + 明确 allowlist。
- 一次性容器 / VM：必要时才用 `bypassPermissions`。

> [!WARNING]
> **反模式**：不要因为弹窗烦，就直接开 `bypassPermissions`。正确顺序是：先收窄 allowlist，再考虑 sandbox，再考虑 auto，最后才是隔离环境里的 bypass。

## 10. 和 Hooks 放在一起看

第 10 篇讲 Hooks，这一篇讲 Permissions。两者经常一起用，但职责不同。

职责边界可以这样记：

- “能不能运行 `git push`？”：Permission。
- “每次写 `.env` 前必须拦住并解释原因”：Hook。
- “如果测试输出太长，自动只保留失败信息”：Hook。
- “任何 MCP 浏览器工具都不许点发布按钮”：Permission + Hook。
- “只允许读取 docs，不允许读 secrets”：Permission。

官方 Permissions 文档也说明了这个关系：`PreToolUse` hook 会在权限提示前运行，hook 可以 deny、强制询问或跳过提示；但 hook 决策不能绕过 deny / ask 规则。匹配到 deny 的规则仍然会阻止调用。

```mermaid
flowchart LR
    Action["Claude 准备调用工具"]
    Hook["PreToolUse Hook<br/>运行自定义检查"]
    Rules["Permission Rules<br/>Deny / Ask / Allow"]
    Mode["Permission Mode<br/>default / auto / ..."]
    Run["工具执行"]
    Block["阻止或询问"]

    Action --> Hook --> Rules --> Mode
    Hook -->|blocking| Block
    Rules -->|deny / ask| Block
    Mode -->|允许| Run

    style Hook fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
    style Rules fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
    style Block fill:#fee2e2,stroke:#ef4444,stroke-width:2px
```

> [!TIP]
> **一句话理解**：Permission 负责“这类工具调用能不能过”；Hook 负责“过之前或过之后要不要做额外检查”。

## 11. 本章自检

试着用自己的话回答：

1. 为什么权限弹窗不是"AI 不够强"，而是"动作后果需要分层"？对应 §1-§2。
2. `acceptEdits`、`auto`、`bypassPermissions` 的差别是什么？对应 §3-§4。
3. 为什么 `deny` 规则应该比 `allow` 规则更窄但更坚决？对应 §5。
4. Sandbox 为什么只能补强 Bash 边界，不能替代所有 Permission？对应 §7。
5. **动手题** ⭐：在你最常用的项目根 `.claude/settings.json` 写 3 条规则——1 条 allow（写一条你**真的常用**的命令，比如 `Bash(pnpm test)`）、1 条 ask（写一条**频繁但有风险**的命令，比如 `Bash(git push *)`）、1 条 deny（写一条**永远不该自动执行**的，比如 `Read(./.env)`）。每条解释为什么放这一档。这一题做完你才会真懂"分层"不是道理，是配置文件。对应 §5 + §9。

> [!IMPORTANT]
> **过关标准**：你能为一个真实项目写出三条规则：一个 allow、一个 ask、一个 deny，并能解释为什么这三条对应不同风险。

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

- Permission：权限。Claude Code 工具调用能不能执行的规则体系。
- Permission mode：权限模式。一次会话的整体批准策略。
- `default`：默认模式。读文件自动，其他高风险动作询问。
- `acceptEdits`：自动接受编辑。文件改动自动通过，适合事后看 diff。
- `plan`：计划模式。先探索和出方案，不直接改源码。
- `auto`：自动模式。少弹窗，但后台 classifier 做安全检查。
- `dontAsk`：不询问模式。只执行预批准工具，其他自动拒绝。
- `bypassPermissions`：跳过权限。跳过权限提示和安全检查，只适合隔离环境。
- Allow：允许规则。匹配后自动通过。
- Ask：询问规则。匹配后要求人工确认。
- Deny：拒绝规则。匹配后直接阻止。
- Sandbox：沙盒。对 Bash 进程做操作系统级文件和网络隔离。
- Classifier：安全分类器。`auto` 模式下判断动作是否越界的后台模型。
- Protected paths：受保护路径。`.git`、`.claude` 等不应轻易自动修改的位置。

</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)

## 接下来去哪

<Cards>
  <Card href="/docs/claude-code/understanding/12-plugins" title="➡️ 12 · 插件怎么扩展" description="Permissions 解决工具能不能用，Plugins 解决能力怎么打包和分发。下一篇讲 Claude Code 插件体系。" />
  <Card href="/docs/claude-code/understanding/10-operation-control" title="10 · 怎么让操作 100% 执行（上一篇）" description="如果你还分不清 Hook 和 Permission，先回看上一篇：Hook 是确定性检查点。" />
  <Card href="/docs/claude-code/understanding/05-thinking-depth" title="05 · 思考深度怎么选" description="权限管动作边界，effort 管思考成本。成本敏感时，这一篇也要一起看。" />
</Cards>

如果只记一个判断：**权限不是越松越先进，也不是越严越安全；好的权限配置，是让低风险动作自动发生，让高影响动作必须经过你。**
