<!-- title: 权限模式与项目配置入门 -->

## 概述

本教程面向第一次使用 Claude Code 的零基础开发者，聚焦最容易被忽略却最关键的一环——**权限控制与配置文件**。你将学会在六种权限模式间自如切换、用 `/permissions` 管理 allow/ask/deny 三类规则、编写分层 `settings.json`，以及用 `CLAUDE.md` 给项目注入"长期记忆"。学完后，你能为一个真实项目搭出一套"既顺畅、又不失控"的安全基线，避免每条命令都点 Allow 的疲惫，也避免 `bypassPermissions` 一时爽、删库火葬场的悲剧。

**适用人群**：已经装好 Claude Code、能跑通首条提示，但还停留在默认模式、每次操作都被打断的初学者。

## 前置条件

- 已安装 Node.js 18+ 与 Claude Code，能进入交互界面
- 有一个可练习的本地代码目录（哪怕是空文件夹）
- 基本的命令行操作能力（`cd`、`mkdir`、编辑文本）
- 了解 JSON 语法（会写大括号和方括号即可）

---

## 第一步：理解权限系统的三层心智模型

Claude Code 的安全设计可以用一张表概括。官方把工具按"危险程度"分成三类，对应不同的审批策略：

| 工具类型 | 典型例子 | 是否需要审批 | "不再询问"的生效范围 |
|---------|---------|------------|-------------------|
| 只读工具 | 文件读取、Grep 搜索 | 否 | 不适用 |
| Bash 命令 | 任意 shell 执行 | 是 | 按"项目目录 + 命令"永久记住 |
| 文件修改 | Edit / Write | 是 | 仅本会话内有效 |

这里有一个初学者最容易踩的坑：**给一条 Bash 命令点"不再询问"后，它是按"当前项目目录 + 这条命令"组合记忆的**。这意味着你在 A 项目放行的 `npm run build`，到 B 项目仍会重新询问；而你在同一项目放行的 `git push`，会一直放行到会话结束。理解这一点，你就明白为什么需要 `settings.json` 来固化那些"反复都要用、每次都该通过"的命令。

另一个反直觉但极其重要的原则是：**权限规则由 Claude Code（宿主程序）强制执行，而非模型**。你在 `CLAUDE.md` 里写"不要执行 rm -rf"只能影响模型"想做什么"，无法改变"被允许做什么"。要真正堵住某个操作，必须用 deny 规则、权限模式或 PreToolUse 钩子。把这句话记牢，能帮你避开 90% 的安全错觉。

## 第二步：掌握六种权限模式与 Shift+Tab 切换

权限模式是控制"整体审批松紧度"的总开关。在交互界面里，**反复按 `Shift+Tab` 即可循环切换模式**，左下角会显示当前模式名。你可以在 `settings.json` 里用 `defaultMode` 字段指定一个启动默认值。

| 模式 | 行为 | 适用场景 |
|------|------|---------|
| `default` | 每种工具首次使用时询问 | 陌生项目、初次探索 |
| `acceptEdits` | 自动放行文件编辑 + `mkdir`/`touch`/`mv`/`cp` 等常见文件系统命令（限工作目录及 additionalDirectories 内） | 信任的重构、批量改动 |
| `plan` | 只读探索：可读文件、可跑只读 shell，**绝不改源码** | 方案设计、代码审查、估算工作量 |
| `auto` | 自动放行工具调用，但后台做安全核验，确认动作与你的请求一致（研究预览特性） | 想要顺滑又想要一道智能闸门 |
| `dontAsk` | 默认全部拒绝，只有被 `/permissions` 或 allow 规则预先批准的才放行 | 严格受控、最小权限 |
| `bypassPermissions` | 跳过几乎所有审批 | ⚠️ 仅限容器/VM 等隔离环境 |

其中前三种是日常主力，`acceptEdits` 是大多数熟练用户的常驻模式——它让你摆脱"改一个文件点一次确认"的疲劳，但仍然会拦住 shell 执行这类高危操作。

`bypassPermissions` 必须单独提醒。它确实能让 Claude 跑得飞快，但官方明确写了两个"熔断器"：一是显式 ask 规则仍会强制弹窗；二是针对文件系统根目录或家目录的删除（如 `rm -rf /`、`rm -rf ~`）始终会弹窗，作为防模型出错的最后一道闸。即便如此，该模式下对 `.git`、`.claude`、`.vscode`、`.cargo` 等敏感目录的写入是直接放行的。团队管理者若想彻底禁用，可在 managed settings 里把 `permissions.disableBypassPermissionsMode` 设为 `"disable"`；同理 `permissions.disableAutoMode` 可禁掉 `auto` 模式。

