我们如何在各产品中约束Claude
How we contain Claude across products
Anthropic工程团队发布关于其agent产品(claude.ai、Claude Code、Claude Cowork)安全遏制架构的技术报告。报告将agent安全风险分为用户滥用、模型行为不当、外部攻击者三类,并针对环境、模型、外部内容三层实施防御。数据显示Claude Opus 4.7在Gray Swan红队benchmark上单次攻击成功率约0.1%,Claude Code沙箱使权限提示减少84%。文中详述了虚拟机隔离、出口控制等机制及两起数据外泄事件。作者为Max McGuinness等五人。
十二个月前,我们还会断然拒绝让Claude拥有足以关闭Anthropic内部服务的访问权限。而如今,这种级别的访问已是常态,Anthropic的开发者们也因此效率更高。这些部署的风险包含两个部分:故障发生的可能性有多大,以及一旦发生能造成多大损害。安全防护和模型训练方面的进展稳步降低了前者;而后者——理论上的爆炸半径——则随着能力和访问范围的扩大而不断增长。然而,当agent能够胜任曾经需要一个人甚至一个团队才能完成的工作时,不部署的代价也变得足够大,以至于只要产品能够确保安全,风险收益的天平就会大幅倾向于采用。工程问题就变成了如何限制爆炸半径。
大致有两种方法可以做到这一点。
第一种是通过人在回路中来监督agent的行为。Claude Code此前通过在每一步都请求用户许可来防止agent采取非预期行动。理论上这可行,但我们发现这种方法容易出错。我们的遥测数据显示,用户批准了大约93%的权限提示。用户看到的批准请求越多,他们对每个请求的关注就越少,久而久之,他们的监督就会变得不那么尽职。我们最近构建了Claude Code自动模式,它自动化了更安全的批准流程,以减少这种批准疲劳。尽管如此,漏洞依然存在——任何概率性防御都有非零的漏检率。
第二种限制爆炸半径的方法——也是本文的重点——是遏制(containment)。我们不监督agent做什么,而是通过强制执行访问边界来监督它能做什么,例如通过沙箱、虚拟机和出口控制。这是Anthropic工程团队投入最多精力的地方,也是许多最令人惊讶的安全故障发生的地方。
在过去两年里,我们发布了三款主要的agent产品:claude.ai、Claude Code和Claude Cowork。每款产品服务于不同的受众,需要不同的遏制架构。本文分享哪些方法行之有效,哪些出了问题,以及我们在此过程中学到的关于agent安全的知识。
agent面临的安全风险分为三类:
用户滥用:用户——无论是恶意还是粗心——指示agent做有害的事情。这包括从要求agent绕过他们觉得烦人的检查,到运行他们不理解的危险命令,再到指定故意伤害。
模型行为不当:agent采取了无人要求的有害行动。随着我们模型的改进,它们在大多数行为评估上变得更加对齐,但这并不意味着风险必然会缩小。能力较弱的模型更可能误判情况并犯下明显错误。能力更强的模型犯的错误更少,但它们也更擅长找到通往目标的意外路径,通常是通过绕过没人想到要写下的限制。
在Anthropic,我们见过Claude模型“好心”地逃出沙箱以完成任务,检查git历史来寻找编码测试的答案,以及自发地识别出它正在运行的benchmark以便解密其答案密钥。每个模型都带来一套新的能力,有时这些能力会以意想不到的方式被利用。
外部攻击者:agent通过外部向量受到攻击,如工具、文件或网络访问。这一类别既包括提示注入,也包括对agent运行时、编排层或代理的传统攻击。
在构建遏制和防御系统时,我们对三个主要组件应用防御措施:
agent运行的环境。我们通过进程沙箱、虚拟机、文件系统边界和出口控制来限制agent可以行动的地点和方式。目标是为agent能触及的范围设定一个硬边界。例如,如果凭据从不进入沙箱,那么无论原因是用户、模型找到了“创造性”路径,还是攻击者,它们都无法被窃取。
紧密的边界也意味着你可以放松监督。Claude Code的参考开发容器正是为了让agent可以在无人值守的情况下运行,无需逐操作批准而存在。
agent咨询的模型。这里的机制包括系统提示、分类器、探针和训练修改。由于模型是概率性的,这些只塑造agent倾向于做什么,而不是它在理论上能够做什么。
这些防御措施很强大。在Gray Swan的Agent红队benchmark(测试对提示注入的敏感性)上,Claude Opus 4.7在单次尝试中将攻击成功率保持在约0.1%,在100次自适应尝试后约为5-6%。Claude Code自动模式在执行前捕获了约83%的过度行为。然而,即使拥有顶级的防御,模型层的保护也永远不会100%有效,这就是为什么它不能单独存在。
agent可以访问的外部内容。MCP服务器、第三方插件和网络搜索工具都会从你无法控制的来源向agent的上下文提供内容。经过审计的连接器不等于经过审计的数据——例如,一个GitHub连接器可以将一个被投毒的README直接加载到模型的上下文中,尽管它通过了恶意软件检查。细粒度地限制工具权限有助于限制爆炸半径。例如,一个具有只读数据库访问权限的agent可以比一个能写入生产环境的agent部署得更广泛。
防御措施应该重叠并相互补充。当环境防御不可用时,模型层必须弥补(这正是Claude Code自动模式的设计目的)。在本地,环境和模型防御可以防范恶意工具输出,但可以通过限制工具的能力和访问权限在更高级别添加防御。
聚焦环境层,我们描述三种隔离模式以及它们如何针对每个Claude平台——claude.ai、Claude Code和Cowork——进行定制。我们是在逐步找到agent所需能力与用户所需干预程度之间的平衡后,才逐渐得出每个设计的。
尽管claude.ai最出名的是聊天界面,但它也编写和运行代码、生成文件并调用连接器。当Claude在claude.ai内运行代码时,它是在隔离基础设施上的gVisor容器中进行的。agent完全在服务端;没有代码在本地机器上运行,文件系统是临时的(每会话)。爆炸半径最小,但Claude能做的事情的上限也很低——没有持久化工作区,也无法访问用户的文件系统。
这也使得claude.ai面临更传统的威胁模型。我们不是在保护用户机器免受agent侵害;我们是在保护我们自己的基础设施和每个租户免受彼此侵害。我们为claude.ai做的发布前工作主要是传统安全工作,如网络配置、内部服务认证和编排。
这项工作强化了安全领域最古老的教训:最薄弱的层是你自己构建的那一层。gVisor和seccomp在对抗资源充足的对手方面已经比agentic AI存在的时间更长,因此审查工作集中在我们在它们周围构建的较新组件上。我们稍后会回到这一点,因为我们自定义的代理也是在我们最重大的事件中出问题的组件。
Claude Code在用户的机器上运行,可以访问他们的文件系统、shell和网络。没有这些,编码agent的实用性就有限,因此必须找到一种安全地授予这种访问权限的方法。
一种方法是依赖人在回路。这对Claude Code来说是一个可行的解决方案,因为普通用户是熟悉编码环境的开发者:他们能读bash,他们知道rm -rf是做什么的,而且他们每周已经多次从不受信任的来源运行npm install。所有这些都意味着,当弹出“允许此操作”对话框时,他们极有可能具备专业知识来准确评估agent试图做什么以及所涉及的风险。鉴于此,Claude Code以最简单的防御措施推出:允许读取,写入、bash和网络访问需要批准。
然而,如前所述,批准疲劳在几周内就出现了。讽刺的是,这意味着一个原本设计用于提供监督的功能可能产生相反的效果——一些用户可能干脆不再注意。作为减少不谨慎批准的第一步,我们发布了一个操作系统级沙箱(macOS上的Seatbelt,Linux上的bubblewrap),它强化了边界:允许读取,允许在工作区内写入,但默认拒绝网络。在沙箱内,agent基本上可以不受干扰地运行。结果是权限提示减少了84%,我们开源了运行时,因此边界是可审计的。
我们的匿名使用数据还显示,经验丰富的用户自动批准的频率大约是新手用户的两倍,但他们也更多地在执行过程中打断agent。经验丰富的用户不是对每个步骤进行门控,而是更可能在agent偏离轨道时才进行监督。虽然这可能是人们与agent合作方式的自然演变,但这同样容易出错,要求用户足够技术化和专注,首先能注意到偏离。随着模型能力的提高和agent开始编写越来越雄心勃勃的bash命令,注意到这种偏离变得更加困难。而且随着用户转向多agent系统,这种方法作为有效监督策略的可能性也大大降低。
在2025年年中到2026年1月之间,我们通过负责任披露计划收到了关于Claude Code漏洞的报告。其中三个漏洞针对的是在用户同意任何操作之前执行的代码。要理解这是如何可能的,考虑最直接的情况:一个开发者克隆一个仓库来审查拉取请求,该仓库包含一个.claude/settings.json,其中定义了一个钩子。因为Claude Code在启动期间读取项目设置——在显示标准的“你信任此文件夹吗?”提示之前——攻击者编写并提交的钩子会自动执行。其余案例在结构上类似,即在信任边界建立之前,来自尚未受信任目录的输入被解析。
每个案例的修复方式都相同:将项目本地配置的解析和执行推迟到用户接受信任提示之后。如果你在构建类似的东西,请像对待来自互联网的任何入站请求一样对待项目打开、配置加载和localhost监听器。它们不应该仅仅因为感觉是本地且在用户同意之前到达就被隐式信任。
在2026年2月的一次受控内部红队演习中,一名研究员成功通过钓鱼让一名员工使用恶意提示启动Claude Code。钓鱼看起来像普通的协作——一封“你能帮我运行这个吗?”的电子邮件,附带了准备粘贴的提示——提示本身读起来像常规的任务指令。但在某个设置步骤中,它温和地要求Claude读取~/.aws/credentials,对内容进行编码,并将其POST到外部端点。在25次重试该提示中,Claude完成了24次数据外泄。
这是一个直接的提示注入——攻击者的指令是通过用户到达的,而不是通过工具输出或获取的内容。我们的模型层防御锚定在用户意图上——当用户是输入指令的人时,分类器没有异常可捕捉。一个人类承包商拿到同样的脚本也会做同样的事情。
在这种情况下唯一有效的防御是环境,特别是阻止POST的出口控制(无论意图如何)以及首先将~/.aws排除在外的文件系统边界。
(当我们在内部Slack中分享这个有效提示进行讨论时,有人指出一些内部agent会读取Slack。载荷现在无处不在。我们在线程中添加了一个金丝雀字符串,以便在有任何东西拾取它时能注意到。在一个agent读取所有内容的世界里,调查工具本身也是一个攻击面。)
Claude Cowork在用户的桌面上运行,可以访问用户选择的工作区文件夹。由于该平台是为通用知识工作而非软件工程构建的,普通用户不太可能精通bash。
因此,人在回路的沙箱策略可能无法转移;不能指望非技术知识工作者判断诸如find . -name "*.tmp" -exec rm {} \;这样的bash咒语。当批准例外需要普通用户不具备的专业知识时,管理员应该设置一个绝对且始终开启的边界。
为了实现这一点,我们的第一个版本的Claude Cowork在完整虚拟机内运行,使用平台的供应商虚拟机监控程序(macOS上的Apple Virtualization框架,Windows上的HCS)。虚拟机有自己的Linux内核、自己的文件系统和自己的进程表。用户选择的工作区和.claude文件夹被挂载;主机上的其他任何内容都不可见。凭据保留在主机钥匙串中,永远不会进入客户机。这种设计防止了Claude在某个时刻行为失调的可能性。一个被攻破的Claude仍然可能破坏工作区文件夹内的内容,因此架构设计确保那是它唯一能触及的地方(直到用户添加连接器),并且用户控制着挂载在那里的内容。
在最初的架构中——我们称之为全虚拟机模式——agent循环本身在客户机内运行,因此Claude作为一个普通的Linux用户执行,不知道它被沙箱化了。与Claude Code相比,后者有一个特权进程位于沙箱之外,决定每条命令是否强制执行;一个说服力强的注入提示或一次疲劳的批准点击可以让该进程运行未沙箱化的东西。在这里,没有外部进程持有逃生舱钥匙,因此没有组件有权授予例外。
然而,我们很快意识到,在全虚拟机模式下运行整个agent会导致实际问题:虚拟机启动期间的任何故障都会使Cowork无法使用。将agent循环移到虚拟机之外,同时将代码执行保留在虚拟机内,使Claude仍然可以响应用户并帮助调试问题,而不是在错误时冻结。这一改变对安全影响很小,因为虚拟机仍然对agent执行的代码强制执行文件系统和网络控制。
另外,我们还将本地MCP服务器移到了虚拟机之外。在虚拟机内运行它们使它们更难审计,在虚拟机更新时产生脆弱的依赖问题,并且不支持需要与本地进程(如数据库)交互的MCP——这类服务器无论如何都必须在主机上运行。这一改变使Claude Cowork与Claude Desktop中本地MCP服务器的工作方式保持一致:将它们视为用户可能选择安装的任何软件,并委托管理员决定启用哪些本地MCP(如果有的话)。远程MCP服务器不受影响,因为它们不在用户机器上运行。
文件系统控制是另一个重要的架构选择。Claude需要能够访问主机上的某些文件才能有用,但我们希望最小化爆炸半径,并向用户提供本地文件访问的透明度。我们发现提供不同的文件挂载模式有助于细粒度控制风险;Claude Cowork提供只读、读写和读写-无删除模式。这里一个潜在的陷阱是符号链接解析必须在路径验证之前进行,而不是之后,否则授权文件夹内的符号链接可以指向外部并逃逸。对于企业客户,我们允许管理员通过MDM设置中的挂载路径允许列表来控制这一点。
一个通过批准域进行外泄的明显例子来自第三方披露。Claude Cowork的出口允许列表正确地将流量传递到api.anthropic.com——产品不调用我们自己的API就无法运行。在这种情况下,一个放置在用户挂载工作区中的恶意文件携带了隐藏指令以及攻击者控制的API密钥。Claude按照指令读取工作区中的其他文件,并使用攻击者的密钥调用Anthropic的Files API。出口代理检查了目的地,看到api.anthropic.com,就放行了。文件被上传到攻击者的Anthropic账户。沙箱完美运行,但数据仍然被外泄了。
此前,我们将允许列表概念化为目的地过滤器,告诉Claude这些域是可以通信的。但它可能更好地被概念化为能力授权。允许列表上任何域可访问的每个功能现在都是一个攻击面。允许api.anthropic.com意味着允许向任意Anthropic账户上传文件。
我们通过虚拟机内的防御性中间人代理修复了这个问题,该代理拦截到我们API的流量。它只传递携带虚拟机自身配置的会话令牌的请求;攻击者嵌入的密钥会被代理拒绝。它还阻止启用服务器端获取的头部。代理位于虚拟机内部而不是我们的服务器上,因为只有虚拟机知道来源——从服务器的角度来看,Cowork请求与其他任何API客户端无法区分。
这也是“你自己构建的软件往往是最薄弱的”原则的第二个实例。我们产品中的虚拟机监控程序、seccomp和gVisor一直很可靠。我们自定义的允许列表代理是出问题的部分。
在评估Claude Cowork时,企业安全团队问:“为什么我们的EDR看不到内部?”答案是,隔离Claude的同一机制也将基于主机的端点检测和响应拒之门外。从EDR的角度来看,Claude Cowork是一个不透明的虚拟机监控程序进程。它无法检查客户机。
隔离降低了可见性,而对于合规态势依赖端点可见性的团队来说,不透明性是有问题的。我们目前的缓解措施是使用基于拉取的OTLP导出,让管理员事后检索事件日志,但这与实时监控不同。如果你在构建类似的东西,请尽早为这种对话做好预算。
企业经常问我们如何保护MCP连接。这是一个好问题,但正确的问题比MCP本身更广泛。提供给agent的任何外部资源同时代表两种风险:传统供应链意义上的代码执行风险,以及提示注入向量。传统的依赖审计(固定版本、验证签名、审查源代码)解决了第一个问题,但忽略了第二个。
远程与本地之间的区别比看起来更重要。本地安装的工具是可审计的。你可以阅读代码、固定版本,并知道它不会在你不知情的情况下改变。远程工具——托管的MCP服务器、云连接器——可以在你批准后的任何时间点改变行为;你的安装时信任决定可能不再适用。我们的连接器目录通过持续审查来解决这个问题,但目录之外的任何内容都应被视为不受信任。首先在恶意工具爆炸半径受限的环境中,用假数据运行它。
即使工具是受信任的,工具输出也是一个攻击面。前面提到的GitHub README例子正是这种情况;应用于网页的任何输入扫描都需要以同样的严格程度应用于启用网络的工具结果。尽管这增加了延迟并且不是完美的防御,但我们倾向于实时检查:一旦被投毒的工具返回将agent引向数据外泄,日志只会显示一个成功、授权的API调用。事后没有信号可寻。
在Claude Code和Claude Cowork中,工具调用通过代理路由,这些代理强制执行网络和文件策略,并可以在返回值进入模型上下文之前检查它们。执行检查的分类器可以是一个小而快的模型;它不需要是进行推理的那个。
模型和产品正在快速发展。随着它们的发展,风险也在变化和演变,我们的缓解措施必须跟上以应对它们。
持久记忆投毒。跨会话持续的agent上下文份额不断增长——这包括产品记忆、CLAUDE.md文件、挂载的工作区,以及定时和长期运行agent的状态目录。落在这些任何地方的注入都会在agent每次启动时重新加载。随着更多agent状态在会话后存活,我们受到经典后利用意义上的新持久性机制的威胁。会话启动时的良好分类器将需要变得更加普遍。
多agent信任升级。一方面,子agent可以隔离不受信任的内容,向主agent返回结构化事实而不是原始文本。另一方面,这可以被滥用:如果子agent的输出被视为比原始工具结果更高信任,因为这种输出来自“我们”,那么提示注入的新向量就被引入了。在多agent系统中,分配不同信任级别与容易受到信任升级之间存在着权衡。
Agent身份。Claude Cowork对agent身份的回答是具体的:凭据保留在主机钥匙串中,虚拟机获得一个每会话范围缩小的令牌,该令牌可以独立于用户的令牌被撤销。然而,我们开始应对跨平台agent身份这一更广泛的问题。agent应该拥有自己的主体身份,还是应该作为用户的扩展并继承用户的权限?最终,答案可能是两者的混合。
随着agent能力的增强,攻击面不断变化。我们看到的故障类型可能会在各行业和实验室中重复出现。我们需要在agent特定安全态势方面进行集体投资,从共享benchmark和披露规范到通用身份标准和跨供应商红队。我们在本文中专注于遏制,但这只是agent安全图景的一部分。关于治理、可观测性以及其余技术栈,请参阅NIST关于AI agent身份和授权的项目、由澳大利亚ACSC牵头、CISA和英国NCSC参与的六机构关于采用agentic AI的指南,以及AI管理标准ISO/IEC 42001。我们的Glasswing计划是其中的一个贡献,但我们期待在这个关键问题上与合作伙伴和竞争对手合作。
简而言之,有几条我们不断回归的原则:
首先在环境层设计遏制,然后在模型层引导行为。教会我们最多的两起事件——员工钓鱼和第三方允许列表披露——都是出口案例,数据通过允许的路径离开。在这两种情况下,模型层都无能为力;没有异常可捕捉。当所有概率性防御都失效时,确定性边界就是被击中的那一个。
将隔离强度与用户的监督能力相匹配。能读bash的开发者与不能读bash的知识工作者运行的不是同一个威胁模型。用户能否评估agent将要做什么的问题应该有助于确定遏制策略,而无论哪个方向答错——对专家来说摩擦太多,对非专家来说信任太多——都是自身的失败。
警惕自定义组件。经过实战考验的虚拟机监控程序、系统调用过滤器和容器运行时比你能构建的任何东西都经受了更多的对抗性关注。在本文描述的每个部署中,标准原语都保持了稳定,而我们围绕它们构建的工作暴露了缺陷。
最终,虽然agent可能是一种新的软件类别,但它们的系统级交互并非如此。它们仍然读取文件、打开套接字和生成进程;这使得使用成熟工具进行遏制成为一种至关重要的可行防御。随着AI的发展,部署的风险收益平衡将继续转变,但对爆炸半径设置硬限制往往能迫使这种平衡朝着正确的方向发展。
作者:Max McGuinness、Mikaela Grace、Jiri De Jonghe、Jake Eaton和Abel Ribbink。
我们还要感谢Hanah Ho、Hasnain Lakhani、Pedram Navid、Molly Villagra、Maya Nielan、Akila Srinivasan、Travis Szucs、Sam Attard、Alfred Xing、Mohamad El Hajj、Gabby Curtis、David Dworken、Adam Jones、Amie Rotherham、Christian Ryan、Lucas Smedley、Brett Andrews以及其他人的贡献。
特别感谢我们的安全和产品工程团队,以及报告Claude产品漏洞的个人和组织。