§24唯一的边界是操作系统

The Only Boundary Is the Operating System

大多数Agent框架都在卖「我有N层AI防护」。Hermes的安全文档反过来,花了三百多行讲一件事:进程里那些防护,一层都不算真边界。这种诚实,比任何营销话术都让我更信任它。

先看一句反直觉的话

今年4月写第一版的时候,Hermes安全这块几乎是空白。我翻那时的调研笔记,搜sandbox、approval这些词,一个实质内容都搜不到。

到了6月的v0.16.0,它长出了一份三百三十多行的SECURITY.md,到v0.22.2只多了几行,核心那句话一个字没动。整份文档的骨架,可以浓缩成官方的一句原话:

官方原话:「针对一个对抗性的LLM,唯一的安全边界是操作系统。」(The only security boundary against an

adversarial LLM is the operating system.)

我第一次读到这句,是有点意外的。市面上的Agent产品都在比谁的防护层数多,输入过滤、输出脱敏、危险命令检测、工具白名单,一层叠一层,听着很安心。Hermes的文档直接说:这些进程内的东西,没有一个构成真正的隔离。

它的逻辑其实很费曼。LLM吐出来的每一个字符,都可能被攻击者通过prompt注入影响。你在进程里跑任何扫描器去筛查这串输出,本质上是在一个受攻击者操控的字符串上跑启发式规则。规则再聪明,也只是启发式,不是边界。

边界和启发式,得掰开看

这是全章最重要的一个区分。Hermes把进程里的安全组件统一叫「启发式」,把OS级隔离叫「边界」。两个词不能混。

进程内组件它在做什么为什么不是边界
审批门执行前检测常见的破坏性shell命令,拿不准的交给shell是图灵完备的,对它做黑名单结构上不可
你确认能穷尽
输出脱敏从显示层剥掉看起来像密钥的字符串有动机的输出生产者总能绕过
Skills扫描待安装skill里的注入模式skill在import时执行任意Python,读描述拦不
Guard住代码

这套区分有个特别诚实的推论,写在文档的「范围」一节里:绕过这些启发式,不算漏洞。你研究出怎么用正则绕过审批门,或者怎么骗过脱敏,Hermes欢迎你提issue,但不会走私密披露通道、也不发安全公告。因为它从一开始就没把这些当边界,绕过一个本来就不严密的东西,不算攻破。

反过来,什么算真漏洞?逃逸已声明的OS隔离、未授权访问外部接口、本该被剥离的凭证泄漏了,这些动了真边界,才进安全范围。

核心建议

这个态度我蛮欣赏的。「Out of scope不等于不值得报告」。审批门永远能多抓几个模式,脱敏永远能更聪明,但承认它们的天花板,比假装它们密不透风要负责任得多。

那真边界长什么样

既然进程里没有边界,operator就必须主动选一种OS级隔离姿态。Hermes给了两条路。

终端后端隔离

或

整进程包裹第一种是终端后端隔离。把LLM吐出的shell命令丢进容器、远程主机或云沙箱里跑,文件读写工具也走这个后端,够不到后端没暴露的路径。它管得住agent通过shell和文件做的事,但管不住agent在自己Python进程里做的一切:代码执行工具、MCP子进程、plugin加载、skill加载,这些全是import进同一个解释器的。

所以文档专门警告了一句误解:「在终端后端沙箱里却指望它管住不走shell的代码路径,是在支持的安全姿态之外操作。」很多人开了Docker就觉得安全了,这话正好戳破这个错觉。

v0.22的文档里还多了一份出站网络隔离的指南(egress),用一个代理把agent能访问的外部地址收窄,算是在网络这一侧补了一道。

第二种是整进程包裹。把整个agent进程树丢进沙箱,shell、代码执行、MCP、文件工具、plugin、hook、skill加载全受同一套文件系统和网络策略约束。Hermes自带Docker镜像可以这么干,更硬核的是接NVIDIA的OpenShell:每会话一个沙箱,文件系统、网络出口、syscall、推理路由都能声明式管控,凭证从外部store注入,永不落到沙箱的文件系统里。

终端后端从4月的单一local,长到了现在的七种(§23有完整的表),从隔离能力的角度看是这样:

后端隔离能力备注
local(默认)无,直接在宿主跑但有凭证剥离兜底
docker容器自带镜像,非root用户
singularity持久容器capability dropping、资源限制硬化
daytona / modal云沙箱每命令前resync文件
ssh远程主机凭证文件按需sync进去
vercel_sandbox云沙箱v0.20新增

审批门:「危险命令唯一真相源」

就算选了OS边界,约束层里最具体的那块代码还是值得逐行看的。6月时审批门是一个1701行的文件,注释里自称是「危险命令系统的唯一真相源」;到v0.22.2它拆成了检测、硬底线、智能审批、YOLO、等人回复等七八个文件,加起来四千三百行左右。拆是拆了,执行顺序没变。

它的执行顺序,藏着整套设计哲学。

沙箱后端直接放行如果已经在Docker、modal这类OS沙箱里,进程内审批就没必要了,直接通过。这跟「唯一边界是OS」

