主题
Permissions(权限)
通过 allow/ask/deny 规则、权限模式和托管策略,细粒度控制 Claude Code 能用哪些工具、能访问哪些文件和域名。
权限求值器(交互)
输入一条命令、选权限模式,立刻看到 Claude Code 在你的设置下会怎么处理它:逐子命令判定、命中哪条规则、最终后果。开局即为你们真实配置(bypassPermissions + 红线 deny),规则可改。
规则(deny → ask → allow,可编辑)
在 Claude Code 里:被拒绝,不会执行。
| 子命令 | 判定 | 命中规则 / 原因 |
|---|---|---|
git commit -m "fix login" | 询问 | ask: Bash(git commit *)ask 命中,会请求确认 |
git push origin main | 拒绝 | deny: Bash(git push *)deny 命中(deny 优先级最高,压过 allow) |
教学用简化匹配:* 通配,' *'(带空格)/ :* 要求词边界;自动剥离 timeout/nice/nohup/stdbuf/裸 xargs;放行 ls/cat/grep 等只读命令。判定铁律 deny 优先于 ask 优先于 allow,第一条命中即生效。
你的真实配置
你的权限设置分两处:
全局 ~/.claude/settings.json:
json
{ "permissions": { "defaultMode": "bypassPermissions" }, "skipDangerousModePermissionPrompt": true }你默认跳过所有权限弹窗。好处是顺;代价是权限这道闸基本不拦你,安全主要靠 deny 规则加 hook(见 Hooks 节)。
项目 .claude/settings.local.json:
json
{ "permissions": { "allow": [
"WebFetch(domain:gitee.com)",
"Bash(pip list *)",
"Bash(xargs cat)"
] } }这几条是你为本项目放行的(gitee 文档、pip list、xargs cat)。注意:在 bypassPermissions 下这些 allow 其实可有可无(反正都不弹);它们真正有用的场景是你把 defaultMode 调回 default 或 acceptEdits 时。
去真实体验
| 想验证什么 | 这样做 |
|---|---|
| 看当前全部规则及来源 settings 文件 | 输入 /permissions |
| 临时收紧(不想全程裸奔) | claude --permission-mode default 起一个会话 |
| 给某域名/命令放行 | /permissions 里加,或写进 .claude/settings.local.json |
针对你的 bypassPermissions 的建议
你用了 bypassPermissions,但 CLAUDE.md 又列了一串"必须先确认"的红线(git push、rm -rf、改 AGENTS.md、改 SpringBlade 启动配置)。在 bypass 下这些靠权限拦不住。两个补救:
- 加 deny 规则:哪怕 bypass,
deny仍然生效。把红线写成 deny:json{ "permissions": { "deny": ["Bash(git push *)", "Bash(rm -rf *)", "Read(./SpringBlade_GKX_Base/**/application*.yml)"] } } - 加 PreToolUse hook(更灵活,能拦复合命令、能给原因)——见 Hooks 节的
guard.sh。
求值铁律:
deny永远压过allow;任意层级 deny 命中,其它层级都 allow 不回来。managed 设置的 deny 连命令行都覆盖不了。
官方文档要点
以下为按官方文档整理的系统性参考。
是什么
Permissions 是 Claude Code 的分层权限系统,用来精确指定 agent 被允许做什么、不被允许做什么。规则可以签入版本控制并分发给组织内所有开发者,也能被单个开发者自定义。权限规则由 Claude Code(而非模型)强制执行——prompt 或 CLAUDE.md 只能影响 Claude "想做什么",不能改变 Claude Code "允许什么"。它和 Sandboxing(OS 级隔离)是互补的两层安全。
怎么工作
- 三类工具分层:只读(文件读取、Grep)不需批准;Bash 命令需批准,选"Yes, don't ask again"后按项目目录+命令永久记住;文件修改(Edit/write)需批准,但记住只到 session 结束。
- 规则求值顺序固定为 deny -> ask -> allow,第一条匹配的规则生效,所以 deny 永远优先。
- deny 规则有两种行为:裸工具名如 Bash 会把整个工具从 Claude 的上下文里移除(Claude 根本看不到它);带 specifier 的如 Bash(rm *) 保留工具,仅在调用匹配时阻止。
- 规则格式为 Tool 或 Tool(specifier)。裸工具名匹配该工具所有用法;Bash(*) 等价于 Bash。
- Bash 通配符 * 可出现在命令任意位置;命令末尾带空格的 * 强制词边界——Bash(ls ) 匹配 ls -la 但不匹配 lsof,Bash(ls) 两者都匹配;😗 后缀等价于结尾的 ' *',只在模式末尾被识别。
- Bash 能识别 shell 操作符:复合命令的每个子命令必须各自被规则匹配才放行;识别的分隔符是 && || ; | |& & 和换行。批准复合命令时会为每个需批准的子命令分别存规则,单条复合命令最多存 5 条规则。
- Bash 匹配前会剥离固定的进程包装器 timeout/time/nice/nohup/stdbuf,以及无 flag 的裸 xargs;这个列表内置不可配置。
- Bash 内置一组只读命令(ls/cat/echo/pwd/head/tail/grep/find/wc/which/diff/stat/du/cd 及只读形式的 git),任何模式下都不弹窗,不可配置。
- Read/Edit 路径模式遵循 gitignore 规范,分四种锚点:// 绝对路径、~/ 家目录、/ 项目根相对、path 或 ./path 当前目录相对;* 匹配单层目录,** 跨目录递归。
- 符号链接会同时检查 symlink 本身和解析后的目标:allow 规则需两者都匹配否则降级为弹窗;deny 规则只要任一匹配就阻止。
- PreToolUse hook 在权限弹窗前运行,可 deny/force prompt/skip;但 hook 决定不能绕过 deny 和 ask 规则,exit code 2 的阻塞型 hook 优先于 allow 规则。
怎么配置 / 用法
用 /permissions 命令查看和管理所有规则及其来源 settings.json 文件。规则写在 settings 文件的 permissions 对象下的 allow / ask / deny 数组里,并通过 defaultMode 设置默认权限模式。settings 文件优先级(高到低):Managed settings > 命令行参数 > .claude/settings.local.json > .claude/settings.json > ~/.claude/settings.json。示例:
json
{
"permissions": {
"allow": ["Bash(npm run *)", "Bash(git commit *)", "Bash(git * main)"],
"deny": ["Bash(git push *)", "Read(.env)", "Agent(Explore)"]
}
}扩展工作目录:启动用 --add-dir <path>,session 中用 /add-dir,持久化用 settings 里的 additionalDirectories。CLI 还可用 --allowedTools / --disallowedTools 临时覆盖。
什么时候用
- 何时用 allow:把高频且安全的命令/工具加入允许列表,免去反复弹窗(如 Bash(npm run *)、WebFetch(domain:example.com))。
- 何时用 deny:阻止危险操作或保护敏感文件(如 Bash(git push *)、Read(.env)、Read(~/.ssh/**));裸工具名 deny 可彻底隐藏某工具。
- 何时用 ask:希望某工具每次使用都确认。
- 何时用 plan 模式:只想让 Claude 探索代码、读文件、跑只读命令,不改源文件。
- 何时用 acceptEdits:信任的本地环境里自动接受文件编辑和常见 fs 命令。
- 何时别用 bypassPermissions:仅在容器/VM 等隔离环境用,普通开发机绝不要用。
- URL 过滤别只靠 Bash 参数约束(如 Bash(curl http://github.com/ *))——很脆弱;改用 deny 封掉 curl/wget + WebFetch(domain:...) 白名单,或用 PreToolUse hook。
限制 / 坑
- 权限由 Claude Code 强制执行,不是模型;prompt 和 CLAUDE.md 改不了允许边界。
- Read/Edit deny 规则只覆盖内置文件工具和 Claude Code 能识别的 Bash 文件命令(cat/head/tail/sed);不覆盖间接读写文件的子进程(如 Python/Node 脚本)——要 OS 级封堵须启用 sandbox。
- Bash 参数约束模式很脆弱:选项位置、协议差异、重定向、变量、多余空格都能绕过(curl 例子)。
- 进程包装器剥离列表内置不可配置;direnv exec/devbox run/mise exec/npx/docker exec 等环境 runner 不在列表里,Bash(devbox run *) 会匹配 run 后面的任意命令包括 devbox run rm -rf .,须为每个内部命令写精确规则。
- exec 包装器 watch/setsid/ionice/flock 始终弹窗,无法被 Bash(watch *) 这类前缀规则自动批准;find -exec / -delete 同理,Bash(find *) 不覆盖。
- 复合命令单条最多存 5 条规则。
- 😗 只在模式末尾识别;Bash(git:* push) 里冒号被当字面字符,不匹配 git 命令。
- additionalDirectories(settings 里的)只授予文件访问,不加载该目录的 .claude/ 配置;只有 --add-dir / /add-dir 才会加载部分配置(skills、部分 plugin 设置、需 env 开启的 CLAUDE.md)。
- 形如 /Users/alice/file 不是绝对路径,而是项目根相对;绝对路径要写 //Users/alice/file。
- bypassPermissions 仍会对 rm -rf / 和 rm -rf ~ 弹窗作为熔断;管理员可用 permissions.disableBypassPermissionsMode 设为 disable 禁用该模式。
- deny 在任何层级生效后,其他层级都无法 allow;managed settings 的 deny 连命令行参数都覆盖不了。
硬事实速查(30 条)
- 管理命令:/permissions(查看/管理规则,显示来源 settings.json)
- 三个规则数组:permissions.allow / permissions.ask / permissions.deny
- 求值顺序:deny -> ask -> allow,第一条匹配生效
- 规则格式:Tool 或 Tool(specifier);Bash(*) 等价于 Bash
- 权限模式(defaultMode 取值):default / acceptEdits / plan / auto(research preview)/ dontAsk / bypassPermissions
- acceptEdits 自动接受文件编辑和常见 fs 命令 mkdir/touch/mv/cp 等(限工作目录或 additionalDirectories 内路径)
- dontAsk:自动拒绝未经 /permissions 或 permissions.allow 预批准的工具
- bypassPermissions:跳过所有弹窗,但 rm -rf / 和 rm -rf ~ 仍弹窗;受保护目录写入仍拦:.git/.claude/.vscode/.idea/.husky/.cargo
- 禁用模式:permissions.disableBypassPermissionsMode、permissions.disableAutoMode 设为 "disable"
- Bash 通配符:* 可在任意位置;Bash(ls ) 匹配 ls -la 不匹配 lsof;Bash(ls) 两者都匹配;😗 后缀等价结尾 ' *'
- Bash 复合命令分隔符:&& || ; | |& & 和换行;单条复合命令最多存 5 条规则
- 剥离的进程包装器(内置不可配置):timeout、time、nice、nohup、stdbuf,以及无 flag 的 xargs
- 始终弹窗的 exec 包装器:watch、setsid、ionice、flock;find -exec / -delete 也不被 Bash(find *) 覆盖
- 内置只读 Bash 命令:ls cat echo pwd head tail grep find wc which diff stat du cd 及只读形式 git(不可配置)
- Read/Edit 四种 gitignore 锚点://path 绝对、~/path 家目录、/path 项目根相对、path 或 ./path 当前目录相对
- 示例:Read(//Users/alice/secrets/)、Read(~/Documents/*.pdf)、Edit(/src//.ts)、Read(.env)
- Read(.env) 等价 Read(/.env);* 匹配单层、 递归
- Windows 路径归一化为 POSIX:C:\Users\alice -> /c/Users/alice,跨盘用 //**/.env
- WebFetch 规则:WebFetch(domain:example.com)
- MCP 规则:mcp__puppeteer(整个 server)、mcp__puppeteer__*(通配全部工具)、mcp__puppeteer__puppeteer_navigate(单个工具)
- Agent 规则:Agent(Explore)、Agent(Plan)、Agent(my-custom-agent);可用 --disallowedTools 禁用
- PowerShell 规则:与 Bash 同形,PowerShell(Get-ChildItem )、: 后缀等价;别名 gci/ls/dir 会被规范化匹配;大小写不敏感;7+ 支持 && ||
- 工作目录扩展:--add-dir <path>(启动)、/add-dir(session)、additionalDirectories(持久化 settings)
- settings 优先级(高到低):Managed settings > 命令行参数 > .claude/settings.local.json > .claude/settings.json > ~/.claude/settings.json
- CLI 标志:--allowedTools、--disallowedTools
- Managed-only 设置示例:allowManagedPermissionRulesOnly、allowManagedMcpServersOnly、allowManagedHooksOnly、strictPluginOnlyCustomization、forceRemoteSettingsRefresh。注:disableBypassPermissionsMode 不是 managed-only,可在任意 scope 设置(用户也能在自己的设置里把自己锁出 bypass 模式)
- env 变量:CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1(让 --add-dir 目录加载 CLAUDE.md)
- sandbox 默认 autoAllowBashIfSandboxed: true,沙箱内 Bash 即使有 ask: Bash(*) 也不弹窗,但 deny 和 rm 关键路径仍生效
- 符号链接检查 symlink 路径与解析目标两条路径;allow 需双匹配,deny 任一匹配即拦
- PreToolUse hook:exit code 2 阻塞优先于 allow;hook 不能绕过 deny/ask