<!-- title: 告别逐条放行：权限配置上手 -->

## 概述

本教程面向刚装好 Claude Code、却每次都要点"Allow"点到怀疑人生的零基础开发者。你将学会用 **三种权限模式** 和 **settings.json 的 allow/ask/deny 规则**，把一个"问个不停的助手"调教成"边界清晰的受控沙箱"。学完后你能为任意项目写一份可入库、可复用的权限配置文件，让 Claude 在白名单内自由操作、在危险操作前停下来问你。无需编程经验，跟着复制粘贴即可完成首个受控项目。

## 前置条件

- 已安装 Claude Code（命令行输入 `claude --version` 有输出即可；若没装，参考官方 `npm install -g @anthropic-ai/claude-code`）
- 已完成一次登录（订阅登录或 API Key 登录，能进入交互界面）
- 会用命令行创建文件夹、用任意编辑器改文本文件
- 准备一个练手目录（本教程用 `~/perm-demo`）

---

## 一、先搞懂：为什么默认配置会让你"放行到手酸"

Claude Code 出厂默认是**最谨慎模式**：它每想改一个文件、每想跑一条命令，都会暂停并弹出确认框。这对第一次用的人很安全，但一旦你让它"重构这个模块""跑一下测试"，确认框就会像弹幕一样刷屏。

更麻烦的是：这些放行决定**只活在当前会话里**。下次重启，又从零开始点。这就是社区俗称的 **"approval fatigue"（放行疲劳）**。

解决办法不是粗暴地打开"全部自动通过"（那就是危险的 bypassPermissions 模式），而是**用配置文件把规则固化下来**：哪些操作永远自动放行，哪些永远拒绝，哪些每次都要问。这就是本教程的核心。

---

## 二、认识三种（实为四种）权限模式

Claude Code 把"该不该问"抽象成模式。在交互界面里按 **Shift+Tab** 会在三个模式间循环切换，当前模式显示在输入框上方。

| 模式 | 改文件 | 跑命令 | 典型场景 |
|---|---|---|---|
| **default** | 问 | 问 | 日常开发，最稳 |
| **acceptEdits** | 自动放行 | 仍问 | 改一批文件、跑少量命令时提速 |
| **plan** | 不改（只读） | 受限 | 先让它出方案、不动手 |
| **bypassPermissions** | 全自动 | 全自动 | **慎用**，仅限一次性脚本/CI |

记忆口诀：**default 最稳，acceptEdits 提速改文件，plan 只读不动手，bypass 是裸奔**。

关键认知：**模式是"会话级开关"，settings.json 是"项目级规则"**。两者叠加——规则定义白名单/黑名单，模式决定白名单之外的操作要不要问你。本教程重点是把"规则"写进文件。

---

## 三、settings.json 的三层作用域

Claude Code 的配置不是单一文件，而是三层叠加，优先级从高到低：

1. **企业策略**（`/etc/claude-code/managed-settings.json` 等，普通用户基本用不到）
2. **命令行参数**（启动时传入，临时覆盖）
3. **项目本地** `.claude/settings.local.json`（不入库，个人偏好，如个人的 API Key）
4. **项目共享** `.claude/settings.json`（**入库**，团队共享的权限规则）
5. **用户全局** `~/.claude/settings.json`（所有项目通用的默认值）

合并规则：**高优先级覆盖低优先级**。`deny` 永远是硬上限——任何一层写了 deny，下层再 allow 也无效。这条规则是沙箱安全的基石：团队领导在共享层 deny 掉 `rm -rf`，团队成员的个人配置再怎么 allow 也绕不过去。

```mermaid
flowchart TD
    U["~/.claude/settings.json<br/>用户全局默认"] --> M["合并"]
    P[".claude/settings.json<br/>项目共享·入库"] --> M
    L[".claude/settings.local.json<br/>项目本地·不入库"] --> M
    C["命令行参数"] --> M
    M --> F["最终生效配置"]
    F --> R{"deny 硬上限<br/>任何层 deny 即拒绝"}
    R -->|允许| GO["执行"]
    R -->|拒绝| BLOCK["拦截"]
```

> 实践要点：**权限规则放 `.claude/settings.json`（入库），密钥/个人偏好放 `.claude/settings.local.json`（加进 `.gitignore`）**。

---

## 四、allow / ask / deny 三类规则的语法

规则写在 `permissions` 对象里，三组数组：

- `allow`：自动放行，不问
- `ask`：每次都问（即使模式是 acceptEdits）
- `deny`：永远拒绝

每条规则是一个"工具说明符"字符串，格式是 `工具名(参数模式)`。常用工具：`Bash`、`Read`、`Edit`、`Write`、`WebFetch`。

