GuidesAI 编程
为 Claude Code 配置安全的权限模式
用 defaultMode 与 allow/ask/deny 规则,给 Claude Code 配一套可提交版本库的安全权限策略。
基于 Claude Code Docs 整理 · 官方资料 ↗
Claude Code 能读文件、改文件、跑 shell。安全边界不靠模型“自觉”,而靠 Claude Code 强制执行的权限系统:模式决定默认态度,规则决定具体工具与路径。
官方 permissions 文档覆盖分级权限、defaultMode、规则语法,以及与 hooks、sandbox 的关系。这篇把它收成可落地的配置路径:先选模式,再写 deny/ask/allow,最后用 /permissions 核对。
目标不是“全部放开图快”,而是让日常只读顺畅、写文件与危险命令可控,并把团队策略写进仓库。
默认分级:读、改、跑命令
只读工具(工作目录内读文件、Grep 等)通常不提示。Bash 默认需要批准(内置只读命令除外)。Edit/Write 也需要批准;“Yes, don't ask again” 对文件修改通常只持续到会话结束,对 Bash 则可永久写入本地规则。
规则求值顺序是 deny → ask → allow,命中即停。更具体的 allow 不能盖过更宽的 deny。例如 Bash(aws *) 的 deny 会挡住所有匹配,包括你以为例外的 aws s3 ls。
CLAUDE.md 里的叮嘱只影响模型倾向,不改变 Claude Code 允许什么。要真正授权或禁止,用 /permissions、settings 规则、permission mode 或 PreToolUse hook。
先选 defaultMode
在 settings 里设置 permissions.defaultMode(VS Code 扩展启动的会话由扩展解析起始模式)。常用模式:
- default(界面也称 Manual):首次使用工具时询问
- acceptEdits:自动接受工作目录内的文件编辑与常见文件系统命令
- plan:只读探索,不改源码
- auto:自动批准,但有后台安全检查
- dontAsk:未预批规则一律拒绝
- bypassPermissions:跳过提示(仅建议在隔离容器/VM;对 .git / .claude 等受控路径也跳过提示)
本地日常开发优先 default 或 acceptEdits。不要把 bypassPermissions 当默认生产力设置。可用 permissions.disableBypassPermissionsMode 或 disableAutoMode 禁止危险模式,尤其适合托管策略。
写 allow / ask / deny 规则
规则形如 Tool 或 Tool(specifier)。裸 Bash 匹配所有 Bash;Bash(npm run build) 匹配精确命令;Bash(npm run *) 用通配符。Read / Edit 用路径模式;WebFetch 用 domain:host。
官方示例:允许 npm/git commit,拒绝 git push
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)",
"Bash(git * main)",
"Bash(* --version)",
"Bash(* --help *)"
],
"deny": [
"Bash(git push *)"
]
}
}拒绝读取 .env,并拒绝 Explore 子代理
{
"permissions": {
"deny": [
"Read(.env)",
"Read(**/.env)",
"Agent(Explore)"
],
"ask": [
"Bash(git push *)",
"WebFetch"
]
}
}对文件路径,用 Edit(...) / Read(...),不要写 Write(docs/**) 这种不会被文件权限检查咨询的规则。复合 Bash 命令会按子命令分别匹配;Bash(safe *) 不会自动放行 safe && other。
项目配置与本机配置怎么分工
- .claude/settings.json:团队共享策略(可提交)
- .claude/settings.local.json:个人本机覆盖(常被 gitignore)
- ~/.claude/settings.json:跨项目个人默认
- managed settings:组织强制策略,用户无法用更松的规则覆盖 deny
项目里的 permissions.allow 与 additionalDirectories 属于“授予能力”,需先通过该工作区的 trust 对话框才会生效;deny / ask 不受影响。用 /permissions 可查看规则及来源文件。
一份偏安全的项目起点(示例组合)
{
"permissions": {
"defaultMode": "default",
"allow": [
"Bash(npm test *)",
"Bash(npm run lint *)"
],
"ask": [
"Bash(git push *)",
"Bash(npm publish *)"
],
"deny": [
"Read(.env)",
"Read(**/.env)",
"Bash(rm -rf *)",
"WebFetch(domain:*)"
]
}
}上面的 WebFetch(domain:*) deny 只是“默认禁止联网抓取”的示意;若你需要文档网站,改成按域名放行,例如 WebFetch(domain:docs.example.com)。
和 hooks、sandbox 怎么配合
PreToolUse hook 可在运行时追加拒绝或强制询问,但不能绕过已有 deny/ask 规则:匹配的 deny 仍会拦,匹配的 ask 仍会问。exit 2 的阻断甚至会优先于 allow。
Sandbox 从 OS 层限制 Bash 的文件系统与网络;permissions 决定模型侧能尝试什么。两者叠加才是纵深防御。不要用“只开 bypassPermissions”代替 sandbox 与 deny 规则。
如何验收配置
- 运行 /permissions,确认规则与来源文件正确
- 试一次被 deny 的操作(如读 .env 或 git push),应被拒绝或强制询问
- 试一次 allow 的只读/测试命令,应减少不必要打断
- 确认 defaultMode 不是误开的 bypassPermissions
官方仓库提供 settings 示例目录,可作起点再按团队风险收紧。策略变更后开一个新会话再测,避免旧会话残留的临时批准干扰判断。
最容易踩的坑
写了 allow 却仍被拦
先查是否存在匹配的 deny/ask;再确认项目 allow 是否尚未通过 workspace trust。deny 优先于 allow。
Write(path) 规则看起来没生效
文件权限检查认 Edit(path) / Read(path)。把 Write(...) 改成 Edit(...)。
Bash(curl http://github.com/*) 防不住变形命令
官方提醒参数级 Bash 限制很脆弱。更稳妥:deny curl/wget,再用 WebFetch(domain:...) 放行域名,或加 PreToolUse 校验。
误开 bypassPermissions
立刻改回 default/acceptEdits,并考虑设置 disableBypassPermissionsMode。该模式会跳过大量提示,只适合隔离环境。
官方资料
Claude Code Docs
Configure permissions ↗