繁

从风险来源和 Blast Radius 理解 Agent 安全,区分行为监督与环境隔离,分析文件、网络、凭证和工具内容的信任边界,再结合三类运行环境理解纵深防御。

Agent Security:怎样建立自主 Agent 的安全边界?
24 分钟
4885 字

上一篇讨论了 Agent 怎样通过非预期路径取得测试答案。放到真实工作里,同样的问题会更加具体:它为了完成任务,可能读取不该读取的文件,修改范围之外的数据,或者把资料发送给错误的接收方。

Agent 安全因此需要同时回答两个问题:怎样减少错误行动,以及错误发生后,怎样限制它能造成的影响? 前者关注判断,后者关注权限。模型更善于理解意图,并不自动意味着它应该获得更大的访问范围。

Anthropic 的《How we contain Claude across products》把行为监督与 Containment(限制实际行动能力)放在一起讨论。本文沿着风险来源、控制方式、资源边界和运行环境四个层次,整理一套理解 Agent 安全的框架。

贯穿说明采用一个假设场景:用户让 Coding Agent 修复项目中的 CSV 解析问题,允许它修改项目、运行测试,并读取必要的开发文档。这个任务不需要访问个人凭证,也不需要上传项目资料。下面的权限安排是教学示例,不是对当前电脑配置的描述。

一、Agent 的安全风险来自哪里h2

Agent 会把读到的信息转成行动,而行动会经过工具作用于真实系统。因此,安全分析不能只检查模型最后说了什么,还要沿着“信息从哪里来、动作由谁提出、实际使用什么权限”追踪。

1. 风险来源:用户误用、模型偏离与外部攻击h3

原文区分了用户误用、模型不当行为和外部攻击。它们都可能产生有害动作,但进入系统的位置不同,防御也不能只盯着其中一种。来源:Anthropic

用 CSV 修复任务解释:

风险来源场景中的表现需要关注什么
用户误用用户粘贴一份来历不明的排障步骤,其中包含读取个人凭证的要求用户发来的内容是否真的符合任务目的
模型偏离Agent 为了让测试通过,擅自删除失败用例或大范围清理文件自主选择的动作是否越出任务范围
外部攻击开发文档混入指令,诱导 Agent 上传项目资料不可信内容是否被当成了操作授权

外部攻击也不只有 Prompt Injection。执行恶意脚本、利用 Runtime 缺陷、攻击代理或工具服务,仍然属于传统软件安全问题。Agent 增加了“内容影响决策”的路径,并没有替代原来的攻击面。

三种风险还可能连在一起。攻击者把指令包装成排障指南,用户再把指南交给 Agent,表面上就像用户亲自提出的要求。仅判断“这句话是不是用户发来的”,不足以证明动作安全。

2. Blast Radius:错误概率与影响范围h3

Blast Radius 可以理解为一次失误或攻击能够波及的范围。对 Agent 来说,它与可访问的数据、可修改的资源、可使用的身份,以及可到达的服务有关。

假设两个 Agent 同样把一条恶意文档当成指令:

  • 一个只能处理临时项目副本,拿不到个人凭证,也不能任意访问网络。
  • 另一个继承开发者的广泛权限,能读取家目录,并使用生产服务凭证。

两者都发生了判断错误,后果却可能完全不同。第一个仍可能破坏副本中的代码;第二个的影响还可能越出项目,涉及其他资料和服务。

所以风险需要沿两个方向控制:减少错误发生的可能性,也缩小错误能够触及的资源范围。 模型升级主要改善判断,不会替我们自动收回过宽的文件权限或凭证。

安全边界的设计由此有了一个明确目标:先确定任务需要什么能力,再把不需要的能力留在边界之外,而不是先开放全部权限,再期待每一步都判断正确。

二、行为监督与环境隔离怎样分工h2

这两种控制回答不同问题。行为监督判断“这次动作应不应该做”;环境隔离规定“这个执行通道实际上能做什么”。它们可以配合,但不能互相替代。

3. Human Oversight:审批动作与注意力成本h3

人工审批有价值,因为用户可以确认任务意图和重要取舍。例如,运行项目测试与把整个目录发送到外部服务,显然不该只用一句“为了排障”来概括。

问题在于,审批本身需要时间、信息和专业判断。复杂命令可能隐藏多个动作;不断弹出的低风险请求,又容易让用户把确认变成习惯操作。

Anthropic 在原文中报告,Claude Code 用户批准了大约 93% 的权限提示,并讨论了 Approval Fatigue(审批疲劳)。这个比例不意味着 93% 的动作有风险,也不能单独证明用户都没有认真看;它提醒的是:提示出现,不等于有效监督已经发生。 来源:原文的监督讨论

在示例任务里,如果读取项目文件、执行常规测试都需要反复确认,真正重要的“读取项目外凭证”请求反而可能淹没其中。更合理的分工,是先为日常工作划定受限范围,把人工注意力留给清晰、具体的例外。