```mermaid
flowchart LR
    OP["Claude 要执行操作"] --> C1{"命中 deny?"}
    C1 -->|是| BLK["❌ 拒绝"]
    C1 -->|否| C2{"命中 allow?"}
    C2 -->|是| OK1["✅ 自动放行"]
    C2 -->|否| C3{"命中 ask?"}
    C3 -->|是| ASK["❓ 弹窗询问"]
    C3 -->|否| MODE{"看当前模式"}
    MODE -->|default| ASK
    MODE -->|acceptEdits<br/>且为编辑| OK2["✅ 自动放行"]
    MODE -->|plan| BLK2["🚫 只读拦截"]
```

### Bash 规则的几种写法

```text
Bash(git status)        # 精确匹配，只放行这一条命令
Bash(git diff:*)        # 前缀匹配，git diff 后面跟任何参数都行
Bash(npm run test:*)    # 放行 npm run test、npm run test:unit 等
Bash(ls:*)              # 放行所有 ls 开头
```

冒号加星号 `:*` 表示"前缀匹配，后面随便接"。**这是减少弹窗最有效的语法**——把团队高频命令写成前缀规则，能干掉 80% 的确认框。

### 文件规则

```text
Read                    # 放行所有读取（最宽松，慎用）
Read(./src/**)          # 只能读 src 目录
Edit(./src/**)          # 只能改 src 目录
Edit(~/.zshrc)          # 精确到某个文件
Write(//tmp/out.txt)    # 绝对路径用双斜杠开头
```

### 敏感信息保护（重点）

把密钥、环境变量文件 deny 掉，避免 Claude 把 `.env` 内容读进上下文、甚至写进 commit：

```text
Read(./.env)
Read(./.env.*)
Read(./**/*.key)
Read(./**/*.pem)
Read(./**/credentials*)
```

---

## 五、动手：配置你的第一个受控项目

### 步骤 1：创建练手项目

```bash
mkdir -p ~/perm-demo/.claude
cd ~/perm-demo
git init
echo "node_modules/" > .gitignore
echo ".claude/settings.local.json" >> .gitignore
```

**预期结果**：生成一个带 `.claude` 目录、已初始化 git 的空项目，本地配置被排除在版本控制外。

### 步骤 2：写共享配置 `.claude/settings.json`

用编辑器创建 `~/perm-demo/.claude/settings.json`，粘贴：

```json
{
  "model": "claude-sonnet-4-6",
  "permissions": {
    "defaultMode": "default",
    "allow": [
      "Read",
      "Bash(git status)",
      "Bash(git diff:*)",
      "Bash(git log:*)",
      "Bash(ls:*)",
      "Bash(wc:*)",
      "Bash(npm run test:*)",
      "Bash(npm run build)"
    ],
    "ask": [
      "Bash(npm install:*)",
      "Bash(git add:*)",
      "Bash(git commit:*)"
    ],
    "deny": [
      "Bash(rm:*)",
      "Bash(sudo:*)",
      "Bash(git push:*)",
      "Bash(curl:*)",
      "Bash(wget:*)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./**/*.key)",
      "Read(./**/*.pem)",
      "Edit(~/.**)",
      "Write(~/.**)"
    ]
  }
}
```

**字段逐行解读**：
- `model`：固定用某个模型，避免每次手选
- `defaultMode: default`：会话默认从最稳模式起步
- `allow`：读文件全放行；git 查看类、统计类、构建测试类命令前缀放行——这些是"看"和"验"，零风险
- `ask`：装依赖、改 git 状态这种"有副作用"的操作每次确认
- `deny`：删除、提权、推送、联网下载、读密钥、动家目录——**红线**

**预期结果**：保存后文件即是项目的权限宪法。

### 步骤 3：进会话验证

```bash
cd ~/perm-demo
claude
```

进入交互界面后输入：

```text
/permissions
```

**预期结果**：弹出权限管理界面，能看到刚才写的 allow/ask/deny 三组规则，且来源标记为 `.claude/settings.json`。

### 步骤 4：实测规则是否生效

在会话里依次让它做三件事，观察弹窗差异：

1. "读取当前目录所有文件并统计行数" → 触发 `Read`、`ls`、`wc`，全部**自动放行**，无弹窗
2. "执行 npm install" → 触发 `ask`，**弹窗询问**你同意与否
3. "删除整个 node_modules（用 rm -rf）" → 命中 `deny`，**直接拒绝**，连问都不问

**预期结果**：三条命令对应三种行为，证明规则已接管。

### 步骤 5：用模式切换进一步提速

按 **Shift+Tab** 切到 `acceptEdits`，让它"创建一个 utils.js 并写个加法函数"。这次改文件**不再弹窗**，但若它想跑 `npm install`，仍会问——因为 `ask` 规则优先于模式。

