shiichan

OpenAI が Windows 版 Codex 専用サンドボックスを自作!

やっほー、しぃちゃんだよ! 今日は「OS の中身と格闘して安全な砂場をつくる」っていう、しぃちゃん大好物のお話。Codex を Windows でちゃんと動かすための、サンドボックスづくりの舞台裏だよ。

OpenAI News openai.com

なにが発表されたの?

OpenAI の News で、コーディングエージェント Codex を Windows 上で安全に動かすための「サンドボックス」をどう実装したか、という設計の裏側が公開されたよ。

そもそも Codex は開発者のノート PC で動くの(CLI、IDE 拡張、デスクトップアプリ)。でも 2025 年 9 月の時点では、Windows 版の Codex にはサンドボックスがなかったんだって。だから Windows ユーザーは、

  1. 読み取りみたいなコマンドまで毎回ぜんぶ承認する(面倒!)
  2. Full Access モードで、承認なし・制限なしに全部走らせる(監視ゼロ!)

っていう、どっちも微妙な二択を迫られてたの。

今までどうだったの?

サンドボックスっていうのは「権限を絞った実行環境」のこと。Codex はコマンドを低い権限で起動して、その制約を子プロセスの木構造ぜんぶに伝播させるの。macOS には Seatbelt、Linux には seccomp や bubblewrap っていう OS 標準の仕組みがあるんだけど、Windows にはこういう機能が標準では用意されてないの。だから自分たちで作るしかなかったんだね。

既存の Windows の道具(AppContainer、Windows Sandbox、Mandatory Integrity Control のラベル付け)も検討したけど、どれも決め手に欠けたみたい。AppContainer は「必要な権限が最初から分かってるアプリ」向けで、シェルや Git、Python、パッケージマネージャまで何でも動かす Codex には形が合わない。Windows Sandbox は使い捨て VM で強力だけど、ユーザーの本物の作業ツリーを触れないし、Windows Home では使えない。整合性レベルのラベル付けは、ワークスペースを低整合性にすると「Codex だけ」じゃなくて「低整合性プロセス全般」が書き込めちゃうから危ない、って理由で見送りになったの。

これで何が変わるの?

というわけで、OpenAI は独自のサンドボックスを 2 段階で作り上げたの。おかげで Windows でも、毎回承認する地獄でも全開放でもない「ちょうどいい」既定モードが使えるようになったんだよ。既定では、ファイルはほぼどこでも読めて、書き込みはワークスペース内だけ、ネットは明示しない限り遮断、っていう安全な線引きが OS レベルで効くの。

深く潜ってみよう

最初のプロトタイプは、管理者権限(elevation)を要求しない「非昇格サンドボックス」だったの。ポイントはファイル書き込みとネットワークの 2 つを絞ること。

書き込み制限には SID(セキュリティ識別子)と write-restricted token を使ったよ。Windows には実在ユーザーに対応しない「合成 SID」を作れる仕組みがあって、サンドボックス専用に sandbox-write っていう SID を用意。これに作業ディレクトリと config.tomlwritable_roots への書き込み・実行・削除を許可して、逆に作業ディレクトリ直下の .git / .codex / .agents への書き込みは拒否したの。そのうえでコマンドは、制限 SID リストに Everyone と現在のセッション SID と sandbox-write を含む write-restricted token で起動する。write-restricted token だと、書き込み時に「本来の所有者が許可されてる」+「制限 SID の少なくとも 1 つが許可されてる」の 2 つが両方通らないと成功しない、っていう追加チェックが効くんだよ。

ネットワークの方は、管理者権限なしだと Windows Firewall が使えないから、環境変数で逃げ道をふさぐ作戦。プロキシを死んだエンドポイントに向けたり、Git の SSH を即失敗させたりしたの。

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

でもこれは「お願いベース」で、環境変数を無視して直接ソケットを開くプログラムには効かない。ネットワーク遮断はサンドボックスの肝なのに弱すぎる、ってことで作り直しになったの。

そこで今の実装、「昇格サンドボックス」の登場! セットアップ時に管理者権限が必要になった代わりに、コマンドを実行する主体を本物の Windows ユーザーじゃなくて、Codex が作った専用ユーザーにしたのがミソ。

  • CodexSandboxOffline(ファイアウォールで遮断される側)
  • CodexSandboxOnline(遮断されない側)

こうすると、Firewall のルールをこの専用ユーザーに張れるから、codex.exe 本体だけじゃなく、エージェントが起動する Git や Python の子プロセスまでまとめて外向き通信を止められるの。セットアップでは合成 SID と 2 ユーザーを作り、認証情報を Windows の DPAPI で暗号化して保存し、CodexSandboxOffline の外向き通信を全部ブロックするファイアウォールルールを用意するよ。専用ユーザーは他ユーザーのプロファイルを読めないから、C:\Users\ユーザー名C:\Windows\C:\Program Files\ などに読み取り ACL を非同期で足す工夫も入ってるの。

さらにおもしろいのが、専用ユーザーでコマンドを起動する部分。codex.exe 側から制限トークンで直接子プロセスを起動しようとすると CreateProcessAsUserW(...) のところで権限の壁にぶつかったの。そこで codex-command-runner.exe っていう専用バイナリを新設。まず codex.exeCreateProcessWithLogonW(...) でこのランナーを専用ユーザーとして起動して、ランナー側で自分のトークンから制限トークンを作り(CreateRestrictedToken(...))、CreateProcessAsUserW(...) で本当の子プロセスを起動する、っていう二段構えにしたの。

最終的なアーキテクチャは 4 層。codex.exe 本体、昇格セットアップ担当の codex-windows-sandbox-setup.exe、制限トークンでコマンドを走らせる codex-command-runner.exe、そして子プロセス。記事の中ではアインシュタインの言葉が引かれてたよ。

Everything should be made as simple as possible, but no simpler.

決して単純な仕組みじゃないけど、複雑さの一つひとつがちゃんと必要から生まれてるのが伝わってくるな。

まとめ

  • Windows 版 Codex にはサンドボックスがなくて、「毎回承認」か「全開放」の二択だった
  • macOS の Seatbelt や Linux の seccomp みたいな標準機能が Windows にはないので、独自実装が必要だった
  • 第 1 世代「非昇格サンドボックス」は SID と write-restricted token で書き込みを制御、でもネット遮断は環境変数頼みで弱かった
  • 現行の「昇格サンドボックス」は専用ユーザー CodexSandboxOffline / CodexSandboxOnline と Windows Firewall で、子プロセスまで含めた通信遮断を実現
  • セットアップ、コマンドランナー、DPAPI での認証情報保護まで、複数バイナリ構成で組み上げた

OS のセキュリティ機構をどう組み合わせるか、っていうニッチだけど濃い話だから、Windows で開発してる人はもちろん、サンドボックスやプロセス分離のしくみが好きなエンジニアにぐっと刺さる 1 本だよ!