← 所有文章

别让 Claude Code 误删代码:这 5 层安全护栏必须配好

Claude Code 一旦拿到文件修改、命令执行和 Git 操作权限,效率会大幅提升,风险也会同步放大

图1

Claude Code 一旦拿到文件修改、命令执行和 Git 操作权限,效率会大幅提升,风险也会同步放大。一条错误的 rm、一次误触发的数据库重置,或一次绕过检查的强制推送,都可能造成难以挽回的损失。

只靠提示词告诉它“不要执行危险操作”远远不够。真正可靠的方案,需要从执行环境、原生权限、动态 Hook、工程规则到远程仓库,建立一套层层兜底的安全机制。

本文将拆解 Claude Code 的 5 层安全护栏,并给出可直接落地的 deny、ask、allow 配置与命令分级清单,让 Agent 在安全边界内尽可能自主执行。

三层硬防线(沙箱 → 权限规则 → PreToolUse Hook),加两层软护栏(工程规则 → 远程门禁),以下从强到弱排列。

图2

第一层:OS 沙箱与凭据隔离

最底层。限制文件系统、网络、密钥和执行环境。Claude Code 原生支持 sandbox.filesystem,作用于所有子进程(kubectl、terraform、npm 等),不是只拦 Claude 自己的工具调用。

{
  "permissions": {
    "deny": [
      "Bash(rm -rf /:*)",
      "Bash(git push --force:*)",
      "Bash(git reset --hard:*)",
      "Bash(prisma migrate reset:*)",
      "Bash(terraform apply:*)",
      "Bash(cdk destroy:*)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Edit(./.env)",
      "Edit(./.env.*)",
      "Bash(cat .env:*)",
      "Bash(git commit --no-verify:*)",
      "Bash(git push --no-verify:*)"
    ]
  }
}

这层搞定了,后面几层才有意义。

风险级别 示例 处理方式
只读 git status, git diff, git log, grep, find, rg allow
本地可逆 git add, git checkout -b, 格式化, 测试, 构建 allow(可信仓库内)
远程副作用 git push, gh pr create, gh workflow run ask
强制拒绝 force push 受保护分支, rm -rf /, 销毁基础设施, 重置数据库 deny

第二层:原生权限规则 — deny / ask / allow

最可靠的命令控制层。Claude Code 原生权限系统,匹配顺序是 deny → ask → allow。

直接封死(deny)

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Destructive command blocked."
  }
}

需要确认(ask)

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|Read|Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash scripts/protect-files.sh"
          }
        ]
      }
    ]
  }
}

直接放行(allow)

{
  "permissions": {
    "ask": [
      "Bash(git push:*)",
      "Bash(gh pr create:*)",
      "Bash(gh workflow run:*)"
    ]
  }
}

原生权限是真正的硬边界,优先于 Hook。Hook 适合需要动态上下文判断的策略,不适合当唯一防线。

第三层:PreToolUse Hook — 动态策略

原生权限处理「固定规则」,Hook 处理「要看上下文才知道」的判断——比如当前分支、目标 ref、命令参数组合。

脚本(共用核心)

关键修正:matcher 必须覆盖 Bash|Read|Edit|Write,只匹配 Bash 拦不住文件工具。

#!/bin/bash
# scripts/protect-files.sh
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

# 任何工具都不能碰 .env
if echo "<equation>FILE_PATH" | grep -q '\.env</equation>'; then
  echo "Blocked: .env files are protected" >&2
  exit 2
fi

# 危险命令(按需扩展,这是示例不是完整清单)
DANGEROUS=("rm -rf /" "git push --force" "git reset --hard" "prisma migrate reset")
for d in "${DANGEROUS[@]}"; do
  if echo "$COMMAND" | grep -qF "$d"; then
    echo "Blocked: dangerous command '$d'" >&2
    exit 2
  fi
done

exit 0

固定字符串匹配容易被绕过(rm -r -f /、git push -f、bash -c ‘…’ 等)。Hook 是策略辅助,不是安全沙箱。强约束放原生 deny。

Claude Code 配置 — .claude/settings.json

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash scripts/protect-files.sh",
            "statusMessage": "Checking command safety...",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Claude Code 的 PreToolUse 支持通过 JSON 返回 permissionDecision: “allow” | “deny” | “ask”。exit code 2 等效 deny。ask 会弹出确认框。

Codex 配置 — .codex/hooks.json