**预期结果**：体会"规则 + 模式"双层控制：规则管白名单/黑名单，模式管白名单之外那一档的松紧。

---

## 六、实战案例：代码统计沙箱

把上面的配置打包成一个**只读分析沙箱**——让 Claude 自由读代码、自由跑统计命令，但**一行都改不了、连不上网、删不掉任何东西**。这种配置特别适合"让 AI 帮我做代码审查/统计但绝不能动我的代码"的场景。

创建 `~/perm-demo/.claude/settings.json`（覆盖步骤 2 的版本）：

```json
{
  "model": "claude-sonnet-4-6",
  "permissions": {
    "defaultMode": "default",
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "Bash(git status)",
      "Bash(git log:*)",
      "Bash(git diff:*)",
      "Bash(ls:*)",
      "Bash(wc:*)",
      "Bash(find:*)",
      "Bash(grep:*)",
      "Bash(rg:*)",
      "Bash(cat:*)",
      "Bash(echo:*)"
    ],
    "deny": [
      "Edit",
      "Write",
      "NotebookEdit",
      "Bash(rm:*)",
      "Bash(mv:*)",
      "Bash(cp:*)",
      "Bash(mkdir:*)",
      "Bash(touch:*)",
      "Bash(git add:*)",
      "Bash(git commit:*)",
      "Bash(git push:*)",
      "Bash(curl:*)",
      "Bash(wget:*)",
      "Bash(npm:*)",
      "WebFetch",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./**/*.key)",
      "Read(./**/*.pem)"
    ]
  },
  "additionalDirectories": [],
  "env": {
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
  }
}
```

**设计思路**：
- `allow` 里全是"只读"工具：`Read`/`Glob`/`Grep` + 只读 Bash 命令
- `deny` 里把所有"写"工具（`Edit`/`Write`/`NotebookEdit`）一刀切掉，再加文件系统修改命令、git 写操作、联网、包管理
- 即便你不小心切到 `bypassPermissions`，`deny` 仍然是硬上限——**这是 deny 模式最强的价值：模式会忘，规则不会**

**实测任务**：在 `~/perm-demo` 里随便丢几个源码文件，然后对 Claude 说：

> "统计这个项目每个文件的代码行数，找出最长的三个函数，输出一份 markdown 报告。"

**预期结果**：它能流畅读文件、跑 `wc -l`、跑 `rg` 搜函数，最终生成报告——全程零弹窗，且如果你后续追问"顺便把这些函数重构一下"，它会因 `deny(Edit)` 而**无法动手**，只能口头给建议。沙箱成立。

---

## 七、工作流程全景图

```mermaid
flowchart TD
    A["开始一个新项目"] --> B["cd 到项目根目录<br/>git init"]
    B --> C["创建 .claude/settings.json"]
    C --> D{"项目要不要入库共享?"}
    D -->|团队共享| E["权限规则写 settings.json<br/>个人密钥写 settings.local.json"]
    D -->|个人练手| F["都写 local 即可"]
    E --> G["定义 allow: 高频只读命令"]
    F --> G
    G --> H["定义 ask: 有副作用但可控"]
    H --> I["定义 deny: rm/sudo/密钥/家目录"]
    I --> J["把 settings.local.json<br/>加进 .gitignore"]
    J --> K["进会话<br/>/permissions 检查"]
    K --> L{"日常用哪个模式?"}
    L -->|谨慎改| M["default"]
    L -->|批量改文件| N["acceptEdits<br/>Shift+Tab"]
    L -->|先出方案| O["plan<br/>Shift+Tab 两次"]
    M --> P["放心交给 Claude"]
    N --> P
    O --> P
```

---

## 八、常见问题与排坑

**Q1：规则写了但没生效？**
检查三点：① JSON 语法是否正确（少逗号、多逗号都会让整个文件被忽略）；② 文件路径是否在 `.claude/settings.json`，而非项目根目录；③ 是否被更高优先级层覆盖——在 `/permissions` 界面看每条规则的**来源标注**。

**Q2：allow 和 ask 同时匹配一条命令，听谁的？**
优先级是 **deny > ask > allow**。所以 `Bash(git push:*)` 同时出现在 allow 和 deny 里，结果是被拒。利用这点可以把"团队默认放行、但个人想拦"的操作放个人层的 deny。

**Q3：`Bash(npm run test)` 和 `Bash(npm run test:*)` 有什么区别？**
前者**精确匹配**，只有 `npm run test` 这一条放行，`npm run test:unit` 仍会问；后者**前缀匹配**，子命令全放行。做测试/构建类规则几乎都用 `:*`。

**Q4：acceptEdits 模式下还是弹窗？**
说明该操作命中了 `ask`，或不在 allow 里。模式只决定"白名单之外"的默认行为，`ask` 规则永远优先于模式。

