🧠

[Codex] sandbox実行の仕組みと設定方法を完全に理解する

に公開

はじめに

Claude Code や GitHub Copilot と Codex の最大の違いの一つとして、「Codex が“モデル生成して実行するコマンド”は、原則 sandbox_mode の制約下で動作する」という点があります。

別のCodingAgentからCodexに乗り換えた方など、このSandbox制約に阻まれてうまく利用できていない方も多いのではないでしょうか。

対象

  • Codex初心者
  • sandbox制限がよくわからないのでとりあえず danger-full-access を常用している
  • Codexにやらせたいことがある(例:pnpm install、xcodebuild、特定スクリプト実行など)が、sandbox で落ちるので結局そこだけ手動で回している

そもそもSandboxとは?

Sandboxとは、プログラムがシステムの他の部分に悪影響を及ぼさないように、外界から隔離したり、触れられる機能(ファイル・ネットワーク等)を制限したりして、万一そこで問題が起きても影響が外に広がらないように設計された実行環境(領域)や仕組みのこと。

VMやコンテナのような仮想環境だけでなく、同一OSで動作する「アクセス制御された実行コンテキスト」も同様にSandboxと呼ばれている。

CodexはなぜSandboxでの実行を採用しているのか?

Coding Agentは基本的にApproveさえあれば何でも実行可能で、かつ多くの方が自動承認を使用しているかと思います。

AIちゃんはときどきお馬鹿なので、例えばこんなコマンドも無邪気に叩いてしまうみたいです。
https://x.com/mugisus/status/1940127947962396815

Codex はそういった危険なコマンド/意図しないコマンドの実行を防ぐために

  • Approval(認可):実行してよいかどうかをユーザが決定する
  • Sandbox:Agentがアクセスできる資源(ファイル・ネットワーク等)をルールベースで制限する

という二段構えで設計されています。

つまり、確認がすり抜けたり auto-approve が強すぎたりしても、ファイルの書き込み先やネットワーク到達範囲を絞って、被害が広がりにくいような思想となっています。

※ClaudeCodeもSandboxでの実行が可能ですが、あくまでオプションという位置づけなのでそもそもの設計思想の違いがありそう。

(図案)二層モデルの箱図(approval → sandbox → execution)

Codex の sandbox_mode を理解する

Codexには以下3つの sandbox_mode が用意されています。

  • read-only:読む/調べる用途(副作用を極小化)
  • workspace-write:ワークスペース内で完結する開発作業(必要なら追加許可)
  • danger-full-access:実質“制限を大きく外す”最終手段(隔離は期待しない)

