权限与模式
本教程共 34 篇 · 第 17 篇 · 更新于 2026-07-26 · 约 8 分钟阅读
17. 权限与模式
本节目标:搞懂 Claude Code 的权限系统怎么工作。学会用 allow/ask/deny 三条规则精确放行或拦截操作,掌握六种权限模式的区别和切换方法,弄清自动模式(auto)背后的分类器怎么配。学完你能让 Claude 该自动的自动、该拦的拦住。
权限到底在管什么
Claude Code 不是想干啥就干啥。每次它要执行一个有副作用的操作—改文件、跑命令、发网络请求—权限系统都会先过一道门。
打个比方:权限系统像公司门口的保安。读文件这种只读操作,保安直接放行(不用你签字);改文件、跑 npm install 这种有副作用的,保安拦下来要你点头;rm -rf / 这种要命的,保安直接挡在门外。
权限管的就是三件事:
| 工具类型 | 示例 | 默认要不要批准 |
|---|---|---|
| 只读 | 文件读取、Grep 搜索 | 不要,直接放行 |
| Bash 命令 | Shell 执行 | 要,除了内置只读命令 |
| 文件修改 | Edit/Write | 要 |
Note权限规则由 Claude Code 强制执行,不是模型自己判断。你在
CLAUDE.md里写”别跑 git push”只能影响 Claude 的意图,真正能不能跑成,得看权限规则。
三条规则:allow、ask、deny
权限规则就三种动作,记住这三个就够了:
| 动作 | 效果 | 什么时候用 |
|---|---|---|
allow | 不问你,直接放行 | 低风险高频操作,比如 npm run build |
ask | 弹提示,你点头才跑 | 有点风险,想每次过目的 |
deny | 直接拦死,不跑也不问 | 明确禁止的,比如 git push |
关键:优先级是 deny > ask > allow
规则按这个顺序评估:先看 deny,再看 ask,最后看 allow。第一个匹配的规则说了算,规则写得多具体都不改变这个顺序。
举个例子,你同时配了:
{
"permissions": {
"allow": ["Bash(aws s3 ls)"],
"deny": ["Bash(aws *)"]
}
}
aws s3 ls 虽然匹配了 allow 规则,但更匹配 deny 规则里的 aws *,而 deny 优先,所以照样被拦。deny 规则不能有例外,这是设计上的硬规则。
Warning裸工具名做 deny(比如就写个
Bash)会把整个工具从 Claude 的上下文里移除—Claude 压根看不见这个工具。而Bash(rm *)这种带范围的 deny 只是拦匹配的调用,工具还在,Claude 还能跑别的命令。
规则语法长啥样
规则格式就两种:Tool 或 Tool(specifier)。
不带括号,匹配该工具的所有调用:
{
"permissions": {
"allow": ["Bash", "WebFetch", "Read"],
"deny": ["Edit"]
}
}
带括号加说明符,做细粒度控制:
{
"permissions": {
"allow": [
"Bash(npm run build)",
"Read(./.env)",
"WebFetch(domain:example.com)"
]
}
}
Bash(npm run build) 只匹配这一条确切命令,Read(./.env) 只匹配读当前目录的 .env,WebFetch(domain:example.com) 只匹配对这个域名的请求。
通配符:批量放行的利器
Bash 规则支持 * 通配符,能出现在命令的任何位置—开头、中间、结尾都行。
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)",
"Bash(git * main)",
"Bash(* --version)"
],
"deny": [
"Bash(git push *)"
]
}
}
逐条解释:
Bash(npm run *)匹配npm run build、npm run test这些Bash(git commit *)匹配git commit -m "..."这些Bash(git * main)匹配git checkout main、git merge main这些Bash(* --version)匹配任何带--version的命令
通配符前有没有空格,差别很大
这里我踩过坑。* 前面有没有空格,匹配范围完全不同:
Bash(ls *)(有空格)—匹配ls -la,但不匹配lsof。空格强制单词边界。Bash(ls*)(没空格)—ls -la和lsof都匹配。
Tip想放行某个命令带参数,就在命令后面留个空格再写
*:Bash(npm *)。想精确匹配命令名、不误伤别的,也用空格版本。:*是尾通配符的等价写法,Bash(ls:*)和Bash(ls *)一样。
复合命令会拆开看
Claude Code 认识 shell 运算符(&&、||、;、| 这些)。所以 Bash(safe-cmd *) 不会让 Claude 钻空子跑 safe-cmd && rm -rf /—后半段 rm -rf / 不匹配规则,照样被拦。
你点”是,不再询问”批准一条复合命令时,Claude Code 会给每个需要批准的子命令单独存规则。比如批准 git status && npm test,存的是 npm test 这条规则,以后单独跑 npm test 也认。
Note用
--verbose启动能看到每个工具调用里确切的参数名和值,调试权限规则时很有用。
六种权限模式
权限模式决定 Claude 整体上要不要频繁问你。模式是基线,规则是在基线上叠的层—deny 规则和显式 ask 规则在任何模式下都生效。
| 模式 | 不用问就能干啥 | 适合谁 |
|---|---|---|
default | 只读操作 | 入门、敏感工作 |
acceptEdits | 读、改文件、常见文件系统命令 | 迭代审查的代码 |
plan | 只读 | 改之前先摸清代码库 |
auto | 几乎所有操作(有分类器把关) | 长任务、减少提示疲劳 |
dontAsk | 只跑预先批准的工具 | CI、脚本 |
bypassPermissions | 全部 | 仅限隔离容器 |
在 CLI 里,审查每个操作的模式叫 Manual(手动),配置值还是 default,manual 是别名。v2.1.200 起支持别名。
怎么切换模式
会话中途:按 Shift+Tab 循环。默认循环 default -> acceptEdits -> plan。auto 和 bypassPermissions 不在默认循环里,要满足条件才出现。
启动时指定:
claude --permission-mode plan
claude --permission-mode acceptEdits
设为默认:在 settings.json 里写 defaultMode:
{
"permissions": {
"defaultMode": "acceptEdits"
}
}
Note
auto模式只能写在用户设置~/.claude/settings.json或托管设置里,项目里的.claude/settings.json写了会被忽略—防止仓库给自己授权。
default:最稳的手动模式
default 是开箱即用的模式,每个有副作用的操作都问你。状态栏(v2.1.203 起)显示灰色 ⏸ manual mode on 徽章。
适合刚上手、或者做敏感工作时用。慢是慢点,但每一步都在你眼皮底下。
权限提示弹出时,按 Ctrl+E 能看 Claude Code 给这条命令的解释:它干啥、Claude 为啥要跑、可能有啥风险,标成低/中/高风险。这个解释只在按 Ctrl+E 时才发给模型生成,不会每次都消耗 token。
acceptEdits:让 Claude 专心改代码
acceptEdits 让 Claude 在你的工作目录里建文件、改文件,不用每次问。状态栏显示 ⏵⏵ accept edits on。
除了文件编辑,它还自动放行常见的文件系统命令:mkdir、touch、rm、rmdir、mv、cp、sed。带安全环境变量(LANG=C、NO_COLOR=1)或进程包装器(timeout、nice、nohup)前缀的也算。
但有个边界:只在工作目录或 additionalDirectories 范围内。超出范围的路径、受保护路径的写入、其他 Bash 命令,照样问你。
适合你在编辑器里或 git diff 里事后看改动,而不是逐个点批准时用。从 default 按一次 Shift+Tab 就进去了。
plan:只看不动手
plan 模式让 Claude 研究、提议,但不真改。它能读文件、跑只读命令探索,写计划,就是不编辑你的源码。编辑权限被锁死,直到你批准计划。
按 Shift+Tab 进 plan 模式,或者在单条提示前加 /plan:
claude --permission-mode plan
计划做好了,Claude 会问你怎么办。选项有几个:
- 批准并切到 auto 模式开干
- 批准并接受编辑
- 批准并手动审查每个编辑
- 继续规划、给反馈
批准就退出 plan 模式,会话切到对应的权限模式开始改。想再规划,Shift+Tab 循环回去,或下条提示前加 /plan。
Tip按
Ctrl+G能在默认文本编辑器里打开计划,直接改完再让 Claude 继续。批准计划时如果开了showClearContextOnPlanAccept,还能顺手清掉规划阶段的上下文。
auto:分类器帮你把关
auto 模式让 Claude 几乎不用问就能干活,但背后有个独立的分类器模型在每个操作前审查,拦下任何超出你请求范围、针对陌生基础设施、或像被恶意内容驱动的操作。
打个比方:auto 模式像给 Claude 配了个安全员。Claude 想干啥都先跟安全员报备,安全员觉得不靠谱就拦下来,靠谱就放行。你不用每个操作都点头,但危险动作还是会被挡。
auto 模式要满足啥条件
不是谁都能用 auto。得同时满足:
- 账户:所有计划都能用。但 Team 和 Enterprise 上,所有者得在管理员设置里开启。
- 模型:Anthropic API 上要 Opus 4.6+ 或 Sonnet 4.6+;Bedrock、Vertex、Foundry 上只支持 Sonnet 5、Opus 4.7、Opus 4.8。老模型不支持。
- 提供商:Anthropic API、Bedrock、Vertex、Foundry、Claude apps gateway 默认可用。
Warningauto 模式减少提示,但不保证安全。用在信任总体方向的任务上,别拿它当敏感操作审查的替代品。要更硬的安全边界,用
deny规则或bypassPermissions的反面—dontAsk。
分类器默认拦啥、放啥
分类器默认信任你的工作目录和当前仓库的已配置远程。其他都当”外部”对待。
默认拦的典型操作:
- 下载并执行代码,比如
curl | bash - 往外部端点发敏感数据
- 生产部署和迁移
- 云存储上的大规模删除
- 强制推送(force push)
git reset --hard、git checkout -- .、git stash drop这些会丢未提交改动的terraform destroy这类销毁资源的- 写密钥管理器、改 DNS 记录、改 TLS 证书
- 绕过内部包注册表装包到公共源
- 打开隧道或反向 shell 暴露本地服务
默认放的:
- 工作目录里的本地文件操作
- 装锁文件里声明的依赖
- 读
.env并给匹配的 API 发凭证 - 只读 HTTP 请求
- 推到你启动的分支或 Claude 创建的分支
- 例行推送到默认分支(v2.1.203 起)
跑 claude auto-mode defaults 能看完整规则列表。
分类器连续拦几次会回退
如果分类器连续 3 次或总共 20 次拦操作,auto 模式会暂停,Claude Code 退回到问你。你批准一次,auto 模式恢复。这俩阈值不能改。
每次允许的操作会重置连续计数器,但总计数器在整个会话里持续,只有它自己触顶才重置。
在非交互模式(-p)里,重复拦截会直接中止会话,因为没人能点头。重复拦截通常说明分类器缺你基础设施的上下文—该配受信任基础设施了。
配置自动模式:告诉分类器你信任谁
默认分类器只信任工作目录和当前仓库的远程。推到你公司的代码库、写团队云存储桶这些,都会被拦。得在 autoMode.environment 里告诉它哪些是”自己人”。
受信任基础设施怎么写
environment 是个字符串数组,用自然语言写,不是正则也不是工具模式。分类器当自然语言规则读。按你给新同事介绍基础设施的方式来写:
{
"autoMode": {
"environment": [
"$defaults",
"Source control: github.example.com/acme-corp and all repos under it",
"Trusted cloud buckets: s3://acme-build-artifacts, gs://acme-ml-datasets",
"Trusted internal domains: *.corp.example.com, api.internal.example.com",
"Key internal services: Jenkins at ci.example.com, Artifactory at artifacts.example.com"
]
}
}
$defaults 是个字面字符串,写进数组里会把默认条目拼接到那个位置。你的自定义条目可以在默认之前或之后。
一个全面的 environment 该覆盖:
- 组织:公司名 + Claude Code 主要用途(软件开发、基础设施自动化等)
- 源代码控制:开发者推送到的 GitHub、GitLab、Bitbucket 组织
- 云提供商和受信任存储桶:Claude 该能读写的桶名
- 受信任内部域:内网 API、仪表板的主机名
- 关键内部服务:CI、工件注册表、内部包索引
- 内部包注册表:私有 npm/PyPI,装包该走它
- 敏感数据位置:存个人数据、机密数据的桶、库、路径
- 敏感远程目标:算生产的命名空间、主机,远程 shell 要你批准
- 受保护的 IaC 范围:应用或销毁必须你点名的资源
Tip不用一次填全。合理路径:先加默认值 + 源代码控制组织和关键内部服务(解决最常见的误报),再加受信任域和云桶,等出现拦截了再补。
分类器从哪读配置
分类器读 autoMode 的范围有讲究:
| 范围 | 文件 | 用途 |
|---|---|---|
| 单个开发者 | ~/.claude/settings.json | 个人受信任基础设施 |
| 组织范围 | 托管设置 | 分发给所有人的受信任基础设施 |
--settings 标志 / SDK | 内联 JSON | 自动化的每次调用覆盖 |
注意:分类器不从 .claude/settings.json 或 .claude/settings.local.json 读 autoMode。这俩在仓库目录里,签入的仓库或构建步骤可能注入自己的允许规则。所以 autoMode 必须放用户设置或托管设置里。
覆盖默认的拦放规则
默认规则不合你管道时,有三个字段能替换:
hard_deny:无条件安全边界,用户意图和 allow 例外都不管用soft_deny:用户意图能清除的破坏性操作allow:软阻止规则的例外
优先级是四层:hard_deny > soft_deny > allow > 明确用户意图。hard_deny 谁都覆盖不了;soft_deny 能被 allow 或你消息里明确说”就这么干”清除。
{
"autoMode": {
"allow": [
"$defaults",
"Deploying to the staging namespace is allowed: staging is isolated from production"
],
"soft_deny": [
"$defaults",
"Never run database migrations outside the migrations CLI"
],
"hard_deny": [
"$defaults",
"Never send repository contents to third-party code-review APIs"
]
}
}
Note必须永远不能跑的操作,不管用户意图或分类器配置,用
permissions.deny(在分类器之前拦),别用autoMode.hard_deny。
dontAsk:只跑预先批准的
dontAsk 模式自动拒绝所有原本会提示的工具调用。Claude 只跑匹配 permissions.allow 规则的操作、内置只读 Bash 命令、以及 PreToolUse hook 批准的调用。
状态栏显示 ⏵⏵ don't ask on。会话永远不等你输入,适合 CI 管道或受限环境,你预先定义好能干啥就行。
它连你显式的 ask 规则都拒绝(不是提示),内置的 AskUserQuestion 工具、组织设为 ask 的连接器工具、标记 requiresUserInteraction 的 MCP 工具,统统拒。
claude --permission-mode dontAsk
bypassPermissions:跳过一切
bypassPermissions 禁用权限提示和安全检查,工具调用立即执行,包括写受保护路径。只有显式 ask 规则、组织设为 ask 的连接器工具、requiresUserInteraction 的 MCP 工具还会提示。
针对文件系统根或主目录的删除(rm -rf /、rm -rf ~)会作为断路器提示—防模型犯傻。v2.1.208 起,命令里带 $(...) 或反引号的命令替换、<(...) 进程替换,也会触发断路器。
Warning只在隔离环境(容器、虚拟机、没网的开发容器)里用这个模式,Claude Code 损不了你主机。Linux/macOS 上以 root 或 sudo 跑会直接拒绝启动。要更好的方案—有安全检查但提示少—用 auto 模式。
得用启用标志启动才能进这模式:
claude --permission-mode bypassPermissions
# 等效的旧写法
claude --dangerously-skip-permissions
管理员能在托管设置里把 permissions.disableBypassPermissionsMode 设成 "disable" 来禁用这模式,同样能禁用 auto(permissions.disableAutoMode)。
受保护路径:任何模式都护着的
不管哪种模式(除了 bypassPermissions),对一小撮路径的写入永远不会自动批准。这防的是误伤仓库状态和 Claude 自己的配置。
| 模式 | 受保护路径写入怎么处理 |
|---|---|
default、acceptEdits、plan | 提示你 |
auto | 路由到分类器 |
dontAsk | 拒绝 |
bypassPermissions | 允许 |
受保护的目录:.git、.config/git、.vscode、.idea、.husky、.cargo、.devcontainer、.yarn、.mvn、.claude(.claude/worktrees 例外,那是 Claude 自己存 git worktree 的地方)。
受保护的文件:.gitconfig、.gitmodules、.bashrc、.zshrc、.profile、.envrc、.npmrc、.yarnrc、.mcp.json、.claude.json 这些 shell 配置、包管理配置、Claude 自己的配置文件。
Note设置文件里的
permissions.allow规则不会预先批准受保护路径的写入。安全检查在 Claude Code 评估允许规则之前就跑了,所以写Edit(.claude/**)也改不了上面的行为。
用 /permissions 管理规则
在会话里输入 /permissions 能看和管理所有权限规则,还会标出每条规则来自哪个 settings.json 文件。
你能在里面加规则、删规则、看最近被拒的操作(按 r 能用手动批准重试)。
Tip调试权限问题,先用
/permissions看当前生效的规则全集。规则来自哪个文件一目了然,省得你到处翻配置。
模式和规则怎么配合
记住这个层次:
- 模式定基线—整体严还是松
- deny 规则在任何模式都拦(包括 bypassPermissions)
- 显式 ask 规则在任何模式都提示(包括 auto 和 bypassPermissions)
- allow 规则在模式基线上额外放行
典型搭配:
- 日常写代码:
acceptEdits+ allow 常用命令 + deny 危险命令 - CI 自动化:
dontAsk+ 精确的 allow 规则 - 长任务放手干:
auto+ 配好autoMode.environment+ 关键操作加 ask - 探索代码库:
plan摸清了再切acceptEdits干
权限不是越松越好,也不是越严越安全。关键是让 Claude 该自动的自动、该拦的拦住,你把精力放在真正需要过目的操作上。