**Q5：bypassPermissions 到底能不能用？**
能用，但仅建议在**一次性、可丢弃、无敏感数据**的环境（如临时容器、CI 沙箱）里用，且务必配 `deny` 兜底。本地主力开发环境**永远不要**长期挂 bypass，一次误删家目录就够你哭的。

**Q6：怎么临时给一条命令放行，又不污染配置？**
在弹窗时选 "Yes, and don't ask again for this command"——Claude 会把这条规则写进 `.claude/settings.local.json`，下次自动放行，且不污染团队共享配置。这是日常最常用的"渐进式建白名单"手法。

**Q7：项目里已经有 `.env`，怎么保证不被读？**
在 `deny` 加 `Read(./.env)` 和 `Read(./.env.*)`。注意路径相对于项目根；若密钥散落各处，用通配 `Read(./**/*.key)`、`Read(./**/credentials*)` 兜底。

---

## 九、最佳实践清单

1. **共享层管红线，本地层管偏好**：`deny` 和团队标准放 `.claude/settings.json` 入库；个人模型偏好、临时放行放 `.claude/settings.local.json`。
2. **白名单用前缀，不要用全量 `Bash`**：永远别写 `"Bash"` 不带参数——那等于把整个 shell 放行，比 bypass 还危险。
3. **密钥一票否决**：`.env`、`*.key`、`*.pem`、`credentials*` 进 deny，且加进 `.gitignore`。
4. **破坏性命令进 deny**：`rm:*`、`sudo:*`、`git push:*`、`git push --force:*` 是四条"后悔药买不到"的红线。
5. **联网默认问**：`WebFetch`、`curl:*`、`wget:*` 放 `ask` 或 `deny`，避免 Claude 把代码片段发到外网。
6. **配 `.gitignore`**：`.claude/settings.local.json` 必须忽略，否则个人密钥会泄露。
7. **渐进建立 allow**：别一次性写一大堆，用 Q6 的"don't ask again"让真实工作流自然沉淀出白名单。
8. **入库的配置写注释**：JSON 不支持注释，可在同目录放 `settings.md` 说明每条规则的意图，方便新成员理解。

---

## 延伸阅读

- 官方权限模式文档：`code.claude.com/docs/en/permission-modes`——Shift+Tab 循环与四种模式的权威说明
- 官方配置参考：`code.claude.com/docs/en/settings`——所有字段（`model`、`env`、`additionalDirectories` 等）的完整列表
- 官方规则语法：`code.claude.com/docs/en/permissions`——allow/ask/deny 与工具说明符的细节
- 官方示例配置集：`github.com/anthropics/claude-code/tree/main/examples/settings`——可直接拷贝的样板
- 环境变量参考：`code.claude.com/docs/en/env-vars`——`settings.json` 里 `env` 字段可放哪些变量

---

## 训练营适用性评估

- **适合训练营类型**：Claude Code / AI 编程工具入门营、企业 AI 安全合规营、DevOps 自动化营的第一天"环境与边界"模块
- **教学时长**：约 **45–60 分钟**（讲解 20 分钟 + 跟练 25 分钟 + 排坑问答 15 分钟）
- **学员基础要求**：会用命令行、能看懂 JSON，无需编程经验
- **可拓展方向**：
  - 进阶 → 配合 **Hooks**（钩子）实现"违反 deny 时自动告警/回滚"
  - 进阶 → 把同一套 `settings.json` 用于 CI 的 `-p` 无头批处理，配合 bypass + deny 做"无人值守但安全"的管道
  - 团队 → 结合 `managed-settings.json`（企业策略层）做组织级红线
- **评估方式**：让学员提交一个 `settings.json`，跑通"统计沙箱"案例且 `rm -rf` 被拒、`.env` 不可读，即视为通过

## 参考来源

1. [Choose a permission mode — Claude Code Docs](https://code.claude.com/docs/en/permission-modes) — 官方权限模式说明，Shift+Tab 循环与四种模式权威定义
2. [Configure permissions — Claude Code Docs](https://code.claude.com/docs/en/permissions) — 官方 allow/ask/deny 规则语法与工具说明符细节
3. [Claude Code settings — Claude Code Docs](https://code.claude.com/docs/en/settings) — 官方配置字段完整参考（model、env、additionalDirectories、三层作用域优先级）
4. [Claude Code Permissions: A Practical settings.json Guide — Developers Digest](https://www.developersdigest.tech/blog/claude-code-permissions-settings-guide) — settings.json 作用域、规则语法、无头模式的实战解读
5. [examples/settings — anthropics/claude-code (GitHub)](https://github.com/anthropics/claude-code/tree/main/examples/settings) — 官方维护的可直接拷贝的样板配置集

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