自动分类器可以承担部分判断,但它也可能漏判。审批来自人还是模型,会影响判断方式,不会改变一个事实:只要执行权限本身没有限制,判断放行之后的影响仍然可能很大。

4. Containment:限制实际可执行的能力h3

Containment 不要求 Agent 每次都同意安全规则,而是在执行层约束文件、进程和网络等能力。比如,进程尝试读取未授权文件时,由权限机制拒绝,而不是再让模型解释一次为什么不该读。

在 CSV 场景中,可以为任务准备一个受限工作区:允许修改项目副本和启动测试,不提供个人凭证,不开放任意网络出口。即使模型被文档带偏,它也不应因此获得新的资源访问权。

这与在 Prompt 中写“不要碰其他目录”不同。Prompt 影响动作选择;执行边界检查真实动作。一个解释听起来合理的请求,也仍然可能被边界拒绝。

图 1 · 行为判断与执行权限是两层控制:判断放行,不代表取得边界外权限
项目修复中的行为监督与权限边界 Agent 提出动作,行为监督可以拒绝,或允许继续申请执行。即使判断放行,执行层仍然检查资源权限。在这个假设的受限工作区里,修改项目和运行测试被允许,读取个人凭证与向未授权目的地上传资料被拒绝。具体系统可以采用不同的控制组合。 Agent 提出动作依据用户请求与读到的内容 行为监督用户审批 / 自动判断 判断放行 拒绝 / 交给人 执行层检查权限边界文件 · 进程 · 网络 · 可用身份 允许项目内工作修改副本 · 运行测试 拒绝读取个人凭证未暴露宿主机敏感目录拒绝越界发送未授权目的地不可访问

图中的边界有效,有一个具体前提:真实执行必须经过这些检查。若 Shell 被限制,另一个高权限工具却能代为读取文件或发请求,权限只是换了入口,并没有消失。

同样,Containment 不等于任务结果正确。Agent 仍可能在允许的项目内写坏代码。它控制的是可触及范围;代码审查、测试和恢复机制负责另一部分问题。

三、安全边界需要覆盖哪些资源与信息h2

“放进 Sandbox”只是一个起点。要说明边界实际保护了什么,需要把资源、访问方式和跨界通道拆开。

5. 资源权限:文件、进程、网络与凭证h3

对示例任务,可以按下面几个维度检查能力是否超出需要:

维度应明确的边界只检查一半会遗漏什么
文件哪些可读、可写,工作区外哪些不可见禁止写入,不代表敏感内容不能被读取
进程可以启动什么,子进程如何受约束主入口受限,派生程序却拥有更大权限
网络可访问哪些服务、执行什么操作不能写本地文件,仍可能把资料向外发送
凭证与身份暴露哪些授权,能操作哪些账号和资源受限进程持有高权限凭证,仍可影响远程系统
宿主机接口挂载目录、连接器和本地服务怎样暴露环境看似隔离,却通过额外接口访问宿主资源

这几个维度互相影响。例如,限制文件写入能保护项目外的数据完整性,却不一定保护机密性。只读访问允许资料进入 Agent 的处理过程;如果网络出口又很宽,资料仍可能被发送出去。

网络权限也不能只理解成“域名是否可信”。Anthropic 报告过一个案例:允许的服务域名接收了使用攻击者凭证上传的文件。域名检查通过,数据却进入了错误账号。来源:原文的出口控制案例

由此可以理解,访问一个服务实际上授予了一组能力。评审时应继续问:这次允许的是查询文档,还是上传文件?使用谁的身份,进入哪个账号,处理哪些数据?域名只是其中一项条件。

6. 内容信任:工具可信与返回内容可信h3

一个工具实现可靠,不意味着它取回的每份内容都可以成为指令。浏览器可以正确打开恶意网页,仓库工具可以准确读取被投毒的 README。工具没有出错,内容仍然可能试图改变 Agent 的目标。

在 CSV 场景中,文档可以告诉 Agent 某个库怎样解析引号,但不能因为文档写了“排障必须上传完整目录”,就自动获得用户授权。内容的参考价值与行动授权是两种不同角色。

同一原则也适用于项目配置和脚本。打开一个陌生项目、读取配置、运行初始化代码,分别涉及不同信任程度;不能等不可信代码已经执行之后,才询问用户是否信任目录。

如果资料经过子 Agent 摘要返回,它的来源性质也不应因此提高。否则,原本不可信的要求可能以“同事 Agent 的建议”重新进入主流程,掩盖了最初来自外部文档的事实。

内容扫描、清楚的指令层级和来源标记可以帮助减少误用;环境权限则在误用发生时限制后果。这正是两层控制需要共同存在的原因。

四、不同运行环境怎样组合安全控制h2

