
Claude Code 的权限系统用「模式 + 规则」两层机制,外加分类器与裸奔模式两种特殊机制,平衡"敢放手"与"不失控";理解它,你才能真正放心让 AI 动你的代码。
你让 Claude 重构一个模块,它跑着跑着突然要执行 git push——上一秒还在改代码,下一秒要动远程仓库,这时候你心里大概率会咯噔一下。更极端的场景:Claude 想用 rm -rf 清一个"没用的目录",如果你没看清就按了允许,损失可能不可逆。这不是危言耸听,而是每个用 AI 写代码的人迟早会撞见的时刻。
有人可能会说,那我全程盯着弹窗不就好了?问题是真实工作里你不可能每次都认真读弹窗——弹得多了你会麻木,随手按允许,这正是出事的根源。所以 Claude Code 的思路不是"靠你盯紧",而是把判断前置:哪些根本不用问、哪些必须问、哪些问都别问,先替你分好类。
权限系统回答的正是三个问题:AI 能做什么、不能做什么、做之前要不要问你。它像一道闸门,放在每一次工具调用前面。目标也简单——在"敢放手"(不打断你的工作流)和"不失控"(危险操作有人把关)之间找平衡。Claude Code 用「模式 + 规则」两层机制实现这个平衡:模式决定大方向的松紧,规则细化到具体某条命令。新手往往只认识其中之一,于是要么被弹窗问烦,要么不小心放了不该放的操作。这篇把两者一起讲透,外加两个特殊机制(分类器和裸奔模式),你就能自己判断该怎么配。
先看一次工具调用的完整旅程。你提出任务,Claude 在内部计划好要调用哪个工具,比如 git push。注意,这一步不是直接执行,而是先进入权限系统检查,然后根据检查结果走三条路之一:允许(Allow,自动运行)、询问(Ask,暂停等你点头)、拒绝(Deny,直接拦下)。整个决策只有这三种结果,理解了这一点,后面所有模式、规则都是围绕"怎么落在这三选一"来设计的。
权限系统做深度检查时,会综合看三件事:
这三件事叠加之后,才决定最终是放行、弹窗还是拒绝。你可以把它想成过关安检:你的通行证等级(模式)决定能进几道门,安检名单(规则)标注了哪些门禁止进入,而你携带的物品(工具类型)决定了要不要开箱检查。三者任一命中高危,都会被单独拎出来盘问。
举个例子把它串起来。假设你现在处于 acceptEdits 模式,你让 Claude"重构一下模块 A,然后跑测试"。它先 Read 模块 A 的源码——只读工具,放行;接着用 Edit 改了两处文件——在 acceptEdits 模式下,工作目录内的编辑自动通过,不弹窗;然后它想执行 npm run test——Bash 命令不在自动放行范围,默认要询问,弹窗问你;你点了允许,它继续往下走。整个流程里,每一次工具调用都走了同一套检查,只是结果不同。
那 Ask 弹窗到底长什么样?它会把 Claude 想执行的操作和关键参数摆在你面前,比如 git push origin main,然后让你决定放行还是拦下。新手常忽略一个细节:弹窗里"允许并记住"本质是帮你往 allow 规则里写了一条,"拒绝"则只是本次拦截——大多数情况下下次遇到类似操作还会再问,除非 Claude 调整了方案不再触发。想清楚再点——每一次"记住",都在降低你以后看到弹窗的次数,也就悄悄降低了那道闸门对你的保护。
官方没有给工具贴死风险标签,但判断逻辑很直观:会不会修改系统。我据此把常见操作整理成三级,方便你理解——这是聊天用的归纳框架,不是官方分类:
级别 | 典型工具 | 默认行为 | 原因 |
|---|---|---|---|
🟢 只读 | Read、Grep、Glob | 通常直接放行 | 不改动任何系统状态 |
🟡 有副作用 | Bash(npm、git 等命令) | 通常要询问 | 能装依赖、联网、删文件 |
🔴 危险/破坏性 | 删文件、危险路径、读取 .env | 拒绝或强制确认 | 一旦出错损失不可逆 |
为什么这么分级?因为风险越高,越需要人介入。读一个文件读错了,顶多是浪费时间,重读一遍就行;装一个依赖装错了,可能污染整个开发环境;删一个目录删错了,就是数据事故,神仙难救。所以 Claude Code 对危险操作几乎不给自动放行的机会,宁可打断你,也不冒险。理解了这条逻辑,你就明白为什么同样的 Bash 命令,有的不用问、有的必须问——风险等级不一样。
具体到命令更好懂:npm install 会装依赖、pip install 也会装依赖,都属于 🟡;rm -rf dist、往系统目录写文件、读取 .env 都属于 🔴。判断标准始终只有一个——执行完,你的系统还是不是原来的样子。
换句话说,分级不是为了给工具贴标签,而是为了在你和 Claude 之间分配责任:风险越低,AI 自主权越大;风险越高,你介入的必要性越大。这套逻辑贯穿整个权限系统,记住它,后面所有模式、规则都不难理解。
模式是权限系统的大开关,决定默认情况下"不询问直接执行"到什么程度。Claude Code 一共六种,是这篇文章的核心表格:
模式 | 行为(哪些不询问直接执行) | 适用场景 |
|---|---|---|
default | 只读操作放行,危险操作询问 | 刚上手、敏感操作 |
acceptEdits | 工作目录内文件编辑 + 常见文件系统命令自动放行,Bash 命令仍询问 | 日常写代码 |
plan | 只读,可探索分析但不改文件、不跑命令 | 规划 / 探索代码结构 |
auto | 一切交由后台分类器审查,通过才放行、越界即拦截 | 长任务、减少弹窗疲劳 |
dontAsk | 未预批准的一律拒绝 | CI 流水线、脚本 |
bypassPermissions | 跳过所有提示 | 仅限容器 / VM / 隔离沙盒 |
切换方式有三种。会话中按 Shift+Tab 可以循环切换,但它只包含三个模式:default → acceptEdits → plan,再按回到 default。启动时用参数,比如 --permission-mode plan,一次会话直接落到指定模式。配置文件里设,在 settings.json 配 defaultMode 作为默认模式,每次启动自动生效。
三个模式怎么选,看你的工作阶段。plan 模式适合开工前的摸底:让 Claude 读代码、画结构、回答"这个项目怎么组织的",它不会改文件也不会跑命令,纯探索零风险。acceptEdits 模式适合真刀真枪写代码:Claude 在工作目录内改文件、移动文件不用逐个确认,但碰到 Bash 命令(装依赖、跑脚本)还是会停下来问你——这个组合是多数人日常用的甜点位。
对刚上手的新手,我的建议是从 default 模式开始:只读操作不打断你,危险操作必经你确认,节奏最安全。等你熟悉了弹窗的规律、知道自己最常被问的是哪些操作,再逐步切到 acceptEdits 或加 allow 规则,那时候的每一步调整都是有的放矢。
同一个小任务,在不同模式下体验差异巨大。拿"清理临时文件"来说:plan 模式下,Claude 只能看和计划,删不了任何东西;default 模式下,它每删一个文件都可能问一次,删几个你就烦了;acceptEdits 模式下,如果删除用的是常见文件系统命令,它可能直接执行,不用逐个确认;而真切到 bypassPermissions,它删得干脆利落,但你也失去了所有确认机会。对比下来你会发现,模式本质上是你愿意放弃多少"确认权",来换多少"流畅度"的一个旋钮。
注意:auto、bypassPermissions、dontAsk 这三个模式不在 Shift+Tab 循环里,必须单独用启动参数或配置开启——这是刻意设计,避免你随手按到"裸奔"档。另外 auto 模式不是想开就能开:它要求较高版本的模型(如 Claude Opus 4.6+ / Sonnet 4.6+)和 Team / Enterprise / API 计划,而且项目级配置不能自行开启 auto,需要更高层面的授权。
这里补一句衔接:dontAsk 模式依赖下一章的 allow 规则——只有预先批准的才会执行,其余一律拒绝;bypassPermissions 我们放到后文详解。
模式管大方向,规则管细节。规则写在 settings.json 里,一共三层,语义和交通灯一致:
层级 | 颜色 | 作用 | 示例 |
|---|---|---|---|
allow | 🟢 绿 | 自动允许执行 | "allow": ["Bash(npm run test)"] |
ask | 🟠 橙 | 必须弹窗询问 | "ask": ["Bash(git commit)"] |
deny | 🔴 红 | 直接拒绝执行 | "deny": ["Bash(rm -rf /)", "Read(**/.env)"] |
规则语法有两种形式:工具名或工具名(参数模式)。前者是工具级规则,对该工具整体生效;后者是内容级规则,带参数匹配更细。比如 Bash(git *) 匹配所有以 git 开头的命令,Read(~/.env) 精确匹配路径,* 是通配符。一个容易忽略的细节:内容级规则(带参数)优先于工具级规则(不带参数)。这意味着你可以用工具级规则给某个工具整体放行,再用内容级规则把其中个别危险命令单独拦下来,两级互补不冲突。
举个小例子:你给 Read 整体放行(工具级 "allow": ["Read"]),但你又不想让 AI 读某个敏感文件,就再加一条内容级 "deny": ["Read(~/secrets.json)"]。因为内容级优先,读别的文件照常放行,唯独这个文件被拦死。两级规则就是这么配合的。
优先级遵循"最严格规则优先":deny > ask > allow。判断顺序是这样的——先看 deny,命中就直接拒绝;没命中再看 ask,命中就弹窗;都没命中,最后才轮到 allow 自动放行。所以千万不要以为 allow 加得多就万事大吉,只要有一条 deny 撞上,前面的放行全部作废。
settings.json 有四级层级,从高到低:
层级 | 文件 | 作用域 | 说明 |
|---|---|---|---|
1(最高) | managed-settings.json | 企业级 | 管理员统一管理,用户不能改 |
2 | ~/.claude/settings.json | 用户级 | 对你所有项目生效 |
3 | .claude/settings.json | 项目级 | 随项目提交,可共享给团队 |
4 | .claude/settings.local.json | 本地覆盖 | 被 gitignore,仅你自己可见 |
四份配置会合并生效,但合并的规则要分两类看:普通配置项(比如 defaultMode)遵循"后面的覆盖前面的";权限规则则不同——各层级的 allow 会合并成一个允许集合,全部算数;deny 按"最严优先"拦截,某个操作只要被任何一层 deny 了就会被拦下。所以你可以用项目级规则给团队定公共底线,再用本地文件叠加个人偏好,两层 allow 共存,但谁也不能绕过团队写下的 deny。举个例子,一个完整的 settings.json 片段长这样:
{
"permissions": {
"allow": [
"Bash(npm run test)",
"Bash(npm run lint)"
],
"ask": [
"Bash(git commit)",
"Bash(git push)"
],
"deny": [
"Bash(rm -rf /)",
"Read(**/.env)"
]
}
}效果一目了然:npm run test、npm run lint 自动跑,不用问你;git 提交和推送会弹窗确认;rm -rf / 和读取任何 .env 直接拒绝,连问都不问。你也可以随时用 /permissions 命令在会话里交互式地查看、添加、删除规则,不用手改文件,改完立刻生效。
举一个常见操作:你跑 npm run build 前被问了两次,嫌烦,就可以直接输入 /permissions,在交互界面里把 Bash(npm run build) 加进 allow,回车确认,下次就不问了。规则是即改即用的,不需要重启会话。
/permissions 打开的面板会列出当前所有已生效规则,并标注每一条来自哪份配置文件——一眼就能分清是用户级还是项目级定的,想删掉某条历史 allow 规则也在这里操作,不用翻文件。最后记住规则的生效范围:路径类规则(如 Read(~/.env))只在匹配路径上生效,命令类规则(如 Bash(git *))匹配命令前缀。粒度越细越不容易误伤,这是写规则的一个原则:尽量精确,别一刀切。
讲 auto 模式之前,先明确一个前提:auto 不是"全自动裸奔"。它把判断权交给一个后台的 AI 分类器,这个分类器不依赖死规则,而是结合上下文做深度判断。
它会分析这么几件事:
给你一个典型画面:你在 auto 模式下让它"整理临时文件"。它先 Read 看目录,又跑 ls 确认内容,这些都直接放行。接着它准备执行 rm -rf temp/,分类器一比对——你的请求是"整理",不是"清空",动作明显越界,于是拦下,改成逐个删除确认过的缓存文件。审查的作用就在这里。
另外,prompt injection 不是科幻场景:如果你贴进一段包含恶意指令的第三方代码或文档,它可能试图诱导 Claude 执行危险命令。分类器在 auto 模式里专门盯这个,一旦检测到动作与你的显式请求不符,就按住不发。
如果分类器判定危险,系统会拦截,并让 Claude 换一种更安全的做法。比如你让它删一个临时文件,它如果提出删整个目录,分类器就会拦下来,改成精确到单文件的操作。这就是 auto 模式"松手但不失控"的底气来源。
如果你正在跑长任务、被弹窗问烦了,可以试试 auto,把那些"看着合理、但不想逐条确认"的操作交给后台审查,图个清净。只是记得——它防不住危险操作,别拿它去碰生产环境、删真实数据这类任务,那种场景宁可多问几次。
对新手来说,用 default 或 acceptEdits 就够,理解 classifier 主要是为了知道一件事:auto 不是无人审查,后台有 AI 盯着。但也要记住官方的定调——auto 模式"不是安全的保证",它只是把"问你"换成了"AI 审查"。所以 auto 适合长任务、减少弹窗疲劳,但不适合拿来做危险操作的兜底。真要锁死某类操作,靠规则,不靠模式。
如果说 auto 是"AI 帮我审查",bypassPermissions 就是"干脆不审查"。它跳过绝大多数权限提示直接执行,相当于一个"裸奔"开关。
先划红线:切勿在真实环境使用。它只适用于容器、虚拟机、随时可以重置的沙盒目录。你在这个模式下的判断应该是"我愿意承担这个沙盒里的风险",而不是"这个动作本身是安全的"——这两者是完全不同的判断。前者是你主动做出的取舍,后者是危险的幻想。想清楚你在哪个环境、愿不愿意承担后果,再决定开不开。
不过,即使是裸奔模式,Claude Code 也没把安全底线全拆掉,有三层兜底:
rm -rf /、rm -rf ~ 这类命令,弹出确认而不是直接执行;&&、||、;、|、>、$()、反引号)会强制确认,这条绕过了通配符匹配,你加再多的 * 也压不住;所以,如果你要彻底锁死某类操作,正确的做法是写 deny 规则,而不是指望裸奔模式不管。它管不了你不想让它管的,但它有自己必须守的底线。
实操上,最省心的做法是开一个临时目录当沙盒:在里面初始化一个一次性 git 仓库,把要实验的命令都放在这个目录里跑,玩坏了直接整个目录删掉重来。这样你既拿到了"不被打断"的效率,又没把真实项目暴露在风险里。
Claude 的工具调用被拒绝,不代表死路一条。通常原因是命令越权或动作太危险。你有三个应对办法:
举个具体的:你发现 Claude 每次跑测试都弹窗,很烦。别急着切模式,先看它到底在跑什么——如果是 npm run test 这种固定命令,直接加一条 "allow": ["Bash(npm run test)"],以后再也不问;如果是 git push 这种有副作用的,留着问反而踏实。判断标准很简单:这条命令删了重来会不会心疼?不会,就放行;会,就留着问。
再看一段完整的被拒对话。你让 Claude"清掉构建产物",它先 Read 确认了目录,然后准备执行 rm -rf dist——在 default 模式下被拦下弹窗。你看到 rm -rf 就警觉,点了拒绝。Claude 收到拒绝后没有硬来,而是换了个说法:"dist 目录里主要是编译缓存,我建议只删 30 天前的旧文件,保留最近的,可以吗?"这次它把范围收窄、动作降级,你点头放行。整个过程里,拒绝没有中断任务,而是把 AI 的意图校准到了你接受的范围内——这是权限系统最好的使用方式。
新手起步建议遵守安全最小化原则:从 default 开始,慢慢按需加 allow 规则,不要一上来就开 bypassPermissions。下面这张速查表覆盖了最常见的需求:
需求 | 做法 |
|---|---|
只读探索 | 用 plan 模式 |
日常写代码、不想每次确认编辑 | 用 acceptEdits 模式 |
某些命令不想被问 | 加 allow 规则,如 "Bash(npm run test)" |
禁止某些危险操作 | 加 deny 规则 |
批量 / 自动化 | dontAsk 模式 + 完整 allow 清单 |
还有两个保护细节你要知道。第一,.git、.claude 这类敏感目录在除 bypassPermissions 之外的所有模式下从不会自动放行写入,这是设计使然,防止 AI 手滑改坏版本库或配置文件。第二,常见误区有三个:把 bypassPermissions 当"安全模式";把所有命令一股脑加进 allow;以为 auto 模式完全没有审查。这三条踩中任意一条,都可能在某个时刻让代码或仓库付出代价。
Claude Code 的权限系统其实不复杂:模式管松紧、规则管细节、classifier 管 auto 模式的审查、bypassPermissions 管沙盒里的裸奔。对绝大多数新手,记住"default 起步 + 按需加 allow + 危险操作写 deny"这一条主线就够了。剩下的,等你真遇到了再翻也不迟——权限系统存在的意义,就是让你在放心放手的同时,始终留着一道自己能把关的闸门。
(版本声明:本文基于 2026 年 8 月版 Claude Code 撰写,各机制细节——尤其 auto 模式的模型与计划要求——会随版本演进,最终以官方文档为准。)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。