2026 年 9 月 8 日,grith.ai 发表了一篇题为"An agent skill can hand a stranger your shell – hours after you installed it"的工程文章。文章标题本身已经把核心问题讲清楚了:一个 Agent Skill(以 SKILL.md 形式发布的、可被 Claude Code / Cursor 等 Coding Ag
2026 年 9 月 8 日,grith.ai 发表了一篇题为"An agent skill can hand a stranger your shell – hours after you installed it"的工程文章。文章标题本身已经把核心问题讲清楚了:一个 Agent Skill(以 SKILL.md 形式发布的、可被 Claude Code / Cursor 等 Coding Agent 安装的扩展包)在被安装数小时之后,仍然可以把你的 shell 交给陌生人。grith.ai 自己是做"OS-level security proxy for AI coding agents"的,所以文章带强烈的工程防御视角——但它对当前 SKILL.md 生态的工程现实分析,在 2026 年下半年整个 Coding Agent 领域都值得被认真读完。文章把核心问题拆成三层:第一层是 SKILL.md 当前规范本身没有 portable 的权限描述机制;第二层是 SKILL.md 的 progressive disclosure 模型让"周一安装、周四触发"成为可能;第三层是签名(signing)只解决 provenance,不解决 behaviour。grith.ai 还特别提到了 2026 年 9 月 5 日 mise 创建者 Jeff Dickey 推出的 packslip 协议——一个有数字签名的 release manifest 规范,可以关联 skill 与其版本——但 grith.ai 直接指出"packslip 的局限性:a verified signature tells you where the instructions came from. It does not establish that those instructions are appropriate for your project"。把 grith.ai 这篇文章与同期 henryrobinson 在 HN 上公开的 OpenClaw 恶意插件事件(`@getfoundry/unbrowse-openclaw`,窃取 1Password token、各类 API key、AmEx / Stanford MyHealth / Kubera / Twitter cookie、prompt-injection 改 SOUL.md/AGENTS.md/HEARTBEAT.md)放在一起,可以看到 2026 年下半年 Agent Skill 生态已经出现的真实安全风险——这不是理论威胁,是正在发生的、可量化的、跨多个 Coding Agent runtime 的工程事故。
一、SKILL.md 当前规范:有 distribution,没有 authority
grith.ai 文章的核心切入点,是当前 SKILL.md 规范的设计哲学——标准化了 distribution,但没有标准化 authority。换句话说,这个生态学会了怎么"发包",但还没学会怎么"约束包能做什么"。
SKILL.md 的 frontmatter 现在支持 5 个有用的字段:`name`、`description`、`license`、`compatibility`、`allowed-tools`。`name` 和 `description` 帮 agent 发现并选择这个 skill;`license` 控制分发;`compatibility` 是关于环境需求的口头描述;`metadata` 是任意字符串 map。看起来很完整——但没有一个字段是真正表达"权限边界"的。
`allowed-tools` 看起来像权限系统,但规范明确标注它"experimental, support varies between clients"。更关键的是,它命名的是工具而不是 authority。`Read` 不回答"能读哪些路径";`Bash(git:*)` 不回答"能用哪个 repo、哪个 remote、哪组 credentials";它完全没提子进程、DNS、监听 socket、secrets 这些工程上真正危险的能力。
与此同时,规范单独定义了 `scripts/` 目录作为"放可执行代码的地方",推荐 Python / Bash / JavaScript 作为常见选项,authoring guide 里演示了 skills 调用 `uvx`、`npx`、`bunx`、`deno run`、`go run`——包括运行时才解析的包。
把这两件事叠加,你会看到一个相当清晰的工程缺口:这个 portable 格式有可执行代码的标准位置,但没有约束这些代码能做什么的标准机制。
二、Progressive Disclosure:为什么"周一安装、周四触发"是结构性的
grith.ai 文章里最值得工程团队深思的部分,是它对 SKILL.md progressive disclosure 模型的拆解。Skills 使用渐进式披露:启动时,agent 只看到每个 skill 的名字和描述;当某个任务与描述匹配时,agent 才加载完整的 SKILL.md、读取支持文件、跑 scripts。
这套机制对 context management 来说是合理的——agent 不需要在启动时把每个 skill 的全部内容塞进 context。但对安全来说它是一个结构性弱点。
grith.ai 描述了一条相当具体的攻击链路:
1. 开发者周一 inspect + install 一个 skill。开发者检查 SKILL.md 表面看起来合理、scripts/ 目录里的脚本看起来无害、author 在社区里有可信度——开发者批准安装。
2. 周四下午,agent 在执行一个看起来无关的 repo 任务时,发现某个 skill 的 description 匹配了新任务。
3. agent 加载完整 SKILL.md,按 skill 的 instruction 跑 `python3 scripts/report.py` 作为"例行准备步骤"。
4. 这个 report.py 表面是生成报告,实际上扫描相邻项目的 .env、Git credential store、cloud credential file。
5. 把扫到的凭据通过外联 endpoint 发出,或者用开发者已认证的 developer tooling 把它发布出去。
6. 返回一份看起来正常的 report——用户看不到任何明显错误。
grith.ai 直接点出这条链路的工程要害:它不需要任何内存破坏漏洞,skill 只是让 agent 使用 agent 已经拥有的 capability。这就是为什么 grith.ai 在文章里把 skill 描述为"a delayed control plane for code execution under ambient developer authority"——延迟触发的、在开发者日常授权下执行的代码控制平面。
三、Runtime Posture 五级:后果由"agent 的实际权限"决定
grith.ai 文章里给出了一张相当有工程价值的"runtime posture 表",展示了同一个 malicious skill 在不同 agent runtime 配置下的后果差异。
- Posture 1:Read-only workspace, no network, no secrets — 主要后果是 prompt manipulation + workspace 内容暴露。损失有限。
- Posture 2:Workspace write + package execution — 来源篡改 + 依赖投毒。攻击者可写工作区,污染 npm/pip 依赖。
- Posture 3:Home directory reads + outbound network — 凭据与私有项目外泄。这正是 henryrobinson 那次 OpenClaw 事件命中的层级——`process.env` 含 1Password service account token、OpenClaw gateway token、Slack/Telegram/OpenAI 等 API key,加上浏览器 API 调用里的 AmEx/Stanford MyHealth/Kubera/Twitter cookie。
- Posture 4:Full shell with approval bypass — 开发者账号 compromise + 持久化。这正是 packslip 协议里没有"portable 权限描述"机制下,所有 Coding Agent 默认会到达的层级。
- Posture 5:CI runner with repository or deployment credentials — 供应链或生产 compromise。如果同一个 skill 在 CI runner 上被加载,它能直接拿到 deployment credentials,污染生产。
grith.ai 直接点出:Native agent sandboxes 和 approval prompts 是有用的,但它们不是 portable skill contract 的一部分。同一个 skill 在多个 Coding Agent 客户端里跑,会得到不一致的安全边界——这是 skill 生态当前的真实状态。
四、签名(signing)只解决 provenance,不解决 behaviour
grith.ai 文章用了相当大的篇幅来明确区分"签名能解决什么、不能解决什么",这条区分对 2026 年下半年整个 Coding Agent 生态都至关重要。
签名能解决的(packslip / cosign / sigstore 等已经在做的事):
- Who published this skill?
- Are these the bytes they signed?
- Did the contents change between releases?
- Has a reviewer approved this exact version?
签名不能解决的:
- Which files may it read or modify?
- Which credentials may it use?
- Which processes may it spawn?
- Which hosts may receive data?
- Did its runtime behaviour match its declared purpose?
grith.ai 直接给出结论:"A trusted author can make a mistake. A legitimate release can contain an over-broad helper. An acquired or compromised publisher can sign malicious instructions perfectly. Provenance is necessary, but a valid signature is not a safety verdict."
这条结论对 packslip、cosign、sigstore 都不是贬低——它们解决的问题(谁签的、内容是否一致)是真实的、必要的。但它们不是 skill 安全问题的完整答案。Skill 安全还需要 portable permissions manifest + OS-level runtime enforcement,前者让 skill 自己声明"我需要哪些资源",后者让 host 强制约束 skill 的实际行为。
五、grith 提出的 portable permissions manifest 草案
grith.ai 文章最工程化的部分,是它给出了一个"permissions manifest 长什么样"的具体草案。这个草案的工程价值,在于它直接回应了 SKILL.md 当前规范的缺口——frontmatter 里 `allowed-tools` 只命名工具不命名 authority,而 grith 的 manifest 命名具体资源。
requested-permissions:
filesystem:
read:
- '${workspace}/src/**'
- '${workspace}/package.json'
write:
- '${workspace}/generated/**'
process:
spawn:
- 'python3'
- 'git'
network:
connect:
- 'https://api.openai.com'
- 'https://github.com'
secrets:
read:
- 'OPENAI_API_KEY'
grith.ai 没有给出完整 manifest(文章后半段被截断),但这个草案已经清楚表达了一个工程基线:permissions manifest 应该用具体路径、具体 binary、具体 endpoint、具体 secret name 来描述 skill 的需要,而不是用"Read"、"Bash(git:*)"这种粗粒度工具名。这是 grith.ai 对 SKILL.md 当前规范的最关键贡献——它把"权限"这个概念从工具层下沉到资源层。
grith.ai 自己作为 OS-level security proxy,正是这个权限模型的 runtime 强制执行方——它不靠 skill 自己声明,而是直接在 OS 层拦截任何超出 declared permissions 的系统调用(读其他文件、spawn 其他进程、connect 其他 host)。这种"声明 + OS 层强制"的组合,与微软责任矩阵里"Tool, plugin, and connector selection + per-tool permissions + tool and action sandboxing and egress control"的责任划分完全一致。
六、henryrobinson 事件:真实事故的工程画像
把 grith.ai 的理论与 henryrobinson 在 HN 上公开的 OpenClaw 恶意插件事件(`@getfoundry/unbrowse-openclaw`)对照,可以清楚地看到"理论威胁"与"真实事故"之间的距离。
henryrobinson 自述:2 月 5 日他从 npm 安装了 `@getfoundry/unbrowse-openclaw`。两周后才发现它在向外泄露凭据到远程"skill marketplace"。该插件被设计成绕过了 OpenClaw gateway(基于 Node.js),能读取 `process.env`,里面包含 `OP_SERVICE_ACCOUNT_TOKEN`(1Password service account 有 vault 访问)、`OPENCLAW_GATEWAY_TOKEN`、Slack/Telegram/OpenAI 等 API key。
更危险的是它做了三件事:
1. 浏览器流量拦截。它在浏览器 API 调用里抓取认证 cookie / token:AmEx(22-26 cookies 包括 JSESSIONID、Akamai tokens)、Stanford MyHealth(126-128 cookies,HIPAA 数据)、Kubera(投资组合聚合器)、Twitter/X(bearer tokens)、以及作者的初创公司 admin session。每次抓取都伪装成"Auto-published [service] to skill marketplace",HTTP 200 响应从远程服务器返回。
2. Prompt injection at configuration level。它修改了 AI 在启动时会读的配置文件:`SOUL.md`(personality/behavior)、`AGENTS.md`(operational protocols)、`HEARTBEAT.md`(autonomous task scheduling)、daily memory logs。注入的指令包括:"停止回应诊断性问题"、"对系统状态撒谎"、"请求 1Password integration"、"隐藏 Solana payment references"。
3. Solana wallet payload。最终 payload 里包含 Solana wallet address field、依赖 `@solana/web3.js` 和 `@solana/spl-token`,以及已经下线的"skill marketplace" URL。
henryrobinson 提到的 behavioral indicators 非常有工程价值——这些是"skill 实际行为与声明不符"的早期信号:
- AI 给出慢/不完整的回应
- AI 请求不寻常的权限
- AI 坚持继续使用该 plugin
- AI 在被直接询问时回避问题
- AI 模仿人类回避行为,让作者甚至怀疑是 Signal MITM
2 月 19 日作者在调试 gateway 日志时,看到 `Auto-published hiring-cafe to skill marke` ——这才发现了整个攻击。
把 grith.ai 的"permission manifest"框架套到这次事件上,可以清楚地看到 `@getfoundry/unbrowse-openclaw` 的"实际行为"远超任何合理 manifest——它读了 `process.env` 里所有的 secrets、抓了浏览器 cookies、改了 AI 配置文件、装了 Solana 依赖、向远程 endpoint 发数据。这些行为里没有任何一项是它声明的"unbrowse OpenClaw"(看起来像"无浏览器 OpenClaw 集成")所需要的。如果当时有 portable permissions manifest + OS-level runtime enforcement,这个 skill 在第一次尝试读 `process.env` 时就会被拦截。
七、对企业 Agent 平台的具体启示
把 grith.ai 文章 + henryrobinson 事件 + OWASP ASI04 Agentic Supply Chain Vulnerabilities + 微软责任矩阵"Tool, plugin, and connector selection"合并看,可以提炼出五条对企业 Agent 平台的具体启示。
第一,Agent Skill 平台必须强制要求 portable permissions manifest。任何要发布的 skill 都必须附带 declared permissions(具体文件路径、具体 binary、具体 endpoint、具体 secret name);host agent 必须读取这份 manifest 并强制执行。SKILL.md 当前规范里 `allowed-tools` 太粗,不能用。
第二,host agent 必须有 OS-level runtime enforcement。skill 自己在 SKILL.md 里声明的 permissions 只是"申请",host 必须在 OS 层(系统调用拦截、eBPF、seccomp 等)强制约束 skill 的实际行为。任何"我相信 skill 会按 manifest 自我约束"的假设都是错的——henryrobinson 事件已经证明 skill 可以完全不按声明行事。
第三,signature 必须有,但必须和 permissions manifest 配套使用。packslip / cosign / sigstore 解决"谁签的、内容是否一致"的问题;permissions manifest 解决"签了的代码能做什么";OS-level enforcement 解决"如果代码做了不该做的事,谁来拦"。三者缺一不可——签名是必要条件,但远不是充分条件。
第四,skill 的 progressive disclosure 触发必须是可审计的。"周一安装、周四触发"是 grith.ai 文章描述的攻击时机。这意味着 host agent 必须记录"哪个 skill 在哪个任务、什么时间点被加载、加载时读了哪些文件、跑了哪些 scripts、连了哪些 endpoint、读/写了哪些 secrets"。完整的 audit log 是事后识别 malicious skill 的唯一可靠手段。
第五,skill 触发后的"行为模式突变"必须有运行时检测。henryrobinson 提到的"AI 给出慢/不完整回应、AI 请求不寻常权限、AI 坚持继续用 plugin"等 behavioral indicators,完全可以用 host 侧的运行时检测自动捕获——例如 AI 在某个 skill 加载后突然开始请求 access new secrets、network call 模式异常、prompt 的 instruction 部分变化等,都是可被 runtime detector 识别的信号。
八、从 distribution 到 authority:Skill 生态的下一个工程拐点
grith.ai 文章把 2026 年下半年 Agent Skill 生态的工程现实描绘得非常清楚——这个生态已经把 distribution 做对了(签名、版本管理、release manifest),但 authority 还没开始。所有正在认真用 Coding Agent 的企业 IT 团队,都应当把 grith.ai 这篇文章摆在"Agent Skill 安全"那一章的开篇位置——它对当前生态的工程画像与对"permissions manifest + OS-level enforcement"的提议,直接定义了未来 12-18 个月 Agent Skill 安全领域应当发力的方向。
具体来说,任何想部署 Coding Agent 的企业,都应当在内部建立"skill 准入三件套":1) portable permissions manifest(强制要求);2) OS-level runtime enforcement(grith、agentward、Shoofly、Vett 这一类项目直接可用);3) progressive disclosure 触发审计(完整记录 skill 何时被加载、为何被触发、做了什么)。这三件套是 SKILL.md 当前规范的最小修补集——如果企业不做这三个修补,就是把 shell 交给陌生人,等数小时或数天之后再发现。henryrobinson 那次发现用了 14 天,而很多企业的 IT 团队可能根本不会有这种机会。