**预期结果**：进入项目目录启动 Claude Code，按三次 `Shift+Tab`，依次看到 `default` → `acceptEdits` → `plan` 的角标变化，停在 `plan` 模式时让 Claude 阅读代码，你会发现它"光说不练"——这正是你想要的安全状态。

**常见问题**：*按 Shift+Tab 没反应？* 多半是终端快捷键被抢占（tmux、某些 IDE 内嵌终端）。换用系统终端，或直接在启动时用 `--permission-mode plan` 指定。

## 第三步：用 `/permissions` 管理三类规则

在交互界面输入 `/permissions`，会打开一个可视化的规则管理面板，列出所有规则及其来源的 `settings.json` 文件。三类规则的定义很直观：

- **allow**：放行，不再询问
- **ask**：每次都弹窗确认
- **deny**：直接阻止

规则的**求值顺序固定为 deny → ask → allow**，第一个匹配项即决定结果，而且**匹配的先后只看声明顺序，不看规则宽窄**。这带来一条容易吃亏的规则：

> 一条宽泛的 deny（如 `Bash(aws *)`）会拦住所有匹配调用，哪怕你同时写了一条更窄的 allow（如 `Bash(aws s3 ls)`）。也就是说，**deny 规则里无法嵌套 allowlist 例外**。同理，ask 优先于 allow：同一调用若同时命中 ask 与 allow，会弹窗而非放行。

deny 还有两种形态，区别很大：

- 裸工具名 `Bash` 作为 deny：把整个工具从模型上下文里移除，模型根本"看不见"它。
- 带模式限定 `Bash(rm *)`：工具仍可见，但模型一旦尝试匹配调用就被拦截。

前者适合"完全不想让模型碰"的工具，后者适合"允许用 Bash，但禁掉某些危险子命令"。

规则语法是 `Tool` 或 `Tool(specifier)`：

```
Bash              # 匹配所有 Bash 命令（等价于 Bash(*)）
Bash(npm run test)   # 精确匹配这条命令
Bash(npm *)          # 匹配所有 npm 子命令
Read                # 匹配所有文件读取
Edit(src/**)        # 匹配 src 目录下的编辑
WebFetch            # 匹配所有网络抓取
```

**预期结果**：在面板里新增一条 `deny: Bash(rm -rf *)`，然后让 Claude 试图执行 `rm -rf node_modules`，你会看到它被直接拒绝，而不是弹窗。

**常见问题**：*我在 CLAUDE.md 里写了"禁止 git push"为什么还会推？* 因为 CLAUDE.md 只影响模型意图，不影响权限。要真拦住，得写 `deny: Bash(git push*)`。

## 第四步：编写分层 `settings.json`

每次手敲 `/permissions` 太累，而且换台机器就丢了。`settings.json` 就是把这些规则固化为文件、纳入版本控制、团队共享的机制。Claude Code 的设置文件分**五层**，优先级从高到低：

1. **企业托管策略**（`managed-settings.json`，管理员下发，对受限键不可覆盖）— 最高
2. **命令行参数**（如 `--permission-mode`）
3. **项目本地** `.claude/settings.local.json`（个人偏好，应加入 `.gitignore`）
4. **项目共享** `.claude/settings.json`（团队共用，提交到仓库）
5. **用户全局** `~/.claude/settings.json`（跨项目默认值）— 最低

一个推荐分工是：把团队规范放进第 4 层 `.claude/settings.json` 并提交；把个人临时放行（比如你的本地路径）放进第 3 层 `.local.json` 并 ignore；把跨项目通用的模型偏好放进第 5 层。

下面是一个典型的**项目共享**配置，它做了三件事：默认进入 `acceptEdits` 模式、永久放行安全的只读/构建命令、用 deny 兜底拦截破坏性操作：

```json
{
  "permissions": {
    "defaultMode": "acceptEdits",
    "allow": [
      "Read",
      "Grep",
      "Bash(npm run test)",
      "Bash(npm run lint)",
      "Bash(npm run build)",
      "Bash(git status)",
      "Bash(git diff*)",
      "Bash(git log*)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push*)",
      "Bash(git push --force*)",
      "Bash(curl * | sh)",
      "Read(.env)",
      "Read(.env.*)",
      "Read(**/secrets/**)"
    ]
  }
}
```

几个细节值得点破：

- `Read(.env)` 和 `Read(.env.*)` 把敏感配置文件从模型视野里摘掉，防止 API 密钥被读进上下文、进而可能外泄。
- `deny: Bash(git push*)` 比 CLAUDE.md 里一句"不要推送"硬核得多——它是程序级强制。
- 注意 `Bash(git diff*)` 末尾的 `*`，它能同时匹配 `git diff`、`git diff --stat`、`git diff HEAD~1`。

