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