在Windows上构建安全有效的沙箱以支持Codex
摘要
OpenAI工程师为Windows上的Codex构建了自定义沙箱,以实现安全受限的命令执行,在不依赖原生Windows隔离功能的情况下平衡有效性与安全性。
了解OpenAI如何为Windows上的Codex构建安全沙箱,实现安全高效的编码代理,并具备受控的文件访问和网络限制。
查看缓存全文
缓存时间: 2026/05/13 21:15
# 构建安全有效的沙箱,让 Codex 在 Windows 上运行
来源:https://openai.com/index/building-codex-windows-sandbox/
2025 年 9 月我加入 Codex 工程团队时,Codex for Windows 还没有实现沙箱,这意味着 Windows 用户在使用 OpenAI 的编码智能体时,只能在两种不太理想的选项之间选择:
1. 批准编码智能体要运行的几乎所有命令(即使是读取操作),这既低效又烦人。使用 Codex 的一大好处就是不必自己做所有繁琐的工作。
2. 启用完全访问模式:让 Codex 运行所有命令,无需审批或限制,这虽然消除了摩擦,却牺牲了监督。
Codex(https://openai.com/codex/)是我们的编码智能体,运行在开发者的笔记本电脑上——无论是通过 CLI、IDE 扩展还是桌面应用。它管理着键盘前的人类与云端运行用于推理的模型之间的对话。默认情况下,Codex 拥有真实用户的权限,意味着它可以执行用户能做的一切事情。这很强大,但也存在潜在危险。编码模型可能会告诉执行器在本地运行命令,从运行测试、读取或编辑文件,到创建 Git 分支,因此 Codex 的默认模式试图在有效性和安全性之间找到合适的平衡。这种默认模式允许 Codex 在几乎任何地方读取文件,并在你的工作空间(即运行 Codex 的目录)内写入文件,除非你指定需要互联网访问,否则无法联网。
为了自动实现这种在安全范围内限制文件写入和网络访问的约束,Codex 需要一个真正能强制执行这些约束的沙箱环境。
**沙箱**是一个受限的执行环境。当开发者使用 Codex 时,其计算机的操作系统会以降低的权限启动一个命令,并且这些约束会沿着进程树向下传播。每个 Codex 命令从一开始就被沙箱化,每个子进程都保持在同一个边界内。
Codex 需要操作系统提供的隔离功能来实现有效的沙箱。某些操作系统提供了很好的工具(例如 macOS 上的 Seatbelt,Linux 上的 seccomp 或 bubblewrap);然而,Windows 目前并没有开箱即用地提供这种能力。为了让 Codex 在 Windows 上像在其他地方一样安全且使用体验愉悦,我们需要实现自己的沙箱。
Windows 提供了一些用于隔离的工具和原语。虽然它们没有一个完全满足我们的需求,但我们研究了几种潜在的解决方案——即 AppContainer、Windows Sandbox 和强制完整性控制(MIC)标签。
**AppContainer**
- **是什么:** AppContainer 是原生的 Windows 沙箱,一种基于能力的隔离模型,专为那些预先确切知道需要访问什么的应用而构建。
- **为什么考虑:** 很有吸引力,因为它提供了真正的操作系统边界,而不是尽力而为的限制。
- **为什么不选:** Codex 并非一个严格限定范围的应用。它驱动着开放式的开发者工作流:Shell、Git、Python、包管理器、构建工具,以及智能体决定需要的任何其他二进制文件。在实践中,这使得 AppContainer 不适合这个问题。它虽然是强隔离,但只适用于比“让智能体像开发者一样操作”窄得多的工作负载。
**Windows Sandbox**
- **是什么:** Windows Sandbox 是微软的一次性轻量级虚拟机。你会得到一个具有强隔离边界的新 Windows 桌面,会话结束后,你在其中所做的一切都会消失。
- **为什么考虑:** 显然很吸引人——与任意软件的兼容性远高于 AppContainer,并且从安全角度来看,它是一个更强的箱子。
- **为什么不选:** Codex 需要直接作用于用户实际的代码检出、工具和环境,而不是在一个需要设置和主机/客户机桥接的独立一次性桌面内部。它还有一个根本性的产品问题:Windows Sandbox 甚至在 Windows 家庭版 SKU 上也不可用。
**强制完整性控制(MIC)完整性标签**
- **是什么:** Windows 有一个称为“完整性级别”的概念,例如低、中、高,它决定了系统对对象和进程的信任程度。基本规则是:低完整性进程无法写入具有更高完整性级别的对象,即使普通的 ACL 允许也不行。例如,低完整性进程被视为不太受信任,因此 Windows 会阻止它写入正常的中完整性对象,除非这些对象被明确重新标记以允许写入。
- **为什么考虑:** MIC 在纸面上看起来优雅——以低完整性运行 Codex,将可写根目录重新标记为低完整性,然后让 Windows 在其他任何地方强制执行禁止写入。这样我们就获得了一个非管理员路径,背后有真正的操作系统机制。
- **为什么不选:** 与 ACL 一样,完整性标签会修改真实的主机文件系统,而且在这种情况下语义变化尤其广泛。将工作空间标记为低完整性不仅仅意味着“Codex 可以在这里写入”。它还意味着**一般而言**低完整性进程可以在那里写入。在真实的开发者机器上,这会使用户的实际代码检出成为主机的低完整性垃圾场,这比向一个沙箱设计授予精心定位的 ACL 风险大得多。即使中完整性的开发者工具继续正常工作,工作空间底层的信任模型也已经以一种难以控制且更难辩护的方式发生了变化。
在评估了所有选项都不可行之后,我们开始设计自己的解决方案,为 Windows 用户带来良好的 Codex 体验。
## 第一个原型:“非提升沙箱”
我们的第一个工作原型结合使用 Windows 概念和工具来实现我们需要的隔离。从一开始,一个目标就是让它无需**提升**权限即可工作,这意味着 Codex 不需要仅仅为了设置或运行沙箱而提示用户授予管理员权限。这意味着要弄清楚如何对两件事施加合理的限制:文件写入和网络访问。如果我们完全不限制文件写入,就会出现安全问题。如果我们过度限制文件写入,沙箱会损害用户的生产力,需要不断请求批准。
为了解决这个问题,我们依赖两个重要的 Windows 构建块:SID 和写入受限令牌。
SID(安全标识符)是 Windows 用来关联权限的身份。每个用户都有一个 SID,组有 SID,甚至单个登录会话也有自己的 SID。例如,当前登录的会话可能有一个像 `S-1-5-5-X-Y` 这样的 SID。分配给本地管理员组的 SID 可能是 `S-1-5-32-544`。Windows 还允许你创建不对应于真实用户的合成 SID,但它们仍然可以出现在 ACL(访问控制列表)中,ACL 定义了谁可以读取/写入/执行特定的文件或目录。这使得 SID 成为我们沙箱的一个有用原语:我们可以创建专供 Codex 沙箱使用的 SID,而不会干扰机器上的其他任何东西。
进程令牌是 Windows 中的安全对象,用于定义正在运行的进程的身份和权限。它们决定进程可以执行哪些操作。**写入受限令牌**是一种特殊类型的进程令牌,它使 Windows 对写入操作执行额外的访问检查。为了使写入成功,必须通过两个检查:
1. 正常的用户身份(令牌“所有者”)必须被允许执行该操作
2. 令牌受限 SID 列表中的至少一个 SID 也必须被授予访问权限
在实践中,这些检查让我们可以使用 ACL 来精确定义沙箱可以在文件系统的哪些位置进行修改,这为我们围绕写入操作提供了所需的粒度。
借助 SID 和写入受限令牌,我们的非提升沙箱的工作方式如下:
1. 沙箱设置创建一个名为 `sandbox-write` 的合成 SID。
2. `sandbox-write` SID 被授予对以下内容的写入、执行和删除访问权限:
1. 当前工作目录
2. `config.toml` 中配置的任何其他 `writable_roots`
3. 沙箱设置明确拒绝同一 SID 对“可写区域内只读”位置的写入访问权限,例如:
1. `/.git`
2. `/.codex`
3. `/.agents`
4. Codex 在写入受限令牌下启动命令,其受限 SID 列表包括 `Everyone`、当前登录会话 SID 和 `sandbox-write` 合成 SID。
这个流程有效地解决了限制文件写入的问题,看起来很有希望。现在我们需要一个解决方案来限制沙箱的网络访问。限制网络访问是沙箱的重要组成部分;否则,恶意代码可以将数据从机器外泄到互联网。因为我们希望避免提升权限的要求,所以强力阻止网络流量的选项有限。我们想使用的工具,如 Windows 防火墙,通常没有管理员权限就无法安装。
由于无法使用 Windows 防火墙,我们所能控制的有限。我们尝试让子环境对开发者实际使用的联网工具失效,这样 Git 命令、包安装器等在沙箱中会失败,用户必须批准任何面向互联网的操作。这个想法是毒化明显的逃生口:将代理感知的流量发送到一个死端点,让 Git 的 HTTP(S) 传输也做同样的事情,并让 Git over SSH 立即失败。除此之外,我们在 PATH 前面添加了一个小的 `denybin` 目录,并重新排序了 `PATHEXT`,使得存根 SSH 和 SCP 脚本在实际二进制文件之前被解析。
例如,以下是我们用来限制网络访问的一些特定环境覆盖:
- `HTTPS_PROXY=http://127.0.0.1:9`
- `ALL_PROXY=http://127.0.0.1:9`
- `GIT_HTTPS_PROXY=http://127.0.0.1:9`
- `NO_PROXY=localhost,127.0.0.1,::1`
- `GIT_SSH_COMMAND=cmd /c exit 1`
这捕获了很大一部分正常的工具驱动流量,但它仍然只是建议性的。一个进程可以忽略环境变量、绕过 PATH,或者直接打开套接字——风险太大。
与任何有趣的软件实现一样,第一个原型有一些优点和缺点。虽然它只用了几个标准的 Windows 功能就完成了任务,允许非常明确和精细的文件系统写入,并且以非提升方式运行——减少了用户接受过多提升提示或在其本地机器上成为管理员的需求——但它也有一些真正的缺点,其中一些使其不符合成为我们最终设计的条件:
- 设置速度:根据工作区目录的拓扑结构,应用工作区 ACL 可能代价高昂。
- 占用空间:我们将真正的 ACL 应用到了开发者的系统上,不过由于所有应用的 ACL 都属于一个仅由沙箱使用的自定义合成 SID,因此占用空间并不特别具有侵入性。
- 语义更改困难:依赖 ACL 进行基于文件的限制意味着更改沙箱语义既昂贵又复杂。而在 macOS 上,我们可以动态更改用于配置 Seatbelt 的 `.sbpl` 文件的生成方式,Windows 沙箱可能需要一个缓慢且强度高的操作来调整 ACL。
- 网络保护薄弱。如前所述,它是“建议性”的,肯定会被一些实现自己网络栈的程序绕过,并且其设计目的也不是为了抵御对抗性代码。
前三个问题是一个足够灵活以适应智能体流程的自定义沙箱实现所固有的。但网络抑制的情况不同。除了恶意智能体可以轻松绕过基于环境的网络抑制外,许多善意的代码/二进制文件也会仅仅因为不尊重环境代理变量,或者实现了自己的基于套接字的网络代码而绕过它。我们觉得这个方面足以考虑投入资金构建一个更好的沙箱模式。
为了获得更好的网络抑制能力,我们想使用 Windows 防火墙,它允许我们阻止用户或程序的外出网络流量。不幸的是,由于几个原因,我们无法有效地创建一个仅适用于 Codex 执行器生成的命令的防火墙规则:
- Windows 不允许将防火墙规则与受限令牌的非主体身份匹配。这意味着我们无法将防火墙规则应用于“任何在受限 SID 列表中包含我们合成 SID 的令牌”。
- 虽然我们可以创建一个匹配特定二进制文件的防火墙规则,但这只允许我们限制 `codex.exe` 本身的网络连接。它不适用于智能体代表用户生成的进程,如 Git 或 Python 进程。
- 其他防火墙匹配维度也不合适。用户范围的规则仍然匹配非提升设计中的真实 Windows 用户,而不仅仅是受限子进程。程序路径规则太粗糙:它们可以一般性地阻止 `codex.exe` 或 `python.exe`,但不能阻止这一次沙箱化的 `python.exe` 调用。基于端口或地址的规则也完全是错误的策略。例如,我们不想阻止 443 端口;我们想阻止这个特定受限进程树的任意外出访问。
为了将防火墙规则专门应用于我们的沙箱化命令,我们需要将它们作为单独的主体运行,而不是“真实”用户。这种方法使我们走上了一条新的道路,我们放宽了“不提升权限”的约束。
## 重新设计:“提升沙箱”
沙箱的下一个迭代版本(即我们当前的实现)需要在设置时使用管理员提升权限。因此我称之为“提升沙箱”。
在 Codex 在系统上生成命令的边界处,提升沙箱看起来与非提升沙箱类似。它仍然在受限令牌下运行子进程——同样是一个 `write_restricted` 令牌,具有相同的受限 SID 列表 `[Everyone, Logon, Synthetic]`——然而,这个令牌的主体不再是实际的 Windows 用户,而是 Codex 自身创建的两个本地用户之一:
- `CodexSandboxOffline`(受防火墙规则针对的用户)
- `CodexSandboxOnline`(不受防火墙规则针对的用户)
这个看似很小的细节实际上对沙箱、谁能使用它以及其设置和运行时执行的复杂性都有重大影响。它在视觉上与非提升原型相似,但引入了防火墙规则和一个专用的 Windows 用户,该用户实际运行命令。(然而,这些新概念的引入意味着在沙箱可以开始运行和保护命令之前,需要进行更多的设置工作。)
非提升沙箱设计有一个简单的设置步骤,但相对较少:
- 如有需要,创建一个合成 SID
- 为 sandbox-write 合成 SID 应用 ACL
而提升沙箱则有更多工作要做。
- 如果尚未创建,创建一个合成 SID
- 如果尚未创建,创建在线和离线沙箱用户
- 将新创建用户的凭据本地存储,并使用 Windows 数据保护 API(DPAPI)加密,存储位置沙箱用户无法实际读取
- 创建防火墙规则,阻止 `CodexSandboxOffline` 用户的所有外出网络访问;如果规则已存在,则验证其正确性
设置阶段还有一个额外的棘手之处。Codex 的沙箱预期拥有与真实 Windows 用户等效的读取访问权限。在非提升沙箱中,受限令牌的主体 SID 就是 Windows 用户,这一点得以实现。然而,当主体变成一个新的 `CodexSandbox` 用户时,这并非免费获得。Windows 上的许多相关目录会授予“经过身份验证的用户”读取/执行权限。一个显著的例子是用户的配置文件目录。默认情况下,Windows 用户无法读取其他 Windows 用户的配置文件目录,因此甚至...
相似文章
我在无头Linux上为codex构建了一个计算机使用沙箱框架。GPU直通、计算机使用和codex的sudo权限全部工作。这是一个完美的开发沙箱,可以在最小化"rm -rf /"风险的同时实现全自动工作。
作者使用LXC容器构建了一个AI沙箱管理器,允许Codex代理在无头Linux上拥有完整的sudo权限和GPU直通,同时保护主机系统免受灾难性错误的影响。
在OpenAI安全运行Codex
OpenAI详细介绍了如何部署Codex并配备安全控制措施,包括沙箱隔离、审批策略、网络策略以及智能体原生遥测,以确保企业环境中编码智能体的安全运行。
@thsottiaux: 我们持续投资,让代理在Windows上运行得更好。强烈推荐阅读David的工程博客文章…
OpenAI正在通过为Codex实施自定义沙箱来改进Windows上的代理支持,应对操作系统级别的隔离挑战,确保安全高效的运行。
CreateOS Sandbox
CreateOS Sandbox 为AI代理提供即时、硬件隔离的沙盒环境。
Codex 现在可以直接在 macOS 和 Windows 上使用 Chrome。
OpenAI 发布了 Codex 的 Chrome 扩展程序(名为 Cortex),使其能够在真实的 Chrome 浏览器中运行,支持 Cookie、会话和多标签页,从而实现自动化研究、费用报告和多智能体游戏。