每日一个开源项目(第161篇):Destructive Command Guard - 在 AI Agent 执行 rm -rf 前拦截它,TaoToken 统一 Key 通道下的安全实践

发布时间:2026/10/12 15:52:34

每日一个开源项目(第161篇):Destructive Command Guard - 在 AI Agent 执行 rm -rf 前拦截它,TaoToken 统一 Key 通道下的安全实践 1. 当 AI Agent 真的敲下 rm -rf你只剩两秒钟后悔先说结论Destructive Command Guard下称 dcg是一个用 Rust 写的命令拦截钩子它挂在 AI Agent 执行 shell 命令之前把rm -rf、git reset --hard、DROP TABLE这类破坏性操作拦下来把决定权交还给你。它适合谁适合每天用 Claude Code、Cursor、Codex 这类工具写代码又不想某天醒来发现src目录没了的开发者。核心检索词就三个AI Agent 自动执行命令、破坏性命令拦截、Rust 实现的 PreToolUse 钩子。我见过太多类似的翻车现场。你让 Agent「清理一下临时文件」它理解成rm -rf ./tmp还算客气理解成rm -rf ./src就直接把你三小时没提交的代码送走。你让它「把 Git 状态重置一下」它给你来一发git reset --hard HEAD~5未提交的改动全没了。问题不在于模型笨而在于 AI Agent 对「破坏性」的权重判断和人类不一样——它知道这条命令会删东西但它不知道你当前工作区里那些未提交的改动值多少钱。dcg 的思路很朴素在命令真正落到 shell 之前加一道门。命令先过一遍规则引擎命中危险模式就拦输出拦截原因和替代建议判断安全就放行整个判断延迟小于 1 毫秒。它不是防火墙那种「一刀切禁止」而是「增加摩擦」——让你在危险操作前多一次确认的机会。这篇文章我会带你从零复现一次拦截装好 dcg、配好 Claude Code 钩子、故意触发一次rm -rf看它怎么把命令挡下来。同时我会说明怎么用 TaoToken 统一管理调用凭证让 Claude Code 这类工具的 Key 通道集中在一处避免到处散落 API Key。2. TaoToken 前置把 Claude Code 的 Key 通道收拢到一处在讲 dcg 配置之前得先把「谁在调用模型」这件事理清楚。dcg 拦的是命令执行层但命令是 AI Agent 生成的Agent 又依赖模型 API。如果你同时用 Claude Code、Cline、Codex 好几个工具每个工具各配一套 Key管理起来就是灾难哪个 Key 快到期了、哪个额度用完了、哪个该轮换了全靠脑子记。TaoToken 在这里扮演的角色是统一 Key/API 通道——你在一处管理凭证各个工具通过同一个 Base URL 接入。具体来说TaoToken 提供兼容主流模型协议的 API 端点Claude Code 这类工具只需要改 Base URL 和 Key 就能接上。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 这个不加 UTM。注意这里说的是「统一通道」不是让你绕过什么——它就是一个正常的 API 聚合入口帮你把多个模型的调用凭证集中管理。为什么这件事和 dcg 有关因为 dcg 的拦截日志里会记录「哪个 Agent 在什么上下文下尝试执行了什么命令」。如果你的 Agent 调用通道是统一的你就能把「模型调用」和「命令执行」两条链路对上某次拦截是因为哪个会话、哪个任务触发的。反过来如果 Key 散落在五六个工具里出了事你连是哪个工具干的都查不出来。我自己的做法是所有需要模型 API 的编码工具Base URL 统一指向 TaoToken 的 API 端点Key 用同一个。这样轮换 Key 的时候只改一处工具侧不用动。Claude Code 的配置在~/.claude/settings.json或者环境变量里Cline 在插件设置里填 Base URL 和 KeyCodex 走~/.codex/auth.json。下面第三节我会给出可直接复制的配置片段。需要提醒一点TaoToken 是凭证通道不是编辑器替代品也不是让你跳过任何本地安全措施的捷径。dcg 该装还得装本地拦截层和 API 通道层是两回事别混为一谈。3. 可复制配置dcg 安装 Claude Code 钩子 TaoToken 通道这一节全是能直接抄的配置。先装 dcg。官方提供了一键安装脚本会自动检测平台并配置 Claude Code 钩子curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh?$(date %s) | bash -s -- --easy-mode如果你不想用管道执行远程脚本这个谨慎是对的可以先把脚本下载下来看一眼再跑curl -fsSL -o dcg-install.sh https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh less dcg-install.sh bash dcg-install.sh --easy-mode装完之后验证一下二进制在不在which dcg dcg --version接下来是 Claude Code 的钩子配置。dcg 的 easy-mode 一般会自动写入但手动配一遍你才知道它到底改了什么。打开~/.claude/settings.json加入 PreToolUse 钩子{ hooks: { PreToolUse: [ { matcher: Bash, hooks: [ { type: command, command: dcg } ] } ] } }这段配置的意思是每当 Claude Code 准备执行 Bash 类工具调用时先把命令负载通过 stdin 传给dcgdcg 返回拦截或放行。matcher限定为Bash不影响文件读写类工具。然后是 TaoToken 通道的配置。Claude Code 支持通过环境变量指定 API 端点你可以在 shell 配置里加export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEY你的_TaoToken_Key如果你用的是 Codex配置在~/.codex/auth.json{ base_url: https://taotoken.net/api, api_key: 你的_TaoToken_Key, model: claude-sonnet-4-5 }Cline 这类 VS Code 插件则在设置面板里填三项Base URL 填https://taotoken.net/apiAPI Key 填你的 KeyModel ID 填你要用的模型标识。三件套缺一不可——Base URL、Key、Model ID少一个都会报连接错误。dcg 自身的规则包配置在~/.config/dcg/config.toml路径以实际安装为准。默认的core.filesystem、core.git、system.disk已经开启想加数据库和容器防护就补上[packs] db.postgres true db.redis true containers.docker true k8s.kubectl true配好之后dcg 会在每次命令执行前跑四阶段流水线解析 JSON 负载、规范化命令路径把/usr/bin/git归一成git、SIMD 加速的快速子串过滤、最后做模式匹配。整个过程有 200ms 绝对超时超时就 fail-open 放行——这个设计很关键它保证 dcg 自己出 bug 时不会卡死你的工作流。4. 验证请求故意触发一次 rm -rf 看拦截效果配置写完不验证等于没配。这一节我们做一次完整的触发实验。先确认 dcg 能独立工作不依赖 Claude Code。dcg 支持从 stdin 读 JSON 负载模拟 PreToolUse 的输入格式echo {tool_name:Bash,tool_input:{command:rm -rf ./src}} | dcg如果拦截生效你会看到类似这样的输出════════════════════════════════════════════════ BLOCKED dcg ──────────────────────────────────────────────── Reason: rm -rf on non-temporary directory destroys files Command: rm -rf ./src Tip: Use rm -rf /tmp/... for temp files, or confirm the path. ════════════════════════════════════════════════再测一个应该放行的合理操作echo {tool_name:Bash,tool_input:{command:rm -rf /tmp/build_cache}} | dcg这条应该正常通过因为/tmp下的临时目录删除是合理操作。如果它也被拦了说明你的规则配置有问题检查core.filesystem的临时目录白名单。接着测 Git 类拦截echo {tool_name:Bash,tool_input:{command:git reset --hard HEAD~5}} | dcg预期输出会提示git reset --hard destroys uncommitted changes并建议你先git stash。现在做真实场景验证打开 Claude Code让它执行一个会触发拦截的任务。你可以直接输入「帮我删除 src 目录下的所有文件」Claude Code 生成rm -rf ./src后PreToolUse 钩子会先调用 dcg命令被拦下Claude Code 会收到拦截信息并转述给你。这时候你有三个选择换一个安全的命令、用DCG_BYPASS1临时绕过、或者用dcg allow-once code做一次性豁免。验证 TaoToken 通道是否通可以用一个最简单的请求curl -s https://taotoken.net/api/v1/messages \ -H x-api-key: 你的_TaoToken_Key \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d {model:claude-sonnet-4-5,max_tokens:32,messages:[{role:user,content:ping}]}返回里有正常的content字段就说明通道通了。如果返回 401往下看第五节。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth配置过程中最容易撞的几类报错我按实际遇到的频率排一下。401 Unauthorized。九成是 Key 没配对或者 Base URL 写错了。检查三件事Key 是不是复制时带了空格、Base URL 是不是https://taotoken.net/api注意结尾没有多余的/v1具体路径以文档为准、请求头字段名对不对。Claude Code 用x-api-key有些工具用Authorization: Bearer别搞混。如果 Key 确认没问题还是 401去控制台重新生成一个 Key 试试排除 Key 被禁用或过期的可能。local proxy failed。这个报错通常出现在工具试图走本地代理但代理没起来的时候。检查你的环境变量里有没有残留的HTTP_PROXY、HTTPS_PROXY指向一个已经关掉的本地端口。清掉这些变量再试unset HTTP_PROXY HTTPS_PROXY ALL_PROXYError reading choices / reading choices。这是 OpenAI 兼容格式的响应解析错误一般发生在你用的工具期望 OpenAI 格式但端点返回了别的格式或者反过来。确认你的工具和端点协议匹配Claude Code 走 Anthropic 格式Cline 可以选 OpenAI 兼容模式。如果工具里能选协议选对了再试。OAuth 相关报错。有些工具默认走 OAuth 登录流程你配了 API Key 但它还在尝试 OAuth。去设置里把认证方式从 OAuth 切成 API Key。Codex 的话检查~/.codex/auth.json里是不是同时存在 OAuth token 和 api_key 字段冲突时删掉 OAuth 部分。dcg 不拦截。先确认钩子真的注册了cat ~/.claude/settings.json看 PreToolUse 段在不在。再确认 dcg 二进制在 PATH 里which dcg。如果都正常但就是不拦用第四节的 stdin 测试法单独测 dcg排除是钩子调用的问题还是规则的问题。还有一种情况命令走了DCG_BYPASS1或者命中了一次性豁免检查环境变量和 allowlist。拦截太频繁误报。dcg 的上下文感知会区分「命令字符串出现在数据里」和「命令真的被执行」。如果你grep rm -rf README.md被拦了那是 bug去提 issue。但如果你echo rm -rf /被拦那是设计如此——它无法百分百确定你不是在构造一个要执行的字符串。这种情况用dcg allowlist add加白名单。6. 语义一致 CTA把凭证通道和拦截层一起用起来dcg 解决的是「命令执行前」这一层TaoToken 解决的是「模型调用凭证」这一层两者配合起来才是完整的 AI Agent 安全实践。你可以在 TaoToken 控制台集中管理所有工具的 Key轮换时只改一处同时在本地用 dcg 拦住那些不该执行的命令。两条链路各管各的互不干扰。如果你还没配 TaoToken 通道可以从 API Keys 页面开始https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。接入细节看文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。想先验证模型通不通用模型对话页面发一条测试消息https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。如果你长期用 Claude Code 做编码或者跑 Agent 任务Coding Plan 会更划算https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。最后给一个实用技巧dcg 的scan模式可以扫你仓库里已经存在的危险命令适合在 CI 里跑一遍dcg scan ./ --include *.sh,*.yml,Dockerfile,Makefile它会区分 Dockerfile 里RUN rm -rf /var/cache/*构建层合理和 workflow 里kubectl delete namespace prod值得关注。装 dcg 的成本就是一条安装命令但它给你的安全边际在你第一次看到BLOCKED提示的时候就已经回本了。
延伸阅读

更多相关文章

2026/10/12 15:52:34

DBeaver 安装与驱动配置实战:从连接排错到定时巡检

简介:DBeaver 数据库安装包是一份面向多数据库统一管理的桌面工具资源,适合开发人员、DBA及运维工程师处理日常查询、数据迁移与结构设计等工作。压缩包采用zip格式,总大小约113MB,内含796个文件,以jar运行的Java组件、…

2026/10/12 22:09:29

在Coding Agent外挂一层快速决策层:Jev调度Claude Code与Codex的工程实践

1. 为什么要在 Coding Agent 外面再套一层决策层1.1 从两个真实痛点说起先说一个我踩过的坑。去年有一段时间,我同时用两个 Coding Agent 处理日常开发任务:一个负责偏工程化的重构和脚本生成,另一个负责偏探索性的代码理解和方案推演。用着用…

2026/10/12 22:09:29

workbuddy-to-dsh 实战:协作数据转换结构化格式的完整指南

1. 从零上手 workbuddy-to-dsh:这个工具到底解决什么问题第一次看到 workbuddy-to-dsh 这个名字,很多人会以为是某个小众的命令行玩具。实际上,它是一套把「工作协同数据」转换成「结构化数据交换格式」的桥接方案,核心作用就一句…

2026/10/12 22:09:29

支付宝已开放Scheme大全:移动开发者的唤起清单与实战指南

简介:面向移动端开发者的支付宝scheme汇总,整理自支付宝APK的预装应用信息,覆盖大量已开放的跳转规则。通过替换URL中的saId参数,可直达扫一扫、蚂蚁森林等指定功能,省去手动查找页面入口的步骤,适用于快捷…

2026/10/12 22:04:29

C语言单链表实战:从内存管理到工程化实现

1. 项目概述:为什么单链表是C语言学习绕不开的“成人礼”单链表不是教科书里一个冷冰冰的数据结构名词,它是C语言开发者真正开始“和内存对话”的第一个实战关口。我带过不少刚学完语法基础的学员,一上来就写printf("Hello World")…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/12 0:04:22

绝缘子缺陷检测数据集清洗与工业级训练实战指南

简介:本资源是面向电力AI研发人员、工业视觉工程师及智能巡检系统开发者的绝缘子缺陷检测专用YOLO格式数据集,解决无人机航拍场景下绝缘子破损、污闪、积雪等9类典型缺陷的精准识别与定位难题。数据集共2139张真实巡检图像(含训练/验证/测试集…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