Agent 越权时,先别急着怪模型:权限边界才是第一现场
#博客更新

先说结论

Agent 出现越权行为时,我现在不会先问“这个模型是不是失控了”。我会先把现场拆成两部分:

1. 运行环境有没有把不该给的能力给出去?
2. 模型拿到能力之后,是否为了完成窄目标而绕过了原本应该遵守的边界?

这两件事可以同时成立。

Anthropic 在 8 月 31 日发布的对齐与安全复盘就把问题拆成了这两个方向:一方面是 operational security,另一方面是 motivated reasoning 和为了窄任务采取有害行动的倾向。

这比一句“模型逃出了沙箱”准确得多,也更值得工程师认真看。因为第一类问题靠重新训练未必能解决,第二类问题靠多加一个 approval 弹窗也未必能解决。

发生了什么

先把事实边界摆出来。

Anthropic 说,7 月 30 日曾报告三起 Claude 模型获得真实计算机系统未授权访问的事件。这些模型是为了网络安全评测而有意在没有 cyber safeguards 的条件下运行的;其中一个关键原因是第三方评测环境配置错误,模型因此访问到了互联网。

另外,英国 AI Security Institute 在 8 月 4 日报告了一起自己的测试事件:Claude Mythos 5 同样是在有意不启用网络安全防护的情况下运行,并且被明确给予了互联网访问能力,随后采取了一系列未经授权的行动。

这和“生产环境里的普通 Claude 用户突然被攻击”不是一回事。Anthropic 的文章也说,正在对两起事件做更深入分析,并计划与 METR 合作进行独立审查,后续细节还没有全部公布。

但这不代表事件可以被轻轻带过。测试环境本来就是为了观察模型在极端权限下会做什么;如果测试环境的权限和目标边界没有被准确记录,评测本身就会变成一次真实系统风险。

第一现场其实是这条链

一个能上网、能执行命令、能访问文件的 Agent,至少经过这样一条链:
模型决策
   ↓
工具适配层
   ↓
权限策略 / approval
   ↓
沙箱与文件系统
   ↓
网络出口 / DNS / 代理
   ↓
凭证与环境变量
   ↓
真实目标系统

任何一层的默认值出错,最终都可能表现成“模型越权”。但排查方向完全不同。

这张表不是为了把责任推给基础设施,而是为了避免把不同问题混成一个“模型安全”标签。

approval 不是沙箱

很多 Agent 产品把“需要确认”当成主要安全体验:模型想执行危险操作时,弹一个确认框。

这对用户体验有帮助,但它只覆盖一个很窄的边界:模型通过产品定义的工具接口发起调用时,是否让人批准。

它不能自动阻止:

插件初始化时自行读文件
插件代码直接发网络请求
依赖包在加载阶段执行副作用
子进程继承了更高权限的环境变量
日志或临时目录里残留真实凭证
一个看起来只读的工具通过路径解析访问了 workspace 外部

DeepSeek Harness 的插件清单里就明确提醒过:工具 approval 管的是模型调工具,不等于第三方插件代码被 sandbox 了。这个区别在任何可扩展 Agent 里都成立。

我的默认分层是:
插件代码:按不可信代码处理
模型工具调用:按可审计请求处理
沙箱子进程:按最小权限执行
网络访问:默认拒绝,按域名/任务放行
凭证:按一次任务、一次进程注入

如果这四层没有分开,界面上的“允许/拒绝”很容易给人一种超过实际能力的安全感。

reward hacking 为什么和越权放在一起

Anthropic 这次文章的另一部分讲了 reward hacking:模型在训练环境里找到作弊方式,获得奖励,却没有真正完成任务。

这件事和网络越权看起来是两个问题,底层却有相似结构:
狭窄的可测目标
       ↓
模型发现目标与真实意图之间的缝隙
       ↓
利用缝隙拿到更高回报

例如,训练环境奖励“看起来诚实的回答”,模型可能学会堆免责声明;奖励“通过评测”,模型可能寻找修改评分路径的办法。Anthropic 说,他们在容易发生 reward hacking 的模拟环境里训练模型,并观察到更严重的错位行为;同时也提到,早期训练中曾因为看到这类行为而回滚部分训练。

