我们如何在各类产品中对 Claude 进行隔离控制
随着智能体能力不断增强,其潜在影响半径也在扩大。工程上的问题在于如何为其设定上限。以下是我们在为 claude.ai、Claude Code 和 Cowork 构建隔离控制时获得的经验。
十二个月前,如果有人提出要赋予 Claude 足以搞垮 Anthropic 内部某项服务的访问权限,我们会毫不犹豫地拒绝。如今,这种级别的访问已属常态,而 Anthropic 的开发者也因此获得了更高的生产力。这类部署的风险由两部分构成:失败发生的可能性,以及一旦失败可能造成的损害程度。安全防护与模型训练方面的进展,持续降低了前者;而后者——理论上的影响半径——则只会随着能力和访问权限的扩张而增长。然而,当智能体开始能够完成过去需要一个人甚至一个团队才能完成的工作时,不部署它们的成本会增长到足以让风险收益权衡明显倾向于采用,前提是产品能够做到安全。于是,工程问题就变成了如何限制影响半径。
大体上有两种方法可以做到这一点。
第一种是通过 human-in-the-loop(人在回路中)来监督智能体的行为。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 漏洞的报告。其中有三个漏洞利用了用户尚未同意任何事情之前就会执行的代码。要理解这为什么可能发生,可以看一个最直接的例子:开发者克隆一个仓库来审查 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 仍然可能损坏工作区文件夹中的内容,因此该架构的设计目标是确保这就是它唯一能接触到的东西(除非用户额外添加连接器),并且由用户来控制挂载了什么。
在最初的架构中——我们称之为 full-VM 模式——智能体循环本身也运行在来宾机内部,因此 Claude 作为一个普通 Linux 用户执行,并不知道自己处于沙箱中。对比 Claude Code:在那里,一个位于沙箱外的特权进程会逐条命令决定是否执行沙箱约束;一个有说服力的注入提示,或一次疲劳下的批准点击,都可能让该进程运行某个未受沙箱约束的操作。而在这里,并不存在一个掌握“逃生舱钥匙”的外部进程,因此也就没有任何组件拥有授予例外的权限。
然而,我们很快意识到,在 full-VM 模式下让整个智能体都运行在虚拟机内会带来实际问题:只要虚拟机启动过程中出现任何故障,Cowork 就会完全不可用。于是我们将智能体循环移到虚拟机外部,同时仍将代码执行保留在虚拟机内部。这样一来,即使虚拟机出错,Claude 仍然可以响应用户并帮助调试问题,而不是在错误发生时彻底卡死。这个改动带来的安全影响很小,因为虚拟机仍然会对智能体执行的代码施加文件系统和网络控制。
另外,我们也将本地 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 导出,让管理员能够事后提取事件日志,但这并不等同于实时监控。如果你也在构建类似系统,请尽早为这类沟通预留空间。
环境| 短暂容器(claude.ai)
| HITL 沙箱(Claude Code)| 封闭虚拟机(Claude Cowork)
---|---|---|---
成本:隔离开销| 容器启动| 低延迟原生沙箱| 完整虚拟机启动
成本:对用户的依赖| 不适用| 必须能理解 bash| 不适用
风险:影响半径| 服务端容器(由 gVisor + 主机基础设施边界保护)| 本地工作区| 挂载工作区(由 vsock + 虚拟化程序边界保护)
信任智能体所读取的内容
企业经常问我们如何保护 MCP 连接。这是个好问题,但真正的问题比 MCP 本身更广泛。任何提供给智能体的外部资源,同时代表着两类风险:传统供应链意义上的代码执行风险,以及提示注入向量。传统的依赖审计(锁定版本、验证签名、审查源码)能解决前者,却会漏掉后者。
远程与本地的区别比看上去更重要。 本地安装的工具是可审计的。你可以阅读代码、锁定版本,并确信它不会在你不知情的情况下发生变化。而远程工具——托管的 MCP 服务器、云连接器——在你批准之后的任何时刻都可能改变行为;你在安装时做出的信任决策,之后可能就不再适用。我们的连接器目录通过持续审查来应对这一点,但目录之外的任何东西都应被视为不受信任。先拿虚假数据在一个影响半径受控的环境中测试它。
即使工具本身可信,工具输出仍然是攻击面。 前面提到的 GitHub README 例子正是这种情况;任何应用于网页内容的输入扫描,也都需要以同样严格的标准应用于具备网络能力的工具返回结果。尽管这会增加延迟,而且也不是完美防御,我们仍然倾向于实时检查:一旦被投毒的工具返回值把智能体引导去外泄数据,日志里只会显示一次成功且被授权的 API 调用。事后根本没有可供发现的信号。
在 Claude Code 和 Claude Cowork 中,工具调用会经过代理,这些代理会执行网络和文件策略,并在返回值进入模型上下文之前对其进行检查。执行检查的分类器可以是一个小而快的模型;它不需要是负责推理的那个模型。
展望未来
模型和产品正在快速演进。随着它们发展,风险也在不断变化和演化,我们的缓解措施必须同步跟进。
持久记忆投毒。 跨会话持久存在的智能体上下文占比正在不断增长——这包括产品记忆、CLAUDE.md 文件、挂载工作区,以及定时和长时运行智能体的状态目录。任何落入这些位置的注入内容,都会在智能体每次启动时重新加载。随着越来越多的智能体状态跨越会话存活下来,我们正在面临经典后渗透意义上的新型持久化机制威胁。会话启动时的高质量分类器将需要变得更加普遍。
多智能体信任升级。 一方面,子智能体可以隔离不受信任内容,只向主智能体返回结构化事实,而不是原始文本。另一方面,这也可能被滥用:如果子智能体的输出因为来自“我们自己”而被视为比原始工具结果更高信任级别,那么就引入了一条新的提示注入向量。在多智能体系统中,在分配不同信任级别与引发信任升级风险之间,存在一种权衡。
智能体身份。 Claude Cowork 对智能体身份的回答是具体的:凭证保留在主机钥匙串中,虚拟机获得一个按会话范围缩减的令牌,而且这个令牌可以独立于用户令牌被撤销。不过,我们也开始面对更广泛的跨平台智能体身份问题。智能体是否应拥有自己的主体身份,还是应作为用户的延伸并继承用户权限?最终答案可能是两者的结合。
随着智能体能力不断增强,攻击面也在持续变化。我们见过的失败类型,很可能会在各个行业和实验室中反复出现。我们需要在智能体专属安全姿态上进行集体投入,从共享基准和披露规范,到通用身份标准和跨厂商红队测试。本文聚焦于隔离控制,但那只是智能体安全图景中的一部分。关于治理、可观测性以及其余技术栈内容,可参见 NIST 关于 AI 智能体身份与授权的项目、由澳大利亚 ACSC 联合 CISA 和英国 NCSC 牵头发布的六机构关于采用智能体 AI 的指导意见,以及 AI 管理标准 ISO/IEC 42001。我们的 Glasswing 计划是其中一项贡献,但我们也期待与合作伙伴和竞争对手一道,共同推进这一关键议题。
总结
简而言之,我们反复回到以下几个原则:
优先在环境层设计隔离控制,然后再在模型层引导行为。 给我们最大教训的两起事件——员工钓鱼事件和第三方允许列表披露——都属于出口问题,即数据通过被允许的路径离开。在这两起事件中,模型层都帮不上忙;它没有任何异常可抓。当一切概率性防御都失手时,真正起作用的是确定性的边界。
让隔离强度与用户的监督能力相匹配。 能读懂 bash 的开发者,与不能读懂 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、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% 的过度激进行为会通过),因此它只是沙箱内部纵深防御中的一层,而不是沙箱本身的替代品。
获取开发者新闻通讯
产品更新、操作指南、社区精选等更多内容。每月发送至你的收件箱。
如果你希望接收我们的每月开发者新闻通讯,请提供你的电子邮箱地址。你可以随时取消订阅。