背景
大家好啊,我是逐日。刚开始用codex的时候,关于沙箱这块,遇到了不少疑惑,甚至被一个沙箱相关的问题卡了好久,差点就要重装系统。
经过一阵时间学习,简单梳理下我对codex desktop中沙箱的理解(windows平台,非使用windows上wsl2)。
本文主要学习了:https://openai.com/zh-Hans-CN/index/building-codex-windows-sandbox/
原文比较不好懂,可能要多看两遍。
chatgpt desktop中permission
下图这个地方,就是可以选择我希望codex这个agent如何运行,这个地方,下图有两个选项,其实还可以有其他选项:

如果把下图这里打开,就会多一个选项:



这三个选项是什么意思呢?( https://learn.chatgpt.com/docs/permission-modes )
| permission mode | sandbox(沙箱) | 需要突破沙盒时的审批策略(approval_policy) | 审批人 |
|---|---|---|---|
| Ask for approval(请求批准) | workspace-write | on-request(请求用户批准) | 用户自己 |
| Approve for me(帮我批准) | workspace-write | on-request(请求用户批准) | auto_review,不麻烦用户,自动审批 |
| Full access(完全访问权限) | danger-full-access | never | Not Applicable |
这三个选项其实是一组预设的值,你选Ask for approval,自动帮你配置:sandbox为工作区可写,突破沙盒时需要用户批准,不自动审批,由用户审批。沙箱什么意思?先别管,一会就知道了。
有的人说,要是我不喜欢这几个预设的选项怎么办,也简单,你自己在配置文件config.toml中去修改就行了,然后permission mode这选择:custom config.toml就行了(我这不知道扯什么风了,暂时没看到了,前两天还在)。
这几个选项里,比如sandbox,难道除了workspace-write没有别的选项了吗,有的,都有的。
参考: https://learn.chatgpt.com/docs/config-file/config-reference
sandbox_mode |
`read-only | workspace-write |
approval_policy |
`untrusted | on-request |
approvals_reviewer |
`user | auto_review` |
你要是不喜欢那三个预设permission mode选项,就自己改config.toml。

沙箱sandbox
sandbox中的workspace-write什么意思?
先要讲解这类agent中普遍的概念,project,每个project一般要选择一个本地的文件夹,如:E:\test-codex

这个E:\test-codex 目录就成了该project的workspace,后续agent主要就是读写这个目录下的文件。
workspace-write就是说,agent可以写这个目录下的文件,读呢,读是可以读整个电脑的文件。另外,这个模式下,agent不能上网。
如果是像sandbox: read-only呢,那就不能写任何的文件了,上网也不行。
为什么要有沙箱?由于agent是大模型的手和脚,大模型又是不那么确定的,是概率输出的,输出什么内容,我们无法完全预测。比如我给agent说,c盘空间不够,把c盘的垃圾清理下。然后大模型告诉agent:把"C:\Program Files"目录删掉就能空出不少空间,agent直接就上手去删。那我电脑不就废了吗?所以,agent必须在一个受限的环境中去运行,具体哪些方面受限呢,目前agent运行时的采用的沙盒主要限制的是:文件读写、网络访问。
windows中未提权沙箱的实现
在各个操作系统中的实现是不一样的,例如 macOS 上的 Seatbelt,以及 Linux 上的 seccomp 或 bubblewrap。
在windows上其实没有很好的适合agent的一套沙箱机制。根据我参考的这个文章的说法,去年2025年9月时,windows上codex是没有像样的沙箱来约束agent,要么全开,要么啥都让用户批准。
https://openai.com/zh-Hans-CN/index/building-codex-windows-sandbox/
windows中如何控制用户是否可以访问某文件
在windows pc中,我们已经习惯了管理员身份运行,但是,如果是在windows server这种服务器上,我们一般还是不会把管理员账号给每一个需要进系统的人,所以,这种情况下会有多用户使用,那就会有张三创建了张三的文件夹,李四有李四的文件夹。
如何不让张三访问到李四的文件夹呢?每个文件夹,右键属性,点安全,然后可以看到下面这图,里面点高级,可以看到另一个图:


上图这里框起来的4条,其实就是acl列表,比如最后那条,就是允许某用户可以在E:\test-codex这个目录下Read&execute。
如果这个文件夹是李四的,这个文件夹的acl中没有针对张三的acl,那张三就不能访问。
进程token
有人会问,张三能不能用一个程序去看李四的文件夹,其实这也是不行的。张三启动某个程序时,程序会拿到一个进程token(process token) .
在 Windows 中,进程令牌 (process token) 是一种安全对象,用于定义运行中进程的身份和特权。它们决定了进程可以执行哪些操作
这个token就类似于我们java里面的jwt token,你可以从token中解出token属于谁,token可以执行什么操作(具体看token中包含的scope和内容)。
这里的进程token,包含了些啥呢,其实主要就是,谁颁发的,颁发者属于哪个group,这个token有什么权限:
在Windows操作系统中,进程令牌是一个内核对象,包含了进程的安全上下文信息,用于确定进程可访问的资源和可执行的操作。令牌主要由以下部分组成:
用户SID:标识进程所代表的用户账户。
组SID:标识进程所属的用户组。
权限:定义进程可执行的操作,如读、写、执行等。
特权:一组用于系统级别操作的特殊权限。
令牌类型:表明令牌是主令牌还是模拟令牌。
源:标识令牌的来源,如登录令牌、服务令牌等。
程序是由张三启动,那token里的所属用户就是张三,程序访问李四文件夹时,检查到文件夹acl列表没有针对张三的acl,直接就拒绝访问了。
codex如果使用进程token
codex的沙盒,如果就使用上述的进程token,会有什么问题?
如果张三启动了codex,那么codex的进程token中,用户sid就是张三。那么,codex可以读取电脑上任何允许张三读取的文件夹,也可以写任何张三自己的文件夹。
假设下面两个文件夹都是属于张三的:

我现在在codex中建一个项目(workspace选:zhangsan-project1),那么,codex最终其实也可以往zhangsan-project2中去写入。
这个token的权限还是太大了,有什么办法呢?
write-restricted token
其实我们可以基于目前的进程token再创建一个权限更小的token。

上述字段SidsToRestrict这是一个sid列表(sid其实就是用户id,windows上的某个用户肯定就有sid,但也可以是虚拟的不存在的用户)
上述的函数中第二个字段是Flags,可以指定写入时必须用sidsToRestrict字段去接受额外检查:

典型用法:


现在,codex进程如果使用这种write-restricted token(假设SidsToRestrict包含一个随机生成的sid,如11111111111111),会有什么效果?下图这两个目录,张三是有权限的;但是,现在codex想往zhangsan-project1或者zhangsan-project2中去写的时候,发现write-restricted token中的SidsToRestrict包含11111111111,那就要检查这两个文件夹的acl中,是否包含对111111111111的授权,如果没有,那就不能写。

由于11111111111111这个sid是codex自己随机生成的,可以肯定,电脑上肯定没有任何一个文件夹的acl中包含对11111111111111的授权,那就整个电脑都不能写了。
但张三在codex中创建了一个项目啊(路径就是zhangsan-project1),那就单独给zhangsan-project1这个文件夹授权一下就行了。
codex project workspace首次写入文件时,acl的变化
我们先看正常没把文件夹丢给codex信任时,文件夹的acl:

在codex desktop中,创建后,此时,acl还没发生变化:
当我让它写入一个文件后,此时再去看:

现在再看,多了两个acl,一个是针对codexSandboxUsers,这个先不提;看下面那个Account Unknown的,尾号4808的,这个其实就是codex随机生成的,并且让这个sid可以写入这个文件夹:

而且,codex在C:\Users\xx\.codex\cap_sid这个文件中,记录了:

codex在后续在这个project下工作时,直接就去查询这个cap_sid文件,拿到sid,然后弄进生成的write-restricted token中。再拿着这个write-restricted token,不就可以:张三可以读的地方都能读,张三能写的地方(除了这个sid允许的地方可以写,其他地方都不能写)。
codex cli 首次trust时,acl的变化

信任后,我发现acl暂时没变化,但cap_sid中已经生成了这个目录的sid:

acl暂时还没变化:


现在变了:

windows中未提权沙箱如何实现网络控制
上面我们说了,进程拿的是write-restricted token,这个token的sid还是张三。张三肯定是可以上网的。那怎么控制这个token不能上网呢?
直接看原文吧,未提权沙箱,是只能尽力而为,没办法阻止agent下派生的进程上网。比如agent执行一个python脚本,python中直接socket连接互联网,那这里完全控制不住。这个是没办法解决的,必须依靠windows防火墙来控制,这就需要管理员权限了,这就需要使用windows提权沙箱来实现。

未完待续
sandbox = "elevated"这个提权沙箱才是正解,下篇就再讲讲这个。