`additionalDirectories` 用来授权 Claude 访问工作目录之外的路径（比如项目引用了外部的共享库）。但要记住一条原则：**它授予的是"文件访问权限"，而不是"配置传播"**——即你可以让 Claude 读写那个目录的文件，但那个目录里的 `.claude/settings.json` 不会自动套用进来。

**预期结果**：保存上述文件后重启会话，输入 `/permissions`，应看到面板里这些规则赫然在列，来源标注为本项目的 `.claude/settings.json`。再让 Claude 跑 `npm run test`，全程无弹窗。

**常见问题**：*改了 settings.json 不生效？* 优先检查五层优先级——很可能用户级 `~/.claude/settings.json` 里有个 `defaultMode` 把它盖住了，或命令行带了 `--permission-mode`。在企业环境还要确认 `managed-settings.json` 是否锁死了该键。

## 第五步：用 `CLAUDE.md` 注入项目记忆

权限管"能不能做"，`CLAUDE.md` 管"该怎么想、该怎么做"。它是一份会被自动注入会话上下文的 Markdown，扮演"长期系统提示"的角色。它有三个层级：

- `~/.claude/CLAUDE.md`：全局，所有项目生效（适合写个人编码风格）
- `<项目根>/CLAUDE.md`：项目级，团队共享（适合写架构约定、常用命令）
- 子目录里的 `CLAUDE.md`：当 Claude 进入该目录时按需加载

对入门者，一份好的项目级 `CLAUDE.md` 至少回答四个问题：**这是什么项目、怎么跑起来、有什么约定、有哪些雷区**。示例：

```markdown
# 项目说明：order-service

订单微服务，Node.js 20 + Express + PostgreSQL 16。

## 常用命令
- 跑测试：`npm run test`（单文件用 `npm run test -- path/to/file`）
- 启动开发：`npm run dev`（监听 3000 端口）
- 数据库迁移：`npm run migrate:up`

## 约定
- 提交信息遵循 Conventional Commits（feat:/fix:/chore:）
- 所有时间一律存 UTC，展示层再转时区
- 数据库迁移文件**只能新增、不能修改已发布的**

## 雷区
- src/legacy/ 是即将下线的旧逻辑，新功能不要碰
- .env 里有第三方密钥，切勿输出或提交
```

注意 `CLAUDE.md` 不是越长越好。过长会挤占上下文、稀释信号。把"每次都要提醒"的硬约束放这里，把"偶尔查一下就够"的细节拆进 `docs/` 让 Claude 按需用 Read 调取，是更可持续的做法。

**常见问题**：*CLAUDE.md 里写了"用 4 空格缩进"，Claude 还是用了 2 空格？* 检查是否真正生效——可以在会话里直接问"你当前的缩进规则是什么"来验证它是否读到了。若没读到，确认文件确实在项目根且名为 `CLAUDE.md`（大小写敏感）。

## 第六步：打通"模式 + 规则 + 记忆"的求值闭环

把前三步串起来，一次工具调用的完整判定链是这样的：

```mermaid
flowchart TD
    A[模型发起工具调用] --> B{命中 deny 规则?}
    B -- 是 --> X[❌ 直接拒绝]
    B -- 否 --> C{命中 ask 规则?}
    C -- 是 --> P[🔔 强制弹窗确认]
    C -- 否 --> D{命中 allow 规则?}
    D -- 是 --> Y[✅ 自动放行]
    D -- 否 --> E{当前权限模式?}
    E -- acceptEdits 且为文件操作 --> Y
    E -- plan 且为修改类操作 --> X
    E -- default --> P
    E -- bypassPermissions --> Y
    E -- auto --> F[🛡️ 后台安全核验]
    F -- 通过 --> Y
    F -- 可疑 --> P
    P -- 用户同意 --> Y
    P -- 用户拒绝 --> X
```

记住这张图的两个关键分支：**规则永远优先于模式**（ask/deny 不受模式影响），**deny 永远最先判定且无例外出口**。掌握这两点，你就能预测任何调用的命运，而不必反复试错。

---

## 实战案例：为前端项目搭一套安全基线

目标：新建一个 Vite + React 项目，配置成"开发顺滑、危险操作被拦、敏感文件不可见"。

**1. 初始化项目并进入：**

```bash
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
```

**2. 创建 `.claude/settings.json`（团队共享）：**

```json
{
  "permissions": {
    "defaultMode": "acceptEdits",
    "allow": [
      "Read",
      "Grep",
      "Bash(npm run dev)",
      "Bash(npm run build)",
      "Bash(npm run test*)",
      "Bash(npx tsc --noEmit)",
      "Bash(git status)",
      "Bash(git diff*)",
      "Bash(git log*)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push*)",
      "Bash(npm publish*)",
      "Read(.env)",
      "Read(.env.*)"
    ]
  }
}
```

