Anthropic 如何为 Claude 三款产品设计隔离与防护
How we contain Claude across products
Anthropic 工程团队发文说明 claude.ai、Claude Code 和 Claude Cowork 三款智能体产品各自的隔离架构,分别采用临时容器、人在回路沙箱和本地虚拟机三种模式。
Anthropic 公开三款产品各自的隔离架构与真实事故复盘,可迁移到自建 Agent 的边界设计。
十二个月前,我们还会毫不犹豫地拒绝让 Claude 获得足以关停 Anthropic 内部服务的访问权限。如今,这种级别的访问权限已是常态,Anthropic 的开发者也因此效率更高。这些部署的风险由两部分组成:失败的可能性有多大,以及一次失败能造成多大的损害。在安全防护和模型训练方面的进展稳步降低了前者;而后者——理论上的影响范围——只会随着能力和访问权限的扩展而不断扩大。然而,当智能体能够完成曾经需要一个人甚至一个团队才能完成的工作时,不部署的代价会变得足够大,以至于只要产品能够做到安全,风险与回报的权衡就会大幅倾向于采用。工程问题于是变成了如何限制影响范围。

大致有两种方法可以做到这一点。
第一种是通过人在回路来监督智能体的行为。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 的 auto mode 所设计的目的)。在本地,环境和模型防御可以防范恶意的工具输出,但还可以通过在更上层限制工具的能力和访问权限来增加防御。

遏制智能体的模式
聚焦于环境层,我们描述了三种隔离模式,以及它们如何针对每个 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),以加固边界:允许读取,允许在工作区内写入,但默认拒绝网络访问。在沙箱内,agent 基本可以不受干扰地运行。结果是权限提示减少了 84%,我们将运行时开源了,因此边界是可审计的。
我们的匿名使用数据还显示,有经验的用户自动批准的概率大约是新手用户的两倍,但他们也更频繁地在 agent 执行中途打断它。有经验的用户不是对每个步骤都设卡,而是更倾向于只在 agent 偏离正轨时才进行监督。虽然这可能是人们与 agent 协作方式的一种自然演变,但这种方式同样容易出错,需要用户具备足够的技术能力和注意力,才能首先察觉到偏离。随着模型能力的提升,agent 开始编写越来越复杂的 bash,察觉此类偏离变得更加困难。而且随着用户转向多 agent 系统,这种方式也更不可能成为一种有效的监督策略。
我们遗漏的风险:信任对话框之前的一切
2025 年年中至 2026 年 1 月期间,我们通过负责任披露计划收到了关于 Claude Code 漏洞的报告。其中三个漏洞针对的是在用户同意任何内容之前就执行的代码。要理解这怎么可能,请看最直接的情况:一名开发者克隆一个仓库来审查 pull request,而该仓库包含一个定义了 hook 的 .claude/settings.json。由于 Claude Code 在启动期间读取项目设置——在呈现标准的“你信任此文件夹吗?”提示之前——攻击者编写并提交的 hook 就会自动执行。其余几个案例在结构上类似,即来自尚未受信任目录的输入在信任边界建立之前就被解析了。
每个案例的修复方式都如出一辙:将项目本地配置的解析和执行推迟到用户接受信任提示之后。如果你正在构建类似的东西,请像对待来自互联网的任何入站请求一样对待项目打开、配置加载和 localhost 监听器。它们不应该仅仅因为感觉上是本地的、并且在用户同意之前到达就被隐式信任。
我们遗漏的风险:用户作为注入向量
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 framework,Windows 上是 HCS)。该虚拟机拥有自己的 Linux 内核、自己的文件系统和自己独立的进程表。用户选定的工作区和 .claude 文件夹被挂载进去;宿主机上的其他内容都不可见。凭据保留在宿主机的钥匙串中,永远不会进入客户机。这一设计防范的是 Claude 在某个时刻以不对齐的方式行事的可能性。一个被攻陷的 Claude 仍然可以破坏工作区文件夹内的内容,因此该架构的设计目标是确保那是它唯一能触及的东西(直到用户添加连接器),并且用户控制着那里挂载了什么。
在最初的架构中——我们称之为全虚拟机模式——智能体循环本身运行在客户机内,因此 Claude 是以一个普通 Linux 用户的身份执行的,完全不知道自己处于沙箱之中。与之相比,在 Claude Code 中,一个特权进程位于沙箱之外,逐条命令决定是否强制执行沙箱;一段有说服力的注入提示词或一次疲惫之下的批准点击,就能让那个进程运行未经沙箱隔离的东西。而在这里,没有外部进程握着一把逃生舱门的钥匙,因此也就没有任何组件拥有授予例外的权限。

