TodayAI

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

json
{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git commit *)",
      "Bash(git * main)",
      "Bash(* --version)",
      "Bash(* --help *)"
    ],
    "deny": [
      "Bash(git push *)"
    ]
  }
}

拒绝读取 .env,并拒绝 Explore 子代理

json
{
  "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 可查看规则及来源文件。

一份偏安全的项目起点(示例组合)

json
{
  "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