OpenAI Built a Sandbox for Codex on Windows — The Journey Was More Complicated Than Expected

TL;DR · AI Summary
OpenAI built a sandbox for Codex on Windows using dual local users and restricted tokens, solving the lack of native process isolation and enabling secure default execution.
Key Takeaways
- Created two local users: CodexSandboxOffline (firewall-blocked) and CodexSandbox
- Used synthetic SIDs and Write-Restricted Tokens to achieve OS-level file write r
- Introduced codex-command-runner.exe to bypass CreateProcessAsUserW privilege bar
Outline
Jump quickly between sections.
Windows lacks mechanisms like macOS Seatbelt or Linux seccomp, making it hard for Codex to run securely by default.
AppContainer, Windows Sandbox, and Mandatory Integrity Control were unsuitable due to mismatched design assumptions.
File writes were controlled via synthetic SID and restricted token, but network blocking relied on environment variables and was easily bypassed.
Firewall rules cannot match synthetic SIDs in restricted tokens; running as a separate user became the only viable solution.
The system uses codex.exe, setup tool, command runner, and child process layers to ensure security and maintain cross-platform code clarity.
The runner runs under the sandbox user and creates the final restricted token, overcoming Windows API limitations in launching constrained processes across users.
Mindmap
See how the topics connect at a glance.
查看大纲文本(无障碍 / 无 JS 友好)
- Codex Windows 沙箱设计
- 问题挑战
- 无原生进程沙箱
- 现有机制不适用
- 技术方案
- 合成 SID + 写受限令牌
- 双沙箱用户模型
- 四层进程架构
- 核心突破
- runner 绕过权限墙
- DPAPI 加密凭据存储
- 异步 ACL 补全
Highlights
Key sentences worth saving and sharing.
The sandbox-write SID is granted via ACL to the working directory and writable_roots, while explicitly denied access to .git, .codex, and .agents.
Firewall rules cannot match synthetic SIDs in restricted tokens; matching by path or user causes collateral damage, leading to the decision to run under a dedicated sandbox user.
Splitting into separate binaries ensures codex.exe remains free of Windows-specific logic on other platforms, and UAC elevation occurs only when necessary.
A deep technical blog from David Wiesen of the Codex team. Highly recommended reading! https://t.co/S8KFYc8Pjt
Starting point: No sandbox for Codex on Windows Codex runs locally on developers' machines (CLI / IDE extensions / https://t.co/8zr7NVhjFS" / X
OpenAI built a sandbox for Codex on Windows — the journey was more complicated than expected ... A deep technical blog from David Wiesen of the Codex team. Highly recommended reading! openai.com/index/building
Starting point: No sandbox for Codex on Windows Codex runs locally on the developer’s machine (CLI / IDE extension / App), executing commands by default under the current user identity — enabling it to read/write files, run tests, and operate Git, but also introducing potential risks. macOS has Seatbelt, Linux has seccomp/bubblewrap, but Windows natively lacks the ability to "enforce strong per-process constraints." As a result, Windows users were stuck choosing between two poor options: · Approve every command (even read operations), breaking workflow fluency; · Enable Full Access, giving up all constraints.
The team's goal was to bring the "default-secure" experience that Codex already had on macOS/Linux to Windows: only allowed to write within the workspace, no network access by default, and all without requiring user intervention.
Why existing Windows solutions weren't sufficient? · AppContainer: Designed for apps with well-defined functional boundaries; Codex needs to drive arbitrary binaries like shell, Git, Python, build tools — mismatched in shape. · Windows Sandbox: It's an isolated "separate desktop," unable to directly act on the user’s real repository; also unavailable on Windows Home editions. · Mandatory Integrity Control: Marking the workspace as Low integrity means *all* Low-integrity processes can write to it, breaking the host trust model and causing excessive side effects.
First prototype: "Non-elevated Sandbox" Design principle: No UAC prompts, no admin requirement. Two things needed solving: restrict file writes + restrict network access.
- File writes: Enforced via SID + Write-Restricted Token
· Synthetic SID: Windows allows creating an identity that isn’t tied to a real user but can appear in ACLs. Codex created a dedicated sandbox-write SID. · Write-Restricted Token: A special process token where write operations require dual approval — the token’s real user must have permission, *and* at least one SID in the token’s “restricted SID list” must also be granted access. Grant the sandbox-write SID via ACL to: · Current working directory · writable_roots configured in config.toml Explicitly deny write access to .git, .codex, .agents. → This establishes a true OS-level write boundary.
- Network access: Only advisory blocking possible
Windows Firewall requires admin privileges, so only soft lockdown at the environment level is feasible:
HTTPS_PROXY / ALL_PROXY / GIT_HTTPS_PROXY = http://127.0.0.1:9
GIT_SSH_COMMAND = cmd /c exit 1Plus prepending a denybin directory to PATH, containing dummy ssh/scp binaries that intercept calls.
Effect: Blocks well-behaved tools; any program implementing its own network stack, bypassing PATH, or opening raw sockets — slips through. Purely advisory, ineffective against adversarial code.
Key turning point: Why elevation became necessary To make Windows Firewall rules truly effective, they must match by *identity*. But: · Firewall rules cannot match synthetic SIDs inside restricted tokens; · Matching by codex.exe path doesn’t cover child processes like Git/Python; · Matching by user would incorrectly block the real user; · Matching by port/address is the wrong strategy — the goal isn’t to block port 443, but to block *all outbound traffic* from this entire restricted process tree.
The only viable path: Run sandboxed commands under a *different Windows user account*. This meant abandoning the "non-elevated" constraint.
Final solution: "Elevated Sandbox"
- Introduce two local users
Created during Codex installation: · CodexSandboxOffline — fully blocked by firewall rules; · CodexSandboxOnline — not covered by blocking firewall rules.
Child processes still run under a write-restricted token with the [Everyone, Logon, Synthetic] restricted SID list, but the token’s principal (user) is now the sandbox user, not the real user.
- One-time setup step (requires admin)
· Create synthetic SID; · Create online/offline sandbox users; · Store credentials encrypted with DPAPI — inaccessible to the sandbox user itself; · Create a firewall rule blocking *all outbound traffic* for CodexSandboxOffline; · Add read ACLs for the sandbox user — because new users can’t read common directories like other users’ profiles, C:\Users, C:\Program Files by default. This step is time-consuming, executed asynchronously, non-blocking.
- Why `codex-command-runner.exe` is needed
The intuitive flow would be: codex.exe → LogonUserW → CreateRestrictedToken → CreateProcessAsUserW(child)
But there’s a privilege barrier at CreateProcessAsUserW: a process running as the real user cannot reliably launch another user’s process with a restricted token.
Solution: Split the process into two stages:
Part 1 (under real user context) · codex.exe uses CreateProcessWithLogonW to launch codex-command-runner.exe as the sandbox user (not yet restricted).
Part 2 (now under sandbox user context) · Runner uses OpenProcessToken to get its own token; · GetTokenInformation to extract logon SID; · CreateRestrictedToken to construct the final restricted token; · CreateProcessAsUserW to launch the actual child process.
- Final four-layer architecture
· codex.exe — regular, non-elevated harness; · codex-windows-sandbox-setup.exe — one-time elevated installer; · codex-command-runner.exe — runs inside sandbox user context, creates restricted token and launches child; · child process — the actual constrained command.
Benefits of splitting into separate binaries: · codex.exe remains free of Windows-specific logic on other platforms; · UAC boundary crossed only when necessary; · Long-running setup is decoupled from main process lifecycle.
Quote
Tibo
@thsottiaux
10h
We are continuing to invest in making agents work better on Windows. Highly recommend reading David's engineering post on our unique approach to windows sandboxing for Codex: openai.com/index/building