首页 / Claude Code 入门教程 / 权限与模式

Claude Code 入门教程

权限与模式

本教程共 34 篇 · 第 17 篇 · 更新于 2026-07-26 · 约 8 分钟阅读

Claude CodeClaude Code 入门教程权限权限模式auto模式权限规则

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 还能跑别的命令。

规则语法长啥样

规则格式就两种:ToolTool(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) 只匹配读当前目录的 .envWebFetch(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 buildnpm run test 这些
  • Bash(git commit *) 匹配 git commit -m "..." 这些
  • Bash(git * main) 匹配 git checkout maingit merge main 这些
  • Bash(* --version) 匹配任何带 --version 的命令

通配符前有没有空格,差别很大

这里我踩过坑。* 前面有没有空格,匹配范围完全不同:

  • Bash(ls *)(有空格)—匹配 ls -la,但不匹配 lsof。空格强制单词边界。
  • Bash(ls*)(没空格)—ls -lalsof 都匹配。
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(手动),配置值还是 defaultmanual 是别名。v2.1.200 起支持别名。

怎么切换模式

会话中途:按 Shift+Tab 循环。默认循环 default -> acceptEdits -> planautobypassPermissions 不在默认循环里,要满足条件才出现。

启动时指定

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

除了文件编辑,它还自动放行常见的文件系统命令:mkdirtouchrmrmdirmvcpsed。带安全环境变量(LANG=CNO_COLOR=1)或进程包装器(timeoutnicenohup)前缀的也算。

但有个边界:只在工作目录或 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 默认可用。
Warning

auto 模式减少提示,但不保证安全。用在信任总体方向的任务上,别拿它当敏感操作审查的替代品。要更硬的安全边界,用 deny 规则或 bypassPermissions 的反面—dontAsk

分类器默认拦啥、放啥

分类器默认信任你的工作目录和当前仓库的已配置远程。其他都当”外部”对待。

默认拦的典型操作:

  • 下载并执行代码,比如 curl | bash
  • 往外部端点发敏感数据
  • 生产部署和迁移
  • 云存储上的大规模删除
  • 强制推送(force push)
  • git reset --hardgit 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.jsonautoMode。这俩在仓库目录里,签入的仓库或构建步骤可能注入自己的允许规则。所以 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 自己的配置。

模式受保护路径写入怎么处理
defaultacceptEditsplan提示你
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 看当前生效的规则全集。规则来自哪个文件一目了然,省得你到处翻配置。

模式和规则怎么配合

记住这个层次:

  1. 模式定基线—整体严还是松
  2. deny 规则在任何模式都拦(包括 bypassPermissions)
  3. 显式 ask 规则在任何模式都提示(包括 auto 和 bypassPermissions)
  4. allow 规则在模式基线上额外放行

典型搭配:

  • 日常写代码:acceptEdits + allow 常用命令 + deny 危险命令
  • CI 自动化:dontAsk + 精确的 allow 规则
  • 长任务放手干:auto + 配好 autoMode.environment + 关键操作加 ask
  • 探索代码库:plan 摸清了再切 acceptEdits

权限不是越松越好,也不是越严越安全。关键是让 Claude 该自动的自动、该拦的拦住,你把精力放在真正需要过目的操作上。