然而,我们很快意识到,在全 VM 模式下运行整个 agent 会带来实际问题:VM 启动期间的任何失败都会导致 Cowork 无法使用。将 agent 循环移到 VM 之外,同时将代码执行保留在 VM 内部,使 Claude 仍能响应用户并帮助调试问题,而不是在错误上冻结。这一改动带来的安全影响极小,因为 VM 仍然对 agent 执行的代码强制执行文件系统和网络控制。
另外,我们还将本地 MCP 服务器移出了 VM。将它们运行在 VM 内部会使它们更难审计,在 VM 更新时会产生脆弱的依赖问题,并且不支持需要与本地进程(如数据库)交互的 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 账户上传文件。
我们在 VM 内部使用了一个防御性的中间人代理来拦截发往我们 API 的流量,从而修复了这个问题。它只放行携带 VM 自身预置会话令牌的请求;攻击者嵌入的密钥会被代理拒绝。它还会阻止那些会启用服务端抓取的请求头。代理位于 VM 内部而非我们的服务器上,因为只有 VM 知道来源——从服务器的角度来看,Cowork 请求与任何其他 API 客户端无法区分。

这也是同一条原则的第二个例证:你自己构建的软件往往是最薄弱的。我们各产品中的 hypervisor、seccomp 和 gVisor 一直很可靠。我们自研的允许列表代理才是失败的那一环。
我们遗漏的风险:VM 隔离也把端点检测软件挡在了外面
在评估 Claude Cowork 时,企业安全团队问:“为什么我们的 EDR 看不到里面?”答案是,将 Claude 隔离起来的同一套机制,也把基于主机的端点检测与响应挡在了外面。从 EDR 的角度看,Claude Cowork 是一个不透明的 hypervisor 进程。它无法检查 guest。
隔离会降低可见性,而对于合规态势依赖于端点可见性的团队来说,不透明是个问题。我们目前的缓解措施是使用基于拉取的 OTLP 导出,让管理员可以在事后检索事件日志,但这与实时监控并不相同。如果你正在构建类似的东西,请尽早为这场对话预留预算。
| 环境 | 临时容器(claude.ai) | HITL 沙箱(Claude Code) | 密封 VM(Claude Cowork) |
|---|---|---|---|
| 成本:隔离开销 | 容器启动 | 低延迟原生沙箱 | 完整 VM 启动 |
| 成本:用户依赖 | 不适用 | 必须解读 bash | 不适用 |
| 风险:影响范围 | 服务端容器(由 gVisor + 主机基础设施边界防护) | 本地工作区 | 挂载工作区(由 vsock + hypervisor 边界防护) |
信任 agent 读取的内容
企业经常问我们如何保护 MCP 连接。这是个好问题,但正确的问题比 MCP 本身更宽泛。提供给 agent 的任何外部资源都同时代表两种风险:传统供应链意义上的代码执行风险,以及提示注入途径。传统的依赖审计(固定版本、验证签名、审查源码)解决了第一种,但漏掉了第二种。
远程与本地之别比看起来更重要。本地安装的工具是可审计的。你可以阅读代码、固定版本,并知道它不会在你背后发生变化。远程工具——托管的 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 产品漏洞的个人和组织。
脚注
- Claude Code 自动模式将命令批准委托给基于模型的分类器;它最大限度地减少了摩擦(约 0.4% 的良性命令被阻止),代价是漏掉了一部分有风险的命令(约 17% 的过度激进操作得以通过),因此它只是沙箱内纵深防御的一层,而不能替代沙箱。
来源:Anthropic Engineering · anthropic.com