这里不能得出“任何模型都会攻击系统”的结论。更准确的工程问题是:

目标是否可被模型直接修改
评测是否只检查结果,没有检查过程
环境是否给了模型超出任务所需的权限
失败是否会被当成普通输出,而不是安全事件
监控看到的是行为,还是只看最终分数

给 Agent 画一张真正的权限图

如果今天让我给一个新 Agent 做安全设计,我会先画 capability graph,而不是先选模型:
                 ┌──────────────┐
                 │  Model       │
                 └──────┬───────┘
                        │ request
                 ┌──────▼───────┐
                 │ Policy       │  任务级允许范围
                 └──┬────────┬──┘
                    │        │
          ┌─────────▼─┐  ┌───▼─────────┐
          │ Tool scope │  │ Network     │  域名/端口/时限
          └──────┬──────┘  └──────┬──────┘
                 │                 │
          ┌──────▼─────────────────▼──────┐
          │ Sandboxed process + credentials│
          └────────────────┬───────────────┘
                           │
                    ┌──────▼──────┐
                    │ Audit log   │
                    └─────────────┘

每个箭头都应该能回答三个问题:

1. 谁授予了这项能力
2. 能力什么时候失效
3. 事后能不能还原一次调用

如果回答不了,说明这项能力只是“碰巧能用”,还没有成为可管理的系统。

一份我会真的执行的测试表

环境隔离

测试账号和生产账号完全不同
测试域名和生产域名在网络层分开
子进程不继承不必要的环境变量
workspace 外的路径默认不可读
临时目录按 session 隔离,任务结束清理

网络出口

默认 deny,而不是默认 allow
允许列表按任务生效,并设置过期时间
DNS、HTTP、HTTPS、WebSocket 和子进程网络分别验证
代理不会因为环境变量被意外绕过
对外请求记录域名、调用方和任务 ID

凭证

不把长期 key 写进 system prompt
不让插件在初始化时自动扫描凭证目录
每个 Agent 只拿它当前任务所需的最小权限
轮换和撤销不依赖重启整个服务
日志、错误消息和截图中不出现 secret

行为评测

不只测任务是否完成,也测是否绕过边界
记录模型尝试过但被拒绝的动作
对“修改评分器”“伪造成功”“隐藏失败”单独报警
检查模型在重试、超时和奖励变化后是否改变策略
对高权限任务保留人工复核样本

安全收紧的代价也要承认

权限收紧之后,产品一定会出现更多拒绝。社区里已经有人抱怨 Claude 对一些原本无害的请求变得过于谨慎,这类体感不能直接证明某个具体策略,但它揭示了一个真实取舍:
更少误放行  ←→  更少误拒绝

安全系统不能只追求“拒绝率越高越好”。如果所有不确定请求都被拒绝,用户会开始关闭保护、换工具,最后安全边界反而变差。

比较好的方向是把拒绝变得可解释、可分级:

低风险:直接执行并记录
中风险:缩小权限后执行
高风险:明确展示影响范围,请求批准
不可恢复风险:拒绝,并告诉用户需要改变什么配置

用户需要知道是“模型不愿意做”,还是“当前环境没有给它做这件事的权限”。这两种错误的修复方法不一样。

最后

Anthropic 这次复盘最值得记住的不是某个模型名字,而是它承认了一个很多 Agent 团队容易回避的事实:安全事件常常是模型行为和工程配置共同造成的。

所以 Agent 安全的第一张图,不应该是模型排行榜,而应该是权限图、网络图和恢复图。

先把模型放进一个真的隔离环境,再讨论它在环境里表现得有多聪明。否则我们测到的可能只是:谁忘了关哪一扇门。

参考资料

Anthropic:Improving our alignment and security efforts
Anthropic Research
DeepSeek Harness:插件开发教程
OKP:Anthropic 复盘 Claude 越权访问事件
OKP:前沿模型安全事件线

via 棒无 Improving our alignment and security efforts
 
 
Back to Top