dcg:挡在 AI Agent 与 `rm -rf` 之间的 Rust 钩子

AI
开源
安全
Rust
Agent
CLI
2026/9/29
·

阅读时间: 大约 8 分钟

dcg:挡在 AI Agent 与 rm -rf 之间的 Rust 钩子

dcg 规则引擎使用 fancy-regex 编写负向先行断言与字符类,例如只拦截 git push --force 而放过 --force-with-lease

“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,后者走一条固定管线:

  1. JSON Parsing:校验各 Agent 变体的钩子负载,抽出命令字符串;非 shell 工具直接放行;
  2. Normalization:剥掉绝对路径(/usr/bin/git 归一成 git),保留参数;
  3. Quick Reject:O(n) 子串扫描 git/rm 等关键字,不含关键字的命令直接跳过正则(官方称覆盖 99%+ 的非破坏性命令);
  4. 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
3heredoc 触发< 5μs> 10μs> 100μs
4heredoc 抽取< 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+ 包”给人的印象。

其他局限:

  1. 规则式拦截天然可绕:它是正则+AST 的规则匹配,不是沙箱。包装、编码、新的命令变体都可能绕过——Koala 点评也强调”当最后一道保险,而非唯一防线”。
  2. 默认放行(default-allow):白名单不命中、破坏规则也不命中时默认放行;对”规则没覆盖到的新型破坏命令”没有兜底。
  3. 不替代隔离与备份:官方定位是钩子层,真正的纵深防御仍需容器隔离、git 提交、数据库备份配合。
  4. 跨 Agent 钩子协议碎片化:各 Agent 的钩子格式、退出码约定不一,dcg 要为每个做适配,新 Agent 支持需要持续跟进(部分如 Aider 仅有限支持)。

五、客观分析:价值与定位

价值:把”别误删”从每个 Agent 各自为政的确认弹窗,抽成一个语言/协议中立、亚毫秒、跨工具的统一策略层;且默认只拦高危、误伤可控,配合 dcg explain 可调试规则。

局限:规则包默认不全开,需自行配置;本质是黑名单思维,面对未知绕过手段无能为力;它保护的是”本地命令”这一层,对 Agent 通过 API 做的破坏(如误删云资源)只有在你显式启用对应 pack 后才生效。

适合谁:在 Claude Code/Codex/Cursor 等多个 Agent 间切换、被误删坑过、想要一层统一兜底的开发者;尤其建议把它接进 git 提交前钩子与 CI(Scan Mode),作为容器隔离与定期备份之外的第二道防线。

参考来源