dcg:挡在 AI Agent 与 `rm -rf` 之间的 Rust 钩子
阅读时间: 大约 8 分钟
dcg:挡在 AI Agent 与 rm -rf 之间的 Rust 钩子

“AI 编程助手跑着跑着就 git reset --hard、rm -rf ./src、甚至 DROP TABLE users,几秒钟毁掉几小时未提交的工作”——这几乎是每个重度 Agent 用户都踩过的坑。各家 CLI 自带的确认机制又常被”自动批准”模式一键放行。dcg(Destructive Command Guard) 由 Dicklesworthstone 用 Rust 写成,定位就是一个跨 Agent 的统一 PreToolUse 钩子层:在命令真正执行前拦下它。本文基于其官方 GitHub README 做一次解析。
一、它覆盖了谁
dcg 作为各 Agent 的”PreToolUse”钩子运行,官方列出的支持面相当广:Claude Code、Codex CLI(0.125.0+)、Gemini CLI、GitHub Copilot CLI、VS Code Copilot Chat、Cursor、Hermes Agent、Grok(xAI)、Posit Assistant、Oh My Pi、OpenCode、Crush、Reasonix,以及仅 git hooks 级的 Aider 和仅检测的 Continue。安装脚本一条 curl ... | bash 即可自动探测平台并配置各 Agent 钩子;Windows 原生走 PowerShell 安装器,会校验 SHA256、minisign 签名与 Sigstore/cosign 来源。
二、四段管线与三级加速
Agent 把每条 shell 命令以 JSON 形式通过 stdin 交给 dcg,后者走一条固定管线:
- JSON Parsing:校验各 Agent 变体的钩子负载,抽出命令字符串;非 shell 工具直接放行;
- Normalization:剥掉绝对路径(
/usr/bin/git归一成git),保留参数; - Quick Reject:O(n) 子串扫描
git/rm等关键字,不含关键字的命令直接跳过正则(官方称覆盖 99%+ 的非破坏性命令); - Pattern Matching:先查安全白名单(命中=放行),再查破坏性规则(命中=拒绝并给理由),都不命中=放行。
为做到亚毫秒,README 把检查拆成三级:Tier 1 触发器(RegexSet,命中才进入后续)、Tier 2 抽取(从 heredoc/内嵌脚本里抽出真实命令)、Tier 3 AST(真正判定)。官方在 src/perf.rs 里钉死了延迟预算与 CI 门禁:
| Tier | 路径 | 目标 | 告警阈值 | 触发 panic |
|---|---|---|---|---|
| 0 | 快速拒绝 | < 1μs | > 5μs | > 50μs |
| 1 | 快速放行路径 | < 75μs | > 150μs | > 500μs |
| 2 | 模式匹配 | < 100μs | > 250μs | > 1ms |
| 3 | heredoc 触发 | < 5μs | > 10μs | > 100μs |
| 4 | heredoc 抽取 | < 200μs | > 500μs | > 2ms |
| 5 | 语言检测 | < 20μs | > 50μs | > 200μs |
| 6 | 完整 heredoc 管线 | < 5ms | > 15ms | > 20ms |
配合 SIMD 加速,官方称日常命令几乎无感。
三、几个真有用的细节
- 识别”真执行”还是”当文本”:
grep "rm -rf"是数据、放行;rm -rf /是执行、拦截。这避免了把无害字符串误杀。 - 穿透包裹层:能扫出
python -c "os.remove(...)"、heredoc 里的内嵌 shell,而不是只看裸命令。 - 人机分流的输出:机器可读的拒绝 JSON 走 stdout,彩色人读面板走 stderr;对 CI/管道/哑终端自动降级为纯文本。
- Codex 契约适配:对 Codex CLI 严格按其钩子契约输出最小 stdout JSON 并以 exit 0 结束,避免被客户端误判。
dcg explain "command":直接告诉你某条命令为什么被拦。- 有界失败策略:分析超时不默默放行,而是变成显式的 review/block 结果;畸形钩子负载也可审计、可配置。
四、口径与局限:50+ 规则包其实默认不开
这是读 README 时最需要纠正的一个营销点。Koala 简介与官网都说”内置 50+ 安全规则包”,但 README 明确写道:databases.postgresql、containers.docker 这些包是 opt-in,配置文件不启用就不生效。dcg init 生成的 config.toml 只是把它们当作示例打开;“零配置默认”实际只拦 git 与文件系统类高危命令,数据库、Kubernetes、S3(storage.s3)、云平台、Terraform 等保护都要你自己写进 [packs] enabled。也就是说,开箱即用时覆盖面远小于”50+ 包”给人的印象。
其他局限:
- 规则式拦截天然可绕:它是正则+AST 的规则匹配,不是沙箱。包装、编码、新的命令变体都可能绕过——Koala 点评也强调”当最后一道保险,而非唯一防线”。
- 默认放行(default-allow):白名单不命中、破坏规则也不命中时默认放行;对”规则没覆盖到的新型破坏命令”没有兜底。
- 不替代隔离与备份:官方定位是钩子层,真正的纵深防御仍需容器隔离、git 提交、数据库备份配合。
- 跨 Agent 钩子协议碎片化:各 Agent 的钩子格式、退出码约定不一,dcg 要为每个做适配,新 Agent 支持需要持续跟进(部分如 Aider 仅有限支持)。
五、客观分析:价值与定位
价值:把”别误删”从每个 Agent 各自为政的确认弹窗,抽成一个语言/协议中立、亚毫秒、跨工具的统一策略层;且默认只拦高危、误伤可控,配合 dcg explain 可调试规则。
局限:规则包默认不全开,需自行配置;本质是黑名单思维,面对未知绕过手段无能为力;它保护的是”本地命令”这一层,对 Agent 通过 API 做的破坏(如误删云资源)只有在你显式启用对应 pack 后才生效。
适合谁:在 Claude Code/Codex/Cursor 等多个 Agent 间切换、被误删坑过、想要一层统一兜底的开发者;尤其建议把它接进 git 提交前钩子与 CI(Scan Mode),作为容器隔离与定期备份之外的第二道防线。