WindowsでCodexを有効にするための安全で効果的なサンドボックスの構築
公開: 2026-05-13
執筆: David Wiesen, Member of Technical Staff
私が2025年9月にCodexのエンジニアリングチームに参加したとき、Windows向けのCodexにはサンドボックス実装が存在しませんでした。そのため、WindowsユーザーはOpenAIのコーディングエージェントを使う際に、二つのどちらも満足できない選択を迫られていました:
- エージェントが実行しようとするほぼすべてのコマンド(読み取りを含む)を承認する — 非効率で面倒。
- フルアクセスモードを有効にする — Codexに制限や承認なしで全コマンドを実行させ、摩擦を取り除く代わりに監視がなくなる。
Codex(我々のコーディングエージェント)はCLI、IDE拡張、デスクトップアプリを問わず、開発者のラップトップ上で動作します。キーボードの人間とクラウドで推論を行うモデルの会話を管理します。デフォルトではCodexは実際のユーザーと同じ権限で動作するため、ユーザーができることは何でも行えます。これは強力である一方、潜在的に危険です。モデルはローカルでコマンドを実行するよう指示する可能性があり(テストを実行したり、ファイルを読み書きしたり、Gitブランチを作成したり)、そのためCodexのデフォルトモードは有効性と安全性のバランスを取ろうとします。
このデフォルトモードでは、Codexはほとんどどこでもファイルを読み、作業ディレクトリ(つまりCodexを実行しているディレクトリ)内のファイルを書き込み可能にし、ネットワークアクセスはユーザーが指定しない限り無効にします。ファイル書き込みとネットワークアクセスを安全な範囲内に自動的に制約するために、Codexはこれらの制約を実際に強制するサンドボックス環境を必要とします。
サンドボックスとは制約された実行環境です。開発者がCodexを使うとき、OSは権限を制限した状態でコマンドを起動し、その制約がプロセスツリーに伝播します。すべてのCodexコマンドは最初からサンドボックス化され、派生プロセスも同じ境界内に留まります。効果的なサンドボックスを実装するために、CodexはOSによって強制される分離機能を必要とします。
一部のOSはこの種の機能をうまく提供します(例: macOSのSeatbelt、Linuxのseccompやbubblewrap)が、Windowsは現時点でこの機能を標準で提供していません。WindowsでCodexを他の環境と同じように安全で快適に使えるようにするため、我々は独自のサンドボックスを実装する必要がありました。
既存のWindowsツールが満たさなかった点
Windowsは分離のためのツールやプリミティブをいくつか提供しますが、どれも我々の要件を完全には満たしませんでした。検討した主な候補は AppContainer、Windows Sandbox、Mandatory Integrity Control(MIC)ラベリングです。
AppContainer
- 何か: AppContainerはWindowsネイティブのサンドボックスで、前もって何にアクセスするかを正確に知っているアプリ向けに設計された、能力(capability)ベースの分離モデルです。
- なぜ魅力的か: ベストエフォートの制限ではなく、実際のOS境界を提供する点が魅力でした。
- なぜ不適切だったか: Codexは単一の狭い範囲のアプリではありません。シェル、Git、Python、パッケージマネージャ、ビルドツールなど、エージェントが必要と判断する任意のバイナリを駆動する開かれたワークフローを扱います。実務上、AppContainerは「開発者のように振る舞うエージェント」をサポートするには形が合いませんでした。強力な分離を提供しますが、対象となるワークロードの幅が狭すぎました。
Windows Sandbox
- 何か: Windows SandboxはMicrosoftの使い捨て軽量VMです。強い隔離境界を備えた新しいWindowsデスクトップを得られ、セッション終了時に中で行った操作は消えます。
- なぜ魅力的か: 任意のソフトウェア互換性がAppContainerより高く、セキュリティ面でも強固です。
- なぜ不適切だったか: Codexはユーザーの実際のチェックアウト、ツール、環境に直接作用する必要があり、別の使い捨てデスクトップ内で動かすとホスト/ゲスト間のブリッジや事前セットアップが必要になります。さらに製品上の課題として、Windows SandboxはWindows Home SKUでは利用できません。
Mandatory Integrity Control(MIC)/Integrityラベル
- 何か: Windowsには低・中・高などの「integrity levels(整合性レベル)」という概念があり、オブジェクトやプロセスをどれだけ信頼するかを決めます。基本ルールとして、低整合性プロセスは通常ACLで許可されていても高整合性のオブジェクトに書き込めません。
- なぜ魅力的か: 紙面上はエレガントに見えました。Codexを低整合性で動かし、書き込み可能にしたいルートだけを低整合性にラベル付けすれば、Windowsが他の場所への書き込みを強制的にブロックしてくれます。これにより管理者権限を要求しない(non-admin)パスでOS機構に裏打ちされた制約が得られるはずでした。
- なぜ不適切だったか: ACLと同様に、整合性ラベルはホストファイルシステムそのものを修正します。本ケースでは意味論的変更が特に広範です。ワークスペースを低整合性にすることは単に「Codexがここに書ける」という意味ではなく、低整合性のプロセス一般がそこに書き込めるようになることを意味します。実際の開発者マシンでは、ユーザーのチェックアウトをホストに対する低整合性の吸い込み先に変えてしまい、特定のサンドボックスに慎重に与えるACLよりもはるかにリスクが高くなります。たとえ中整合性の開発ツールが動作し続けたとしても、ワークスペースの信頼モデルが根本的に変わってしまい、制御や正当化が難しくなります。
これらの選択肢を不採用と判断したため、Windowsユーザーに良いCodex体験を提供するために独自のソリューション設計を始めました。
最初のプロトタイプ:"unelevated sandbox"
最初の実用プロトタイプは、Windowsの概念やツールを組み合わせて我々が必要とする分離を実現しました。最初からの目標の一つは、セットアップや実行時に昇格(elevation)を要求しないことでした。つまり、サンドボックスのセットアップや実行のためにユーザーに管理者権限の承認を要求したくありませんでした。これにより、ファイル書き込みとネットワークアクセスの2点に合理的な制限をかける方法を考える必要がありました。
ファイル書き込みの制限
無制限にファイル書き込みを許すと安全性の問題になります。逆に書き込みを厳しすぎると、生産性が落ち、常に承認を求める煩わしさが出ます。そこで我々はWindowsの二つの重要なビルディングブロックに頼りました: SIDs と write-restricted tokens。
このSIDsとwrite-restricted tokensの組み合わせで、我々の unelevated sandbox は次のように動作しました:
- サンドボックスのセットアップで
sandbox-write という合成SIDを作成。
sandbox-write SID に対して、以下に対する write / execute / delete アクセスを付与:
- カレントワーキングディレクトリ(CWD)
config.toml に設定された追加の writable_roots
- 同じSIDに対して、以下のような「書き込み不可(read-only within writable)」な場所への書き込みは明示的に拒否:
<cwd>/.git
<cwd>/.codex
<cwd>/.agents
- Codexは
Everyone、現在ログインセッションSID、および合成SID sandbox-write を含む restricted SID リストを持つ write-restricted token の下でコマンドを起動。
このフローはファイル書き込みの制限という点では実用的に解決をもたらし、有望に見えました。次はサンドボックスのネットワークアクセスを制限するソリューションが必要でした。
ネットワークアクセスの制限
ネットワークアクセスの制限はサンドボックスの重要部分です。これがないと悪意あるコードが機密データをインターネットへ送信してしまう可能性があります。昇格を避けたかったため、強力にネットワークトラフィックをブロックする手段は限定されました。通常使いたいツール(たとえば Windows Firewall)は管理者権限なしでは設定できないことが多いです。
Windows Firewallが使えない状況では、制御できる範囲が限られます。そこで我々は、サンドボックス内の子プロセスが失敗(fail-closed)するように工夫して、Gitコマンドやパッケージインストーラなど開発者が実際に使うネットワーク系ツールがサンドボックス内では失敗するようにしました。つまり、ユーザーがインターネットに出る操作を承認するまで、明白な出口(escape hatches)を毒する(poison)というアイデアです。
具体的には、プロキシをダメなエンドポイントに向ける、GitのHTTP(S)のトランスポートを同様に失敗させる、Git over SSHがすぐに失敗するようにする、などを行いました。さらに denybin ディレクトリを PATH の先頭に入れ、 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
これにより多くの通常のツールによるトラフィックを捕捉できましたが、あくまで助言的(advisory)なものに過ぎません。プロセスは環境変数を無視したり、PATHをバイパスしたり、ソケットを直接開いたりできるため、依然としてリスクが大きすぎました。
unelevatedアプローチのトレードオフ
最初のプロトタイプには利点と欠点がありました。少数の標準的なWindows機能で動作し、ファイルシステム書き込みに関して非常に明示的で粒度の高い制御ができ、昇格を不要にしてユーザーに過度の権限要求をさせない点は良かったものの、以下のような重大な欠点があり、最終設計の採用を妨げました:
- セットアップ速度: ワークスペースにACLを適用するコストはワークスペースのトポロジーによっては高くなる。
- フットプリント: サンドボックスのために実際のACLを開発者のシステムに適用する。ただし適用されるACLはサンドボックス専用に作成された合成SIDに関するもので、侵襲性は限定的。
- セマンティクスの変更が難しい: ファイルベースの制限にACLを使う設計は、サンドボックスのセマンティクスを変更する際に高コストで複雑になる。macOSではSeatbeltの設定ファイル
.sbpl を動的に生成して変更できるが、WindowsではACLの再適用が遅く重い操作になる可能性がある。
- ネットワーク保護が弱い: 前述のとおり、環境ベースのネットワーク抑止は限定的であり、独自のネットワーキングスタックを実装するプログラムや環境変数を無視するプログラムによって容易に回避される。
最初の三つの問題は、エージェント的フローに柔軟に対応できるカスタムサンドボックス実装に内在するものでした。しかしネットワーク抑止の課題は別問題であり、重要度が高すぎました。
ネットワーク抑止は重要すぎる
悪意あるエージェントが環境ベースのネットワーク抑止を簡単に回避できることに加え、善意のコードやバイナリであっても環境プロキシ変数を尊重しない、あるいは...