**3. 创建 `.claude/settings.local.json`（个人本地，记得 `.gitignore`）：**

```json
{
  "permissions": {
    "allow": ["Bash(open *)"]
  }
}
```

**4. 创建 `CLAUDE.md`：**

```markdown
# my-app

Vite + React + TypeScript 前端项目。

## 命令
- 开发：`npm run dev`
- 构建：`npm run build`
- 类型检查：`npx tsc --noEmit`

## 约定
- 组件用函数式，props 用 interface 定义
- 样式优先 CSS Modules，避免内联 style
- 提交前先跑 `npx tsc --noEmit`
```

**5. 把 `.gitignore` 补上本地设置：**

```
.claude/settings.local.json
```

**6. 验证闭环：** 启动 Claude Code，依次让它执行——

- "跑一下类型检查" → `npx tsc --noEmit` 自动放行（命中 allow）
- "帮我在 src 下新建一个 Button 组件" → 文件创建自动放行（acceptEdits 模式）
- "把 node_modules 删掉" → `rm -rf node_modules` 被拒（命中 deny）
- "读一下 .env" → 被拒（命中 deny）

四项全部符合预期，说明你的安全基线已经成型。之后无论谁来接手，只要 `git pull` 拿到 `.claude/settings.json` 和 `CLAUDE.md`，就能复刻同样的工作体验。

---

## 常见问题速查

**Q：acceptEdits 模式下，Claude 还是改了我不想要的文件，怎么办？**
切回 `default` 或 `plan`。acceptEdits 默认对工作目录内所有路径放行编辑；想限定范围，可缩小 additionalDirectories 或用更细的 deny 规则保护特定子目录。

**Q：allow 写了 `Bash(npm run test)`，为什么 `npm test` 还弹窗？**
规则是精确前缀匹配，`npm run test` 不等于 `npm test`。要么两条都写，要么用 `Bash(npm *test*)` 放宽（注意放宽会带来误放行风险）。

**Q：deny 了一条命令，Claude 却绕道用别的命令达到同样目的？**
这正是"模型意图 vs 宿主权限"的分野。deny 只挡具体调用，不挡语义等价操作。对真正高危的能力，应配合 PreToolUse 钩子做内容审计，或干脆移除工具。

**Q：企业强制了一个我不认可的 defaultMode，能改吗？**
不能覆盖 managed settings 里的受限键。这是设计如此——管理员策略优先级最高且不可被下级文件推翻。

---

## 延伸阅读

- **官方权限配置文档**：`https://code.claude.com/docs/en/permissions` — 规则语法、模式、托管策略的权威来源
- **官方权限模式文档**：`https://code.claude.com/docs/en/permission-modes` — Shift+Tab 循环与各模式何时使用
- **PreToolUse Hooks**：把权限规则升级为"可编程审批"，能在工具执行前跑自定义脚本做内容审计
- **Sandbox environments / Bash sandbox**：官方文档专门一节讲如何用沙箱隔离而非纯靠审批来保命
- **Settings Reference**：`settings.json` 全部可用键的完整清单

## 训练营适用性评估

| 维度 | 评估 |
|------|------|
| 适合训练营类型 | AI 编程入门营、企业内训（强调安全合规）、开发者效能提升营 |
| 学员基础要求 | 会命令行与 JSON，已跑通 Claude Code 首次会话 |
| 建议教学时长 | 1.5–2 小时（含动手实操） |
| 实操重点 | 五层 settings.json 分工、Shift+Tab 三态切换、deny 闭环验证 |
| 进阶衔接 | 本教程讲透"静态规则"，后续可接 Hooks（动态审批）与 Subagent 权限隔离 |

## 参考来源

1. [Configure permissions — Claude Code Docs](https://code.claude.com/docs/en/permissions) — 官方权限系统权威文档，涵盖 allow/ask/deny 求值顺序、规则语法、托管策略
2. [Choose a permission mode — Claude Code Docs](https://code.claude.com/docs/en/permission-modes) — 六种权限模式定义与 Shift+Tab 切换说明
3. [Claude Code settings.json Permissions: Control Exactly What AI Can Do](https://blog.vincentqiao.com/en/posts/claude-code-settings-permissions/) — permissions 配置实战，含 allow/deny/ask 三类规则与 defaultMode 详解
4. [Claude Code settings.json 配置详解：5 层优先级](https://blog.vincentqiao.com/claude-code-settings-intro/) — 五层配置文件优先级与合并逻辑解析
5. [Claude Code 权限配置完全指南 | settings.json·Hooks·allowlist](https://claudecode-lab.com/zh/blog/claude-code-permissions-guide/) — 中文实战指南，含环境专属配置与可运行示例

> [!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)