{
  "permissions": {
    "allow": [
      "Read(*)",
      "Bash(git status:*)",
      "Bash(git diff:*)",
      "Bash(git log:*)",
      "Bash(npm run lint:*)",
      "Bash(npm run test:*)",
      "Bash(grep:*)",
      "Bash(find:*)",
      "Bash(rg:*)"
    ]
  }
}
能力 Claude Code Codex CLI
项目 Hook 配置 .claude/settings.json .codex/hooks.json 或 config.toml
用户级配置 ~/.claude/settings.json ~/.codex/hooks.json 或 config.toml
PreToolUse exit 2 阻止调用 阻止调用
JSON deny permissionDecision: "deny" permissionDecision: "deny"
强制人工确认 ✅ permissions.ask + PreToolUse ask ❌ PreToolUse ask 尚不支持
审批请求 Hook PermissionRequest PermissionRequest
项目配置加载 按作用域自动加载 .codex/ 需被信任后才加载

Codex 的 PreToolUse 支持通过 JSON 返回:

{
  "sandbox": {
    "filesystem": {
      "deny": ["~/.ssh", "~/.aws", "/etc"]
    }
  }
}

也兼容旧格式 {“decision”: “block”, “reason”: “…”}。exit code 2 同样生效。但 permissionDecision: “ask” 当前尚不支持——返回后会标记 Hook 失败并继续执行。

Hooks配置参考文章

第四层:工程规则 — CLAUDE.md / .claude/rules/

权限防灾难,规则防技术债。

.claude/rules/ 下每条一句:

.claude/rules/
  global.md       # 跨项目通用
  backend.md      # 后端约束
  frontend.md     # 前端约束

示例:

禁止内联 Validation Schema,统一放 types/ 目录

禁止跨 domain 建依赖

认证逻辑只读,不准重新设计

写新函数前先搜 shared packages

保护 .husky/ 和相关配置文件,不准改

可参考文章

第五层:远程门禁 — CI + 分支保护

本地 Hook 和 Agent 护栏只是第一道防线。下面这些才是最终控制点。

Husky(本地质量门禁,可绕过)

# .husky/commit-msg — 常规路径强制格式
npx commitlint --edit $1

# .husky/pre-push — 常规路径跑检查
npm run lint && npm run test

Husky 可以通过以下方式绕过:git commit –no-verify、git push –no-verify、HUSKY=0 git commit、git -c core.hooksPath=/dev/null commit。

所以必须配合:

原生权限封禁 –no-verify 参数

远程 CI 重新跑 lint + test

分支保护要求 CI 必须通过

远程仓库策略(不可绕过)

GitHub/GitLab branch protection:

  • 禁止 force push

  • 要求 PR review

  • 要求 CI status checks 通过

  • 禁止直接 push main

「feature 分支可以 push,main 不行」这条策略,靠的是远程分支保护规则,不是本地 Agent 配置。

命令风险分级速查

git add 修改 index、git checkout -b 创建分支、gh pr create 创建远程 PR——都不是只读操作,不能放进无脑放行清单。

双工具适配:Claude Code + Codex 共用

Bash 命令检测的核心脚本可以复用。两边 PreToolUse Command Hook 都从 stdin 收 JSON,exit code 2 都能阻止调用。

落地建议

project/
├── scripts/
│   └── protect-files.sh    # 共用核心逻辑
├── .claude/
│   └── settings.json       # matcher: Bash|Read|Edit|Write
└── .codex/
    └── hooks.json          # matcher: Bash

Deny List 和 Allow List 保持一致,但分别维护薄适配层。不要假设两边所有 Hook 事件和决策字段长期保持完全兼容。

怎么起步

先配原生 permissions.deny,覆盖最危险的操作

加 permissions.ask,覆盖需要确认的远程副作用操作

加 permissions.allow,放行只读和本地可逆操作

用 PreToolUse Hook 补动态判断(分支检测、参数组合等)

工程规则放 CLAUDE.md / rules

远程 CI 和分支保护做最终兜底

更多文章推荐阅读

Claude Code 高阶用法:10 个插件搭起完整开发工作流

如何用 5 个工具 + 自定义 Hooks 把 Claude Code Token 消耗砍掉 90%+

Antigravity CLI 入门指南:从安装到第一次运行

claude-code-setup 插件实战指南:让 Claude Code 真正读懂你的项目

Claude Code 工程化指南:高效组织 .claude/ 目录

Claude Code 斜杠命令全解:14 条实用指南

从 0 开始:用 Hooks 打造自动化 Claude Code 工作流

写好 CLAUDE.md 的 8 条经验:让 Claude Code 更懂你的项目

Claude Code 项目的 MEMORY.md 使用指南

原文发布于 X:https://x.com/vincemask/status/2064581609928699973

评论

加载评论…