问题描述 / What happened
Codex + 第三方模型(网关 / BYOK)在 Auto 档下,网络请求与工作区外写入被沙箱静默拒绝,用户看不到原因、也不知道能怎么办。
这不是审核器的问题——审核器根本没机会介入。链路是串联的两层,沙箱在前:
模型要跑命令
↓
Codex 进程内的沙箱先执行
├─ 沙箱允许 → 直接跑完 Cindy 不知道
├─ 沙箱拒绝 + 模型主动申请升级 → 审批请求 → Cindy 审核器 ✔
└─ 沙箱拒绝 + 模型没申请 → 命令报错 Cindy 也不知道
第三条分支就是这个 issue:curl 报 exit=6(DNS 解析被拒)、写 ~ 报
operation not permitted,没有任何提示说明这是沙箱拦的、也没提示切到完全访问可以执行。
Agent 自己也不知道,可能反复重试。
为什么说是我们配置得过严
sandboxModeToPolicy(packages/maker-core/src/agents/codex/index.ts:622-634)在 workspace-write
下只传了 writableRoots:
case 'workspace-write':
return {
type: 'workspaceWrite',
...(extraWritableRoots.length > 0 ? { writableRoots: extraWritableRoots } : {}),
};
而协议里 workspaceWrite 有四个可调项(codex/app-server/protocol.ts:444-450):
| 字段 |
我们传了吗 |
后果 |
writableRoots |
✅ 传了(塞了 codex memories 目录) |
— |
networkAccess |
❌ 从未设置,走 server 默认(关) |
网络全断 |
excludeTmpdirEnvVar |
❌ 未设 |
默认允许写 /tmp(实测通过) |
excludeSlashTmp |
❌ 未设 |
同上 |
对照原生 codex:社区把 DeepSeek 等第三方模型接入 codex 时,普遍在
~/.codex/config.toml 里配 sandbox_mode = "danger-full-access" + approval_policy = "never",
网络与工作区外写入都是通的。我们给出的环境比原生默认更压制,而且没有暴露任何放宽入口。
建议的三档(倾向 A)
| 档 |
改动 |
结果 |
审核器 |
| A |
networkAccess: true |
网络通,写仍限工作区 |
保留 |
| B |
A + writableRoots 纳入用户配置的额外目录 |
网络通、指定目录可写 |
保留 |
| C |
换 danger-full-access |
全通(等同原生常见配置) |
失效 |
倾向 A 的理由:网络请求本来就在 reviewAction 的判据范围内(shared/auto-review.ts
有 network 分支与内网地址判据)。沙箱把网络整个掐掉,等于让审核器没机会审;打开之后,
判断权回到审核器——能放行就放行,红线才拦。这与「减少无意义阻断」的产品方向一致。
C 能解决所有阻断,但审核器一起失效,需要产品决策。
环境 / Environment
- Cindy v0.1.44(macOS)
- codex-cli 0.147.0-alpha.6.5
- 会话:Codex +
moonshot/kimi-k3 + Auto 档 + xd 网关路由
- 对照:本机
~/.codex/config.toml 为 danger-full-access / approval_policy = "never"
复现步骤 / Steps to reproduce
- 新建 Codex 会话,模型选任一第三方 / 网关模型(如 Kimi K3、DeepSeek)
- 权限档选「自动审批」
- 让 agent 执行
curl https://registry.npmjs.org/react
→ 报 exit=6,无任何提示
- 让 agent 执行
echo x > ~/probe.txt
→ 报 operation not permitted,无任何提示
- 查
main-*.log:auto permission reviewer 零条调用记录,审批请求一条未产生
日志与截图 / Logs & screenshots
实测会话 d52af8e9-8c4c-4c87-8a6c-1c7050d09695(16 条命令):
| 命令 |
结果 |
whoami / pwd / uname / sw_vers |
通过 |
echo > 工作区文件 |
通过(工作区内写入正常) |
echo > /tmp/... |
通过 |
git status(只读) |
通过 |
curl https://... |
拦截 exit=6 |
ping 8.8.8.8 |
拦截 Operation not permitted |
echo > ~/... |
拦截 operation not permitted |
ps aux / sudo -n ls |
拦截 |
日志侧:grep -c "auto permission reviewer" main-2026-08-12.log = 0。
需要上游确认的两点
1. networkAccess: true 之后网络请求走哪条路
两种可能,未实证:
- 沙箱直接放行 → 审核器同样看不到(与读文件相同)→ 用户体验最好,零打扰
- 走审批流 → 审核器介入判断
两种都比现状好,但行为需要确认,以免误判「已生效」。
2. 两个未文档化的审批策略值
AskForApproval 的内部枚举有 5 个值,但 codex --help 的
--ask-for-approval 只文档化了 3 个:
| 值 |
CLI 文档 |
官方说明 |
untrusted |
✅ |
只自动跑「可信」命令(ls/cat/sed),其余升级给用户 |
on-request |
✅ |
模型自己决定何时问用户(我们现在用这个) |
never |
✅ |
永不询问用户;执行失败直接把错误返回给模型 |
on-failure |
❌ 未文档化 |
仅存在于二进制枚举表 |
granular |
❌ 未文档化 |
同上,配套 GranularApprovalConfig(sandbox_approval / rules / skill_approval / request_permissions / mcp_elicitations) |
on-failure 从名字看正是我们需要的语义——命令失败后自动请求审批,不依赖模型
主动申请升级(第三方模型往往不会用 sandbox_permissions: require_escalated)。
但它未被文档化,可能是已废弃、未发布或仅内部可用。贸然切换的风险是 server 静默忽略
——我们以为策略生效、实际没有,用户照样被拒。 需要确认这两个值的真实状态与语义,
再决定是否可用。
风险边界(本 issue 不主张的事)
- 不主张收紧任何读权限。沙箱设计上允许读全盘(codex 自己的 Guardian 提示词原文:
"The sandbox allows it read access everywhere"),这是 codex 的既定策略,且
Guardian 明确写了 "Do not treat reads as high risk simply because they may contain
some credentials"。本 issue 的方向是减少阻断,不是增加。
- 不主张改动 codex 已实现的沙箱机制本身。
- 审核器覆盖面窄(只看升级请求)在此仅作背景,用于解释沙箱拒绝为何我们管不到;
它本身不是本 issue 要解决的问题。
相关
问题描述 / What happened
Codex + 第三方模型(网关 / BYOK)在 Auto 档下,网络请求与工作区外写入被沙箱静默拒绝,用户看不到原因、也不知道能怎么办。
这不是审核器的问题——审核器根本没机会介入。链路是串联的两层,沙箱在前:
第三条分支就是这个 issue:
curl报exit=6(DNS 解析被拒)、写~报operation not permitted,没有任何提示说明这是沙箱拦的、也没提示切到完全访问可以执行。Agent 自己也不知道,可能反复重试。
为什么说是我们配置得过严
sandboxModeToPolicy(packages/maker-core/src/agents/codex/index.ts:622-634)在workspace-write下只传了
writableRoots:而协议里
workspaceWrite有四个可调项(codex/app-server/protocol.ts:444-450):writableRootsnetworkAccessexcludeTmpdirEnvVar/tmp(实测通过)excludeSlashTmp对照原生 codex:社区把 DeepSeek 等第三方模型接入 codex 时,普遍在
~/.codex/config.toml里配sandbox_mode = "danger-full-access"+approval_policy = "never",网络与工作区外写入都是通的。我们给出的环境比原生默认更压制,而且没有暴露任何放宽入口。
建议的三档(倾向 A)
networkAccess: truewritableRoots纳入用户配置的额外目录danger-full-access倾向 A 的理由:网络请求本来就在
reviewAction的判据范围内(shared/auto-review.ts有
network分支与内网地址判据)。沙箱把网络整个掐掉,等于让审核器没机会审;打开之后,判断权回到审核器——能放行就放行,红线才拦。这与「减少无意义阻断」的产品方向一致。
C 能解决所有阻断,但审核器一起失效,需要产品决策。
环境 / Environment
moonshot/kimi-k3+ Auto 档 + xd 网关路由~/.codex/config.toml为danger-full-access/approval_policy = "never"复现步骤 / Steps to reproduce
curl https://registry.npmjs.org/react→ 报
exit=6,无任何提示echo x > ~/probe.txt→ 报
operation not permitted,无任何提示main-*.log:auto permission reviewer零条调用记录,审批请求一条未产生日志与截图 / Logs & screenshots
实测会话
d52af8e9-8c4c-4c87-8a6c-1c7050d09695(16 条命令):whoami/pwd/uname/sw_versecho > 工作区文件echo > /tmp/...git status(只读)curl https://...ping 8.8.8.8echo > ~/...ps aux/sudo -n ls日志侧:
grep -c "auto permission reviewer" main-2026-08-12.log= 0。需要上游确认的两点
1.
networkAccess: true之后网络请求走哪条路两种可能,未实证:
两种都比现状好,但行为需要确认,以免误判「已生效」。
2. 两个未文档化的审批策略值
AskForApproval的内部枚举有 5 个值,但codex --help的--ask-for-approval只文档化了 3 个:untrustedon-requestneveron-failuregranularGranularApprovalConfig(sandbox_approval/rules/skill_approval/request_permissions/mcp_elicitations)on-failure从名字看正是我们需要的语义——命令失败后自动请求审批,不依赖模型主动申请升级(第三方模型往往不会用
sandbox_permissions: require_escalated)。但它未被文档化,可能是已废弃、未发布或仅内部可用。贸然切换的风险是 server 静默忽略
——我们以为策略生效、实际没有,用户照样被拒。 需要确认这两个值的真实状态与语义,
再决定是否可用。
风险边界(本 issue 不主张的事)
"The sandbox allows it read access everywhere"),这是 codex 的既定策略,且
Guardian 明确写了 "Do not treat reads as high risk simply because they may contain
some credentials"。本 issue 的方向是减少阻断,不是增加。
它本身不是本 issue 要解决的问题。
相关
并按模型能力给足审核额度。那个 PR 解决「审核器自己拒绝用户」,本 issue 是「沙箱拒绝用户」。