Codexの「コマンドをどう実行するか」は、ざっくり 2段階で決まります。

  1. そのコマンドを sandbox外で実行してよいか(allow/prompt/forbidden)(=rules
  2. sandboxで実行する場合、sandbox内で何が許されるか(ファイル/ネットワークなど)(=sandbox_mode

1. サンドボックス外に“エスカレート”してよいかの判定(~/.codex/rules

最初の分岐は、コマンドのパターンに対するルール(exec-policy / rules) で決まります。
ここで決めるのは、サンドボックス内の権限ではなく、そもそもそのコマンドを サンドボックス外で 実行してよいか(または承認/禁止)です。

  • allow:サンドボックス外で実行(承認なし)
  • prompt:サンドボックス外に出す前に承認が必要
  • forbidden:実行を禁止

(複数マッチ時はより厳しい決定が優先)

設定例

~/.codex/rules/default.rules
# Prompt before running commands with the prefix `gh pr view` outside the sandbox.
prefix_rule(
    # The prefix to match.
    pattern = ["gh", "pr", "view"],

    # The action to take when Codex requests to run a matching command.
    decision = "prompt",

    # Optional rationale for why this rule exists.
    justification = "Viewing PRs is allowed with approval",

    # `match` and `not_match` are optional "inline unit tests" where you can
    # provide examples of commands that should (or should not) match this rule.
    match = [
        "gh pr view 7888",
        "gh pr view --repo openai/codex",
        "gh pr view 7888 --json title,body,comments",
    ],
    not_match = [
        # Does not match because the `pattern` must be an exact prefix.
        "gh pr --repo openai/codex view 7888",
    ],
)

詳細な設定方法は以下Codex公式ドキュメントをご参照ください。
https://developers.openai.com/codex/rules

2. sandboxで実行する場合の制御 (~/.codex/config.toml

ここからは「サンドボックス内で実行する」と決まった後に、Codex が どこまで触れてよいかを決める仕組みを整理します。
(※「サンドボックス外で実行する/しない」を決めるのは別レイヤー=rules/exec-policyの話)

サンドボックス側の制御は、ざっくり次の3要素です。

  • モード(sandbox_mode)
    • sandbox_mode:read-only: 書き込みを伴う操作・ネットワークを強く制限(読み取り中心)
    • sandbox_mode:workspace-write: ワークスペース内は書き込み可能。必要なら追加の書き込み先やネットワーク許可を設定
      • network_access: 外部通信の許可設定
      • writable_roots: workspace外で書き込みOKにするディレクトリ
    • sandbox_mode:danger-full-access: 非推奨

read-only

read-only は「ログやソースを読んで原因を推測する」「設定や差分案を提示する」用途のモードです。

  • できること:ワークスペース内のファイルを読んで理解する、検索して根拠を示す
  • やらないこと:編集・生成・削除など 書き込みを伴う操作、ネットワークアクセス(=副作用が出やすいこと)
~/.codex/config.toml
sandbox_mode = "read-only"

workspace-write

基本はこのモードを使用することになると思います。

workspace-write は、実際に手を動かして開発するためのモードです。
ただし「何でもできる」わけではなく、落とし穴はだいたい2つに集約できます。

~/.codex/config.toml
sandbox_mode = "workspace-write"

# Extra settings used only when sandbox_mode = "workspace-write".
[sandbox_workspace_write]
# Additional writable roots beyond the workspace (cwd). Default: []
writable_roots = ['/tmp/']
# Allow outbound network access inside the sandbox. Default: false
network_access = true
# Exclude $TMPDIR from writable roots. Default: false
exclude_tmpdir_env_var = false
# Exclude /tmp from writable roots. Default: false
exclude_slash_tmp = false

danger-full-access

danger-full-access は「サンドボックスの制約を大きく外す」モードです。
非推奨なのであえて説明しません。

(VMや開発コンテナ上など、完全に切り離された安全な環境で使用するならOK)

詳細な設定はCodex公式ドキュメントをご参照ください。
https://developers.openai.com/codex/config-basic


Sandbox 制限を回避するには?

まず前提として、ここで言う「回避」は ノーガードにする(= danger-full-accessにする) という意味ではありません。
目指すのは「Codex にやらせたい作業を通す」ことですが、同時に 例外点を最小化して、事故の余地を増やさない形に寄せるのが現実的です。

Sandbox に弾かれる理由はだいたい次の3つに分解できます。

  • 書き込み先の問題:ワークスペース外(例:~ 配下、~/Library、グローバル領域)に書こうとしている
  • ネットワークの問題:外部DLやAPI呼び出しが必要
  • OS資源の問題:GUI/IPC/特権的な機能に触れている(ブラウザ起動、Xcode周辺など)

なので回避策も、基本はこの3つに対応させて考えると整理しやすいです。

まずは「どの資源で弾かれているか」を当てる

Sandbox で落ちたときはまず原因を分類してみましょう。

  • permission denied / not permitted 系 → 書き込み先が怪しい
  • network is disabled / connection failed 系 → ネットワークが怪しい
  • GUI/デバイス/IPC っぽいエラー → OS資源が怪しい

書き込み先を最小で増やす(workspace-write を維持する)

ほとんどのケースはこれで、 workspace-write でもツール側が ~/.cache~/Library などにキャッシュ・設定・履歴を書こうとして落ちることが多いです。

このときの基本方針は2つです。

1. 書き込み先をワークスペース内に寄せる

ツール側の環境変数や設定でログ/キャッシュの出力先を変えます。
global領域への書き込みは最小限に留めるのが普通にベストなので、それが可能ならそれが良いです。

2. 必要なディレクトリだけ追加で書き込み許可する

globalに扱いたいpackage manager系、環境変数で出力先を変更できないツール等は1で回避できないので、必要なディレクトリに書き込み許可を追加しましょう。

npmやgradleのキャッシュ等はこれに該当するので、 例えば config.toml に以下のように設定追加しておけばOKです。
~/.codex/config.toml でも良いが、workspace側の config.toml に書いたほうが安全かも)

~/.codex/config.toml
[sandbox_workspace_write]
writable_roots = ['/Users/user/.cache']

OS資源に触る処理は例外として割り切る

xcodebuild や GUI/ブラウザ起動系は、ファイル・ネットワークとは別に OS資源(IPC、サービス、権限) に触れます。ここは Sandbox と相性が悪く、workspace-write ではどうしても通りにくいケースがあります。

このタイプにおいても danger-full-access に逃げるのではなく、

  • 「OS資源に触る処理だけ」
  • 「サンドボックス外で」 実行し
  • 「毎回承認(prompt)」 を挟む

という形で 例外を局所化 することが重要。

例:xcodebuild だけ “外実行 + 毎回承認” にする

~/.codex/rules/default.rules
# Xcode build/test はサンドボックス外で実行するが、毎回承認を挟む
prefix_rule(
  pattern = ["xcodebuild"],
  decision = "prompt",
  justification = "xcodebuild may require OS services (Simulator/Keychain/etc.) and writes outside workspace; run outside sandbox only with approval",
  match = [
    "xcodebuild test -scheme App -destination 'platform=iOS Simulator,name=iPhone 15'",
    "xcodebuild build -scheme App",
  ],
)

# `xcrun xcodebuild ...` で呼ぶ場合も同様に扱う
prefix_rule(
  pattern = ["xcrun", "xcodebuild"],
  decision = "prompt",
  justification = "xcrun xcodebuild should require approval when running outside the sandbox",
  match = [
    "xcrun xcodebuild test -scheme App",
  ],
)

# 危険なコマンドは明示的にブロックしておく
prefix_rule(
  pattern = ["sudo"],
  decision = "forbidden",
  justification = "Never run sudo from Codex",
)

prefix_rule(
  pattern = ["rm", "-rf", "/"],
  decision = "forbidden",
  justification = "Never",
)

この設定にしておくと、普段の作業は workspace-write のまま安全寄りに回しつつ、どうしてもサンドボックスと相性が悪いコマンドだけを例外として扱いやすくなります。


[補足] MCPサーバを経由する

MCPサーバが「ホスト側でのコマンド実行」や「外部ツール操作」を提供している場合、Codex 本体のサンドボックスとは 別の経路(別の信頼境界) で処理が走ることがあります。
その結果、見かけ上は workspace-write でも実行できるケースがあります(例:Playwright系)。

ただし、MCPサーバ経由で何でもできる…という状態になると結局 danger-full-access と同じくガバガバ権限設定になるため要注意です。


まとめ:おすすめの優先順位

Sandbox 関連で実行制御が難しくなったときは、以下の順序で整理していくと安全に許可設定を追加することができます。

  1. 原因を分類(書き込み先 / ネットワーク / OS資源)
  2. まずは workspace-write のまま、ツール側の書き込み対象をworkspace内に寄せる or config.tomlに書き込み可能なパスを追加する
  3. それでも無理なら、 sandbox外で実行するように設定(rules) する
  4. MCP は便利だが、増やすほど 安全境界が曖昧になるので慎重に

まとめ

  • approval は 実行可否をユーザが判断、sandbox は OSレベルのサンドボックス機構で資源アクセスを制限 する
  • Codexでは原則コマンド実行をサンドボックスで行う(ただし rules によりサンドボックス外へエスカレート可能)
  • Codexでは操作権限を指定できるが、原則 read-only もしくは workspace-write を指定する(danger-full-access は使用しない)
  • workspace-write で sandbox 制限を回避するためには概ね以下で対応する
    • ツール等の書き込み先をworkspace内に寄せる
    • 書き込み先許可設定を追加する (config.toml)
    • 特定パターンのコマンドは sandbox外で実行するよう設定を追加する (rules)
    • MCP経由で実行する

おわりに

Codexは制約が強い分、「自動承認機能を有効化して長時間稼働させておく」といった使い方に適しているように思います。
Cline系が「暴走列車」と例えられていたのが懐かしい…(もはや1年前のトレンドですね)。

ツールの設計思想を理解したうえで適切に扱いましょう。

Discussion