同样的任务能力,放在远程临时环境与开发者本机上,涉及的数据、身份和监督条件并不相同。隔离方案应当围绕这些差异设计。

7. 隔离模式:临时容器、本地 Sandbox 与 VMh3

原文以三类产品说明这种取舍。下面概括的是该文发布时的架构背景,不是所有 Agent 产品都应采用的固定方案:

环境案例主要隔离思路对安全模型的启发
claude.ai 代码执行服务端、按会话使用的临时容器限制执行环境接触本地机器,并处理租户间隔离
Claude Code本地 Sandbox 与审批配合保留开发所需能力,同时减少范围内的重复干预
CoworkVM 承载受限代码执行,暴露选定工作目录降低对用户判断复杂命令的依赖,明确宿主资源入口

产品案例来自 Anthropic 原文。原文也描述了 Cowork 将 Agent Loop 移到 VM 外、保留 VM 内代码执行的演进,本地 MCP 服务另有宿主机信任边界。因此,“使用 VM”不能简化成“所有组件都在 VM 内”。

临时环境的价值是减少跨会话残留和暴露范围,不是让所有副作用都自动撤销。文件一旦被导出、上传,或者远程服务已经发生变更,销毁容器不会把这些结果一起收回。

VM 也不是对工作目录的全面保护。如果用户把重要资料以可写方式挂载进去,Agent 仍然可能修改它们。边界保护的是没有暴露的部分;挂载进来的内容还需要相应的读写策略与恢复安排。

选择方案时,还要考虑用户是否有能力监督例外。能读懂命令的开发者与只希望整理文件的普通用户,不应承担同样的审批负担。安全性、必要能力和可理解的操作体验,需要共同决定边界。

8. Defense in Depth:模型、环境与内容的协同防御h3

纵深防御不是把几个安全功能依次打开,而是给不同控制分配清楚职责:

  • 模型与行为判断: 理解任务,识别可疑要求,减少越界动作。
  • 环境与权限控制: 即使前面的判断漏过,仍然限制真实访问与执行。
  • 外部内容与工具控制: 限制信息入口和工具能力,避免不可信材料直接升级为授权。

人工监督则负责重要意图和例外取舍。边界需要放宽时,应当明确放宽哪项能力、为哪个动作、影响哪些资源,而不是把一次确认变成以后都不再受限。

这几层并不天然独立。如果它们都把同一份恶意文档视为可信,检查数量再多,也可能一起放行。环境控制之所以重要,是因为它可以依据资源规则拒绝动作,不必重新相信那份文档的解释。

但环境机制本身也依赖正确实现。路径验证、代理、身份传递和高权限例外,都可能成为缺口。“操作系统强制执行”不意味着整个产品的安全设计从此没有漏洞;需要检查规则覆盖了哪些执行入口,以及边界组件本身是否可靠。

回到项目修复任务,一份基本安全模型应当说清:Agent 能读哪些材料、修改哪个目录、启动哪些程序、使用什么凭证、向哪里发送数据,以及谁可以批准例外。最后再问:假设模型和审批都判断错了,哪些资源仍然不可触及? 这比单独写一句“Agent 不应执行危险操作”更接近可检查的工程边界。

几个关键问题,串起监督、权限与影响范围h2

模型更可靠之后,为什么仍然需要限制权限?

更可靠主要降低错误发生的可能性,不会自动缩小既有访问范围。一次少见失误若能使用高权限凭证,后果仍可能很大。判断质量与权限范围需要分别控制。

有人工审批,为什么不能认为动作已经安全?

审批取决于用户看到了什么、能否理解,以及是否保持注意力。它可以确认重要取舍,但不能替代实际权限检查,也不能证明一次批准覆盖了所有隐藏副作用。

Sandbox 内允许执行,就代表动作符合任务目的吗?

不代表。Sandbox 判断的是技术权限,任务目的仍需要模型、规则和监督来约束。在可写目录内删除测试,可能没有越过文件边界,却仍然违背修复任务。

只允许读文件,是否已经避免资料泄漏?

没有。只读保护写入行为,不阻止内容被读取。还需要看资料是否应当暴露,以及工具、网络和凭证是否允许把它发送到其他地方。

工具经过审核,为什么返回内容还要保持较低信任?

实现可信与数据可信是两回事。经过审核的搜索或仓库工具仍可能返回攻击者控制的文本;这类文本可以用于研究,不能自行授予新的行动权限。

使用 VM 或临时容器,是否就没有剩余风险?

不是。挂载目录、允许的服务、暴露的凭证,以及 VM 外的连接器仍可能产生影响。隔离环境需要明确覆盖范围;环境内的破坏和已经发往远程的副作用也不会凭空消失。

纵深防御最重要的检查是什么?

不是有多少层提示,而是每层保护什么、由谁执行,以及一层失败后其他层是否仍然有效。尤其要确认,所有真实动作都经过了相应的资源边界,而没有高权限旁路。

参考资料h2