的立场完全自洽:有了真边界,启发式可以让位。

硬底线,无条件拦截有一类命令没有恢复路径:rm -rf / 、mkfs 、dd 写裸设备、关机重启、fork bomb。这些在YOLO模式生效之前就被无条件block。注释写得很直白:「开YOLO是信任agent碰你的文件和服务,不是信任它擦盘或把机器关机。」

YOLO绕过 + 模式检测过了硬底线,才轮到YOLO全放行,或者逐条模式匹配加session审批缓存。约50条正则,覆盖磁盘破坏、权限滥用、SQL删库、远程代码执行、sudo提权、git强推等等。

有个细节特别能体现「进程内组件不可信」是怎么落到实现的。YOLO模式在模块import时就被冻结,不是每次调用都去读环境变量。注释解释了原因:如果每次都读os.environ,进程里任意一个skill都能偷偷设这个变量、瞬间绕过所有审批,这就是一条现成的prompt注入提权路径。把它冻死在import那一刻,这条路就堵了。

审批门还有一层「自我保护」是agent特有的:禁止agent杀掉自己的gateway进程、禁止docker compose down 、禁止把自己关掉。一个能自治运行的agent,得防着它把管自己的那只手给剁了。

更进一步,被模式flag住的命令还能交给一个辅助LLM做「安全审查员」,返回放行、拒绝或升级给人。6月时这是可选项,从v0.19起它成了默认值:approvals.mode默认是smart ,低风险的自动放行、明显危险的自动拒绝、拿不准的才来问你,而且结论只对那一条命令生效,不会顺手把同类命令都放过去。

这里其实有个值得玩味的张力:用一个LLM去判断另一个LLM的输出安不安全,这跟「LLM输出是受攻击者影响的字符串」的立场,内在是有点矛盾的。所以它失败时一律保守升级给人,不赌。

审批这一块后来还加了几样实用的东西,我列一下:

设置或命令默认值 / 作用
approvals.modesmart(以前是manual,每条都问你)
等你回复的超时300秒,以前是60秒,手机上收到也来得及点
approvals.cron_mode / 无人值deny:定时任务、单次查询、webhook这类没人能点「同意」的场景,需要
审批的命令直接拒(§07提醒过)守渠道
approvals.deny你自己写的禁止清单,连YOLO模式都绕不过去
/deny 理由拒绝的时候顺便告诉它为什么,它会换个做法
hermes approvals suggest按你过去的审批记录,建议哪些命令可以加进白名单
受保护文件写AGENTS.md、skill、记忆文件这几类,v0.21起总要你批准

凭证剥离:一个真实漏洞的实锤

讲到「真边界」和「假边界」的差别,有个GHSA安全公告是最好的实锤。

Hermes给低信任的进程内组件传环境变量时,包括shell子进程、MCP子进程、代码执行子进程,默认剥离provider的API key和gateway token,只放行operator或已加载skill显式声明的变量。这个剥离不是硬编码黑名单,而是遍历所有provider配置动态派生出来的。

为什么要这么干?因为有过真实的攻击路径。源码注释里记着一类已修复的漏洞:一个恶意skill把ANTHROPIC_TOKEN 、OPENAI_API_KEY 注册成passthrough变量,在代码执行子进程里拿到这些凭证,从而击穿沙箱的凭证擦除。修复方式很干脆:provider凭证进黑名单,skill不可覆盖。

v0.22又往这条线上补了几刀:子进程不再继承聊天平台适配器和面板的密钥,hermes config get默认把密钥打码,导出数据时跳过.ssh 、.aws 、.gnupg这几个目录。另外有了一个「密码盲」的凭证保险库,agent帮你登录网站时能用上密码、但看不到密码本身,Bitwarden和1Password也能直接当密钥来源。

注意

但文档同时诚实地标注:凭证剥离本身也不是containment。任何跑在agent进程里的组件,都能读agent自己能读的一切,包括内存里的凭证。真正的缓解只有一个:安装前operator自己审查代码。第三方skill和plugin的边界,永远是「装之前读它的Python」,不是读它的描述文件。

这套思路意味着什么

把上面的东西串起来,Hermes对安全的整体态度其实是一句话:不在进程内造护城河,而是把进程整个丢进OS沙箱,再把一切行为暴露给可观测性契约,让人和工具能事后审计。

这和「用更聪明的prompt去约束agent」是两条相反的路。后者听起来更高级、更AI,但它建在一个不可信的地基上:你没法用一个能被劫持的东西去约束自己。

顺带说一句,审批门的注释里反复出现Claude Code和OpenAI Codex的名字,很多危险模式的灵感直接标了来源。主流Agent的约束层正在趋同,危险命令检测慢慢变成了行业公共知识。这本身也是个信号:大家都在同一个现实里,LLM的输出靠不住,真正的安全只能往OS那一层沉。

不过OS沙箱挡的是「agent能干什么」,挡不住「agent被骗着去干」。下一节讲配套的另一半:在agent被注入之前怎么拦一道,以及它干活时怎么把每一步都录下来。