AgentShield 拆解:一个 Claude Code 黑客松作品,如何把「AI Agent 配置审计」做成可上 CI 的合规工具
一、速览
★★★★☆(4/5)。affaan-m 在 2026-02 的 Claude Code 黑客松(Cerebral Valley × Anthropic)上做出的 AI Agent 配置审计器,MIT,1,229 star / 268 fork(截至 2026-09-27),归属于他主理的 Everything Claude Code 生态(42K+ star)。它做的事情不是「扫业务代码漏洞」,而是扫你自己的 .claude/ 目录 —— 硬编码密钥、过度宽松的 tool permission、hook 里的命令注入、MCP server 暴露面、Agent prompt injection 触发点 —— 268 条规则(README 自报)打成 0–100 分 + A–F 评级,CI 里 fail-on-findings 就能直接当门禁。扣一星的原因很具体:README 里规则数有三套口径(268 / 102 / 17+40+49+41,详见第七章),项目只有 6 个月历史,且 --opus/--injection 会把你 .claude/ 的配置内容外发到 Anthropic(或 OrcaRouter)的 API —— 敏感配置必须先脱敏再用。给 Claude Code 重度用户:直接装、立刻用;其他 harness 适配当加分项看;公网 / 多租户场景不推荐。
| 主语言 | TypeScript |
| 许可证 | MIT |
| Star / Fork | 1,229 / 268 |
| 首次发布 | 2026-02-11(Claude Code Hackathon) |
| 最近一次推送 | 2026-09-10 |
| 规则覆盖(README 口径) | 268 条 / 15 模块;分模块章节里又写成 Secrets 10 / Permissions 17 / Hooks 40 / MCP 49 / Agents 41;架构表汇总是 102 条 |
| 评分体系 | A–F 评级 + 0–100 分;critical 25 / high 15 / medium 5 / low 2 / info 0 扣分 |
| 输出格式 | terminal / json / markdown / html / sarif / evidence-pack |
| 自动化形态 | CLI + GitHub Action + GitHub App(ecc-tools)+ MiniClaw HTTP API |
| 主扫描对象 | ~/.claude/、.claude/settings.json、.claude/mcp.json、.claude/subagents/、hooks/、CLAUDE.md 等 |
| 地址 | https://github.com/affaan-m/agentshield |
适合谁(5 分制):
| 人群 | 分 | 理由 |
|---|---|---|
| Claude Code 重度用户 / Agent 开发者 | 5 | 直接扫你 .claude/ 目录里自己配的 hooks / MCP / permissions / sub-agents,覆盖面最贴合日常踩坑点;--fix 能自动替换硬编码密钥 + 收紧 wildcards |
| 企业安全运营 / CISO | 4 | 唯一打动我的是 --compliance soc2,pci,iso 直接输出 GRC 友好的控制覆盖表 + --policy 组织策略门禁,evidence-pack 出可验证审计包;但只覆盖 Claude Code 系生态,别的 harness 适配还很浅 |
| 红队 / 渗透 | 3 | 它不是攻击平台,是自查平台;--injection 可以主动注入 prompt 测 agent 抗注入,但攻击面摸底还得用别的手工方法(hook 沙箱执行 / MCP 流量侧录) |
| 安全研究员 / 误报治理方向 | 3 | runtimeConfidence 七档分类 + template-example / project-local-optional 不同权重 + false-positive-audit.md 工作流这套误报治理方法论值得借鉴;但工具本身是配置扫描,不是研究产出 |
| 个人学习 / 自部署 | 4 | npx ecc-agentshield scan 一条命令零安装,6 个月年轻项目文档完整;要 --opus 才会产生额外 LLM API 调用费,不开就跟普通 lint 一样白嫖 |
二次开发(MIT 三档):
| 难度 | 能做的事 |
|---|---|
| 改配置 | 不需要碰代码:写一个 JSON --rule-pack(schema 校验 + fail-closed)就能挂自定义规则;agentshield policy init/export/promote 三步产出组织级策略(oss / team / enterprise / regulated / high-risk-hooks-mcp / ci-enforcement 六种预设) |
| 改集成 | GitHub Action 已暴露 ~25 个输入参数(path / fail-on-findings / baseline / policy / policy-promotion-manifest / supply-chain / evidence-pack / sarif-output 等);SARIF 可直接喂 github/codeql-action/upload-sarif;Linear sync / evidence-pack fleet / policy export manifest 都是为 CI 接 GRC 设计的 |
| 改内核 | src/rules/*.ts 加规则(5 个分类独立文件,sized 中等);src/reporter/score.ts 改评分权重(这是工具最敏感的逻辑,每个扣分点的权重都在这里);src/opus/prompts.ts 改 Attacker/Defender/Auditor 三智能体对抗提示词 |
二、是什么,不是什么
打开仓库之前先把五件事说清楚,因为 AgentShield 不是这几样常见的东西:
不是通用 SAST/DAST。它不扫你 src/、backend/、业务代码 —— 那是 Semgrep / CodeQL / Snyk 的活。AgentShield 扫的是你自己写的 agent 配置:CLAUDE.md 里的「Always run this without asking」、.claude/settings.json 里的 Bash(*)、hook 脚本里的 curl ${user_input}、MCP server 命令里的 npx -y、sub-agent prompt 里的零宽字符。两个扫描器解决的是不同层的问题。
不是运行时沙箱。它是个静态 + 报告型扫描器,不替你执行/拦截 hook。README 里给的 --sandbox 是「把 hook 脚本放到沙箱里跑然后观察行为」,属于主动验证而不是强制执行。--taint 是数据流追踪(实验性)。真要阻止恶意 hook 触发,仍然要靠 Claude Code 自己的 PreToolUse hook —— AgentShield 只是告诉你哪里需要补。
不是 MCP Server 漏洞扫描器。它不审计 MCP server 的代码,只看你 .claude/mcp.json 里这个 server 的配置是不是危险(high-risk server type、敏感文件作参数、shell metacharacters、缺少 version pin、environment inheritance、autoApprove、remote URL transport 等)。要审计 MCP server 代码本身,你得用别的手工方法或专用工具。
不是只能 Claude Code。README 写了本地 harness adapter 证据(marker-based,不打外部服务):Claude Code / OpenCode / Codex / Gemini / Zed / VS Code / dmux / terminal-agent wrappers / 项目本地模板都识别。但这套 adapter 是「marker 证据」 —— 找到项目的某些标识文件就标 harnessAdapters 而已,不是真正的多 harness 深度适配。Claude Code 是最深的那一个(毕竟它本来就为 Claude Code 而生),其他当加分项看。
不是可以无脑交给团队所有人跑的工具。--opus / --injection / --provider orcarouter 会把你 .claude/ 的配置内容(包括可能存在的密钥、URL、token)外发到 LLM API。README 自己警告:do not use it on configs containing secrets you have not redacted。CI 里跑这些模式,要么用 --no-evidence-redact 反向控制(默认是 redact 的),要么先 strip secrets 再跑。
那 AgentShield 到底是什么?看官方一句话:
AI agent security scanner. Detect vulnerabilities in agent configurations, MCP servers, and tool permissions. Available as CLI, GitHub Action, ECC plugin, and GitHub App integration.
四个关键词:agent configuration(不是业务代码)/ graded score(0–100 分不是布尔)/ CI-native(GitHub Action 是 first-class)/ recognize-and-attribute(recognize defenses 列表里只挂名不扣分也不加分,防刷分)。
三、五大扫描面(268 规则拆解)
AgentShield 的能力按文件类型拆成五块,对应 ~/.claude/ 里五类配置。
| 模块(规则数) | 扫什么 |
|---|---|
| Secrets(10 条 / 14 patterns) | 硬编码密钥:Anthropic sk-ant-、OpenAI sk-proj-/sk-、xAI xai-、AWS AKIA、Google/Gemini AIza、Stripe sk_test_/sk_live_、GitHub PAT ghp_/github_pat_、Linear lin_api_、Cloudflare CF_API_TOKEN=、Slack xox[bprs]-、JWT eyJ...、Bearer tokens、数据库连接串、私钥、env 变量泄漏 |
| Permissions(17 条) | 通配符 Bash(*)/Write(*)/Edit(*)、缺失 deny list、--dangerously-skip-permissions、可变工具未限定、破坏性 git 命令、curl */wget/ssh * 无限网络 |
| Hooks(40 条) | hook 里的命令注入(${file} 插值)、数据外发(curl -X POST ${...})、静默错误(2>/dev/null)、缺失 PreToolUse hook、SessionStart 下载执行、全局 npm/pip/gem/cargo 安装、Docker 特权模式、/dev/tcp reverse shell、剪贴板读写、日志清理反取证 |
| MCP Servers(49 条) | high-risk server type、npx -y 无确认安装、environment 里塞 token、remote URL transport、shell metacharacters in args、缺 version pin、autoApprove、缺失 timeout、0.0.0.0 绑定、敏感文件作参数、supplier chain 验证 |
| Agents(41 条) | unrestricted tool access、外部内容处理无防御、auto-run 指令(”Always run” / “without asking” / “automatically install”)、零宽字符 / HTML 注释 / base64 隐藏指令、URL 执行、时间触发型指令、批量凭据收集、prompt reflection(”ignore previous instructions”)、output manipulation(”always report ok”) |
几个值得展开的设计细节:
Secrets 的 env var 泄漏会被识别为 critical —— 即使配置里写的是 ${SECRET} 而不是明文,hook 命令行里如果出现 echo $SECRET 或环境变量透传,也算高危。这比 grep 字符串要聪明。
Permissions 的”deny list 缺失”会自动分级:settings.local.json 完全限定的 allowlist 把 permissions-no-deny-list 从 high 降到 medium;wildcard 仍保持 high。这是 source-aware 评分(同一条规则在不同上下文里严重度不同)。
Hooks 的 “hook-code“ 专门针对非 shell 实现。manifest-referenced hook(hooks/hooks.json 引用 scripts/hooks/session-start.js 这种)会找到真正的实现,识别显式的 output(...) 上下文注入、transcript 输入访问、child-process 外发。比看 shell 命令字面值更接近真实风险。
MCP 的 runtimeConfidence 分级是这个工具最专业的部分(详见第四章),不是简单的「有/无」。active-runtime(.mcp.json)vs settings.local.json(project-local-optional)vs mcp-configs/(template-example)vs plugin-cache / plugin-manifest / hook-code —— 同样一条 npx -y 在你真的装在机器上是 critical,在 docs 目录里就降权 0.25x、单文件封顶 10 分。
Agents 的 prompt injection 规则对「defensive content」免疫:agent prompt 里提到 fetch(userProvidedUrl) 模式(教导性内容)不触发 agents-injection-surface;直接指令去 fetch/process external content 才会。对防御性 prompt 友好,避免「教防御反而被误报」。
四、评分与误报治理(这是工具最值钱的部分)
AgentShield 真正的护城河不是规则数量,是它怎么打分 + 怎么治理误报。
4.1 评分规则
每个分类从 100 分起,扣分只来自 findings:
- critical −25 / high −15 / medium −5 / low −2 / info 0
最后总分 → 字母等级(A 90+ / B 80+ / C 70+ / D 60+ / F <60)。
Recognized Defenses(识别出的防护配置)单独列在报告里:
- 不扣分(即使有
deny规则命中,也按 allow 走) - 也不加分(防止给一堆装饰性 deny 规则刷分)
也就是分数只能被真实 findings 降低。这是合规向 GRC 报告里很重要的一点 —— 分数越高代表「没有发现真实问题」,不是「你写了很多 deny」。
4.2 runtimeConfidence 七档分级
这是 AgentShield 最专业的误报治理机制:
七档按「这个配置到底在不在跑」区分,权重直接乘在扣分上:
active-runtime(权重 1.0×) —— 真在跑的配置:.mcp.json、mcp.json、.claude/mcp.json、.claude.json、active settings.json
project-local-optional(0.75×) —— settings.local.json 这类本地覆盖,只对当前项目生效
plugin-cache(0.5×) —— 已装插件缓存,如 .claude/plugins/cache/...
plugin-manifest(0.5×) —— 声明性 hook manifest,如 hooks/hooks.json
template-example(0.25×,且单文件封顶 10 分) —— 模板/目录型定义,如 mcp-configs/、config/mcp/
docs-example(0.25×) —— 教学/示例内容,如 docs/guide/settings.json、commands/*.md
hook-code(1.0×,窄规则集) —— manifest 解析到的非 shell 实现,如 scripts/hooks/session-start.js
实际效果:仓库里 docs 目录有一个 risky MCP server 模板,不会像真的启用了一样算 critical;它会被打 template-example 标签,扣 0.25 倍,最多扣 10 分。这是从「多 false positive」到「分级 triage」的关键转变。
4.3 --fix 自动修 + 防篡改
agentshield scan --fix 不是「一把梭」 —— 它的工作流是:
- 只修标
auto: true的项(替换硬编码密钥为${ENV_VAR}、收紧Bash(*)为Bash(git *)等) - 修完复扫一次
- 如果总分下降或出现新的 high/critical finding(典型的「缩紧权限反而暴露其他问题」),回滚所有修改的文件
- 如果 OK,输出一个 tamper-evident attestation digest(绑定 before/after 分数和 finding 变化),让你能证明修完没退化
这等于把 --fix 从「自动改坏不告诉你」变成「改坏自己撤销 + 给你证据」。对在生产配置上做自动化的人来说非常关键。
4.4 误报治理工作流
仓库自带一份 false-positive-audit.md,里面给了完整的 triage 工作流:
- 先用
--format json拿结构化数据 - 用
jq按runtimeConfidencegroup_by - 区分 active-runtime(高信噪比)和 lower-confidence(需解释)
- 优先 active-runtime + project-local-optional
- 验证可疑 FP 时至少跑一个真实仓库 + 一个最小合成 fixture
- 优先 source-aware 重新分类而不是 blanket 抑制
- 真实密钥永远保持 critical(即使在 docs/examples 里也不降权)
这流程本身值得拿来当任何静态扫描器误报治理的范本。
五、进阶能力:Opus 对抗 / 合规映射 / 供应链
5.1 三智能体对抗分析(--opus)
光做规则匹配容易漏掉跨规则的复合攻击。--opus 启了一个三智能体对抗 pipeline:
- Attacker(红队,Claude Opus):找可利用的攻击向量和多步链路
- Defender(蓝队,Claude Opus):评估现有防护、给出加固建议
- Auditor:把两边综合成分级风险评估
Attacker 能找到「curl hook + ${file} 插值 + Bash(*) = 命令注入 pivot」这种跨规则链;Defender 指出没有 PreToolUse hook 拦截;Auditor 把它们串成一个优先行动列表。
需要 ANTHROPIC_API_KEY(或 ORCAROUTER_API_KEY 走 OpenAI/Anthropic 兼容网关)。会调用 Anthropic API,且发送你的 .claude/ 内容(详见第七章)。
5.2 合规映射(--compliance)
1 | agentshield scan --compliance soc2 # SOC 2 Trust Services Criteria |
输出控制覆盖表(control id / title / highest severity / finding count / examples),按严重度排序。给 GRC 团队一份审计员可读的覆盖率清单,而不是 raw findings 列表。
明确标注:是 finding-category-level guidance(SOC 2、PCI DSS v4.0、ISO/IEC 27001:2022 Annex A),不是 certified crosswalk。具体控制适用性请你的审计员确认。这条免责声明写得老实。
5.3 供应链验证(--supply-chain)
MCP 命令流从 npm 装包是个常见 typosquatting 攻击面。--supply-chain 抽 MCP 包引用 + 根 package.json / package-lock.json 依赖证据,报告:
- npm vs git 来源数
- pinned vs unpinned
- known-good packages
- npm-registry 验证
加 --supply-chain-online 还会去 npm 查 downloads、maintainers、postinstall scripts、deprecation、package age。
还检查 .npmrc / .yarnrc.yml / pnpm-workspace.yaml 里的明文 registry 凭据、minimumReleaseAge / npmMinimalAgeGate 等 cooldown 配。
GitHub Action 里默认 supply-chain: true,失败模式可控。
5.4 MiniClaw:附带的安全沙箱 HTTP Agent
npx ecc-agentshield miniclaw start 启一个 单一 HTTP 端点的隔离 agent runtime,对比典型 agent 平台暴露 Telegram / Discord / email / community plugins 多个攻击面,MiniClaw 只暴露 localhost:3847 默认 + 隔离沙箱 + 安全工具集。作为「我也要本地玩 agent 跑点东西」的轻量方案挺合适。也可作为库 import { startMiniClaw } from 'ecc-agentshield/miniclaw'。
六、部署与集成
1 | # 最快路径:零安装直接扫 |
GitHub Action 已是 first-class:
1 | - name: AgentShield Security Scan |
Outputs 超过 25 个,包括 score / grade / critical-count / new-findings / resolved-findings / score-delta / policy-status / supply-chain-critical-count / evidence-pack-digest —— 全部可以接下游 step 做条件判断。
Exit codes:0 无 critical / 1 CLI 错误 / 2 有 critical。这条让 CI 直接判断。
七、边界与风险(诚实写短板)
7.1 规则数三套口径,README 自己没统一
这是写文章时最让我纠结的:
| 出现位置 | 数字 |
|---|---|
| README 开头「268 rules across 15 modules」 | 268 |
| 各章「What It Catches」表格分项 | Permissions 17 + Hooks 40 + MCP 49 + Agents 41 = 147(再加 Secrets 10 = 157,但 README 没这么列) |
| 架构表汇总(README 末尾「Security Rules Summary」) | Secrets 10 + Permissions 10 + Hooks 34 + MCP 23 + Agents 25 = 102 |
实际子模块规则文件(README 架构里写 permissions.ts (17 rules) / mcp.ts (26 rules) / hooks.ts (40 rules) / agents.ts (41 rules)) |
又各不相同 |
三个总数都对不上。可能的解释:「rules」和「patterns」混着用 + 架构里只列「core」规则 + 一些是「hard」/「soft」分级,但 README 自己没解释。对要在 CI 门禁里依赖规则覆盖率的团队来说,这是个隐藏坑 —— 你不知道到底是 100 还是 300 条规则在守你的代码。
建议:跑一次 --format json + jq '.findings | length' 看实际 finding 数(包含的 rule id 集合),用真实数字而不是 README 口径做 CI 决策。
7.2 --opus / --injection 会外发 .claude/ 内容
README 自己写了:
With
--provider orcarouterthe scanned configuration contents are sent to OrcaRouter’s API instead of Anthropic’s, so do not use it on configs containing secrets you have not redacted.
这条对 --opus 和 --injection 都成立。意味着:
- CI 里跑
--opus时,机器上.claude/里所有内容(含密钥、URL、用户名、内网路径)都会发给 Anthropic 或 OrcaRouter - evidence-pack 的 redaction 是针对本地路径/username/email/token-shaped 字符串做的,不一定涵盖你的业务敏感数据
- 合规上跑 CI 的 worker 不能放在会触发数据出境合规审查的环境(比如某些金融/政企内网)
缓解:
agentshield scan --no-evidence-redact是反向(=关闭 redact),不要随便开- 真要跑
--opus,先自己手动 redact 一下.claude/里可能含的 PII / secrets - 或者把
--opus限定在一个独立干净副本上跑,不要直接对生产配置
7.3 项目年轻 + 黑客松出身
- 首次 commit 2026-02-11
- 最近一次 push 2026-09-10
- 6 个月历史(在 AI 安全工具里算非常年轻)
- 黑客松出身意味着节奏快、规则迭代频繁 —— 这次写文章时 README 里的规则数已经在变
意味着:
- API、字段名、规则 ID 都可能在 v2 之前 break(GitHub Action 用
@v1是好的;本地 CLI 建议钉版本) - 报告 schema 会演进(
runtimeConfidence七档就是近期才加的) - 长期稳定性 / 公司治理场景,需要观察
7.4 误报治理仍需人工分级
README 自己承认:
The current scan profile is not dominated by broken matchers. It is mostly dominated by lower-confidence source kinds that need different interpretation.
具体来说:
- template MCP inventory 是当前最大噪音源(很多 everything-claude-code 这种大生态仓库自带
mcp-configs/模板) - example/tutorial config 需要 example-aware 解释,不是 blanket 抑制
- broad
agents-*clusters across files 通常是策略审查问题,不是 false-positive 抑制
runtimeConfidence 已经把噪音分桶了,但怎么 triage 仍然要人。直接拿 JSON 报告喂 GRC 是不够的。
7.5 Harness adapter 只是 marker 证据
README 写:
harnessAdaptersis local marker evidence only. It does not call external services or imply a hosted/team entitlement.
Adapterconfidenceisstrongwhen a primary harness marker exists, andpartialwhen only supporting directories or secondary markers are present.
也就是说:识别到 OpenCode/Codex/Gemini/Zed 只是因为它们目录里有某些文件,不是真的对那些 harness 做深度适配。Claude Code 是最深的那一个。如果你是 Codex-only 用户,AgentShield 的价值打 6 折。
7.6 不验证运行时行为,只读配置
--sandbox(在沙箱里执行 hook 然后观察行为)和 --taint(数据流追踪)都是主动验证,不是被动监控。Claude Code 自己的 PreToolUse hook 是真正的执行拦截,AgentShield 只是个扫描器。别拿它当 runtime protection 用。
7.7 商业 sponsor 嵌入
README 顶部有一行 「Preferred compute sponsor: Itô Markets」+ ECC 的 affiliate 链接。这是合法 affiliate,但对纯中立技术评估来说要标出来:ECC(Everything Claude Code)这个生态在做商业化。AgentShield 本身 MIT 不收费,但 ECC Tools Pro / GitHub App 可能是付费产品。
八、上手
第一步:跑一遍,看你分数多惨。
1 | npx ecc-agentshield scan |
这条命令会发现你 .claude/ 里一堆东西 —— CLAUDE.md 里的「Always run」会触发 agents-auto-run、.claude/settings.json 里的 Bash(*) 会触发 permissions-permissive-*、hooks/*.sh 里的 ${file} 会被打 hook-command-injection。第一次跑很容易出 50+ findings。别慌。
第二步:先理解分级,别急着修。
1 | npx ecc-agentshield scan --format json > report.json |
active-runtime + project-local-optional 是真高信噪比的,先看这些。其他桶的根据需要单独 triage。
第三步:用 --fix 修自动项。
1 | npx ecc-agentshield scan --fix |
这步会自动替换硬编码密钥 + 收紧部分 wildcards。如果修完分数下降或者出现新 high/critical,会自动回滚 + 给你一份 attestation digest。这是工具最有价值的特性之一。
第四步:把 GitHub Action 装上。
1 | # .github/workflows/agentshield.yml |
渐进接入技巧:第一次跑加 baseline: "",把输出存为 agentshield-baseline.json 提交;之后用 --gate 只 fail 在新 critical/high 上。
第五步:把组织策略挂上。
1 | agentshield policy init --pack enterprise # 先用 enterprise 模板 |
policy.json 推进 .agentshield/policy.json 后,Action 就会 fail-on-policy。
新手第一动作:先 npx scan 看分数,别直接装 Action + 严格门禁 —— 你会被一堆 finding 噎死。先理解分级,再用 baseline + --fix 渐进接入。
九、一句话结论
AgentShield 是当前唯一把「AI Agent 配置审计」做到 0–100 分、可上 CI、有误报分级、有合规映射、还有主动对抗分析的 MIT 一档选择 —— 但它的规则数、噪音治理、.claude/ 内容外发问题、以及「Claude Code 专属」的深度都意味着你要带着脑子用:自己跑一次 baseline、看清楚 runtimeConfidence 分级、对 --opus/--injection 先脱敏再跑、对别的 harness 适配当加分项看。给 Claude Code 重度用户:直接用,别家没有这么贴身的;给跨 harness 团队:作为 Claude Code 这边的覆盖层用,别的 harness 再补别的工具。