ARTICLE · 1047159
Hermes 源码解读十一:权限、审批和沙箱,让 Agent 动手之前先有边界
全文约 1750 字,读完大约 3 分钟。
Hermes 源码解读十一:权限、审批和沙箱,让 Agent 动手之前先有边界
Agent 真正危险的地方,不是它会说错话。
而是它会动手。
它能跑命令、改文件、访问网络、调用浏览器、执行脚本、发消息、创建定时任务。
这些能力一旦接上,系统就不能只靠一句“请谨慎操作”。
我读 Hermes 的安全相关源码时,最明显的判断是:
Hermes 把工具执行当成有副作用的操作来治理,而不是把审批当弹窗功能。
这篇看 tools/approval.py、agent/tool_guardrails.py、tools/environments/*、tools/path_security.py、tools/tirith_security.py、docs/security/network-egress-isolation.md。
审批不是一层,而是多层

很多 Agent 项目处理危险命令,做法是:
检测到危险命令,问用户要不要继续。
Hermes 复杂得多。
它至少有这些层:
hardline block → yolo / approval mode 判断 → dangerous command detection → Tirith 扫描 → smart approval → CLI / Gateway approval surface → session/permanent approval cache这里最重要的是第一层:hardline block。
源码里明确有一些命令会被无条件阻断。
比如 rm -rf /、mkfs、对裸设备写入、shutdown/reboot、fork bomb、kill -1 这类。
它们在 yolo 之前就被拦。
这个顺序非常关键。
yolo 不是系统底线的绕过券。
用户可以选择减少确认,但不能让系统执行明显不可恢复的灾难命令。
这是安全系统里很成熟的思路:
可恢复风险 → 可以审批 不可恢复风险 → 直接阻断Gateway 审批不是弹窗,而是异步会话流程
CLI 里审批相对简单,终端里问用户即可。
Gateway 就复杂多了。
用户可能在 Telegram、Slack、Discord 或其他平台上发起任务。
Agent 在线程里跑到一半,命令需要审批。
这时不能让后台线程傻等一个不存在的 stdin。
Hermes 在 approval.py 里有 Gateway approval queue。
它会把 approval request 发回对应会话,Agent 线程阻塞等待用户 /approve 或 /deny,同时还要考虑 timeout、hook、session activity、清理队列。
这说明审批是运行时协议的一部分。
不是 UI 细节。
如果你做多平台 Agent,这点很重要:
审批结果必须能从用户所在的平台回到正在执行的 Agent 线程。
否则 Gateway 场景下的安全交互会断掉。
Tool guardrail 防的是“模型一直撞墙”
审批主要处理危险。
agent/tool_guardrails.py 处理的是另一类问题:模型重复调用同一个失败工具,或者一直没有进展。
比如:
• 同一个命令失败 5 次; • 同一个工具路径无进展; • 重复读取不存在的文件; • 一直用相同参数调用失败 API。
Hermes 会生成 synthetic tool result,告诉模型不要继续重复这条路径。
这类 guardrail 不像安全审批那么显眼,但非常实用。
因为 Agent 失败时经常不是“想作恶”,而是卡在一个错误循环里。
对长任务来说,防止无意义重复,也是稳定性的一部分。
沙箱不是一个开关,而是一组后端
Hermes 的 terminal backend 不只有 local。
tools/environments/ 下面有 local、docker、ssh、modal、daytona、singularity 等后端。
不同后端的风险边界不一样:
Hermes 在 approval 里也会考虑 env_type 和 host access。
如果 Docker sandbox 绑定了宿主路径,就不能简单认为“容器里执行所以安全”。
这点很现实。
很多团队把 Docker 当绝对安全边界,但一挂载项目目录、SSH key、Docker socket,风险就回来了。
沙箱不是标签。
沙箱要看它实际能碰到什么。
路径安全是小细节,也是大问题

tools/path_security.py 里有 validate_within_dir() 和 traversal 检查。
这类代码看起来很基础,但在 Agent 场景里很重要。
因为模型生成路径时,很可能出现:
../../.ssh/id_rsa ~/.env /etc/passwd如果某个工具本来只允许访问 skill 目录、scripts 目录或 workspace,必须用 resolved path 检查它是否仍在允许根目录内。
字符串前缀判断不够。
要处理 symlink、..、绝对路径、home expansion。
Hermes 在 skills linked files、cron scripts 等地方都能看到类似边界。
这说明安全不是只在 terminal 命令上做。
每一个能读写路径的工具都需要边界。
网络出口隔离是另一层防线
Hermes 的安全文档里有一篇 Docker network egress isolation。
它讨论的是:即使 Agent 在容器里执行,如果默认 network_mode: host,命令仍然可以访问外网。
Prompt injection 最典型的攻击之一,就是诱导 Agent 通过 curl/wget/raw HTTP 把敏感信息发出去。
网络出口隔离的思路是:
agent core 在 internal 网络 需要外网的 gateway / proxy 在 egress 网络 出站走 allowlist proxy这不是替代 sandbox。
它是第二层。
就算命令被执行了,也不应该默认能访问任意外部地址。
对企业 Agent 平台来说,这一层非常关键。
这套安全设计给我的启发
Agent 安全不能只靠一个“确认按钮”。
至少要分层:
这里面每一层都不完美。
但叠在一起,系统才有可能接近可用。
我的判断是:
Agent 越能干活,安全边界越要靠运行时设计,而不是靠提示词约束。
提示词可以提醒模型。
但真正执行命令的是工具系统。
真正能阻断危险的是 approval、hardline block、sandbox、path validation、network policy。
Hermes 不是一个完美安全系统,但它的源码至少在认真面对这个问题。
这也是从 demo 走向运行时必须补上的一课。
前面拆了入口、主循环、工具、Prompt、Provider、Gateway、Session、Plugin、Skill、Cron 和安全边界。最后要把它们放回一个更现实的问题:
如果我们要搭一个个人或小团队 AI 工作流系统,Hermes 这些设计到底哪些值得借鉴,哪些不该一开始就照搬?
如果你正在让 Agent 真正操作你的机器,建议先收藏这一篇。功能越强,越要先问清楚边界在哪里。
