0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Codex CLIの--approve-for-me、-sも-aも併用できなかった

0
Posted at

TL;DR

Codex CLI v0.148.0 を実際にインストールして --approve-for-me の挙動を測った結果です。

  • --approve-for-me は承認の粒度を細かく指定するフラグではなく、approval: on-requestworkspace-write サンドボックスの組み合わせに固定する 1 スイッチでした
  • -s/--sandbox-a/--ask-for-approval--dangerously-bypass-approvals-and-sandbox のいずれとも併用できず、引数パースの時点でエラーになります
  • codex sandbox サブコマンドで境界を測ると、workspace-write はカレントディレクトリと /tmp には書けて $HOME には書けず、ネットワークは既定で遮断されていました
  • そのネットワーク遮断が実行環境側の都合ではなくサンドボックス由来であることは、danger-full-accessnetwork_access=true の 2 つの対照実験で切り分けました
  • codex exec の既定サンドボックスは workspace-writecodex sandbox の既定は read-only で、同じ CLI の中で既定値が違いました

はじめに

Codex CLI を CI やスケジュール実行のようなヘッドレス環境で回していると、承認プロンプトをどこまで自動で通してよいかが最後まで決まりません。rust-v0.147.0 で追加された --approve-for-me は、この決めきれない部分を埋めるフラグとして紹介されています。対象読者は、Codex CLI を人が張り付かない環境で動かしていて、承認と隔離の設定を詰めたい開発者です。

ただ、リリース情報を読むと「粒度の細かい自動承認」と表現されている一方で、codex --help に並ぶ他の承認系フラグとの関係は書かれていません。-s read-only と組み合わせたら安全側に寄せられるのか、-a never と併用したらどちらが勝つのか。ここは手を動かさないと分かりませんでした。

検証環境

  • Linux コンテナ(x86_64 / kernel 6.18.5)
  • npm install @openai/codex でローカル導入した codex-cli 0.148.0(実測は ./node_modules/.bin/codex を叩いています。以下のコマンド例はグローバル導入を想定して codex と表記します)
  • 検証日: 2026-08-19(JST)
  • モデル API の認証情報は意図的に外して実行しました(承認ポリシーとサンドボックスの解決結果は、モデル呼び出しの前にセッションヘッダーへ出力されるため、推論を走らせずに測れます)

openai/codex は 2026-08-19 時点で 106.7k stars の OSS で、npm install -g @openai/codex でインストールできます(出典: openai/codex)。

1. --approve-for-me が実際に切り替えるもの

codex exec はセッション開始時に、解決済みの承認ポリシーとサンドボックスをヘッダーへ出力します。ここを読めば、フラグが最終的に何へ落ちたのかが分かります。

echo "" | codex exec --skip-git-repo-check "say hi" 2>&1 | grep -E "^(approval|sandbox|model):"

フラグを変えて 4 パターン測った結果です。

指定したフラグ approval sandbox
なし(codex exec 既定) never workspace-write [workdir, /tmp, $TMPDIR]
-s read-only never read-only
-s danger-full-access never danger-full-access
--approve-for-me on-request workspace-write [workdir, /tmp, $TMPDIR]

実際の出力はこうなりました。

OpenAI Codex v0.148.0
--------
workdir: /tmp/.../sbtest
model: gpt-5.6-sol
provider: openai
approval: on-request
sandbox: workspace-write [workdir, /tmp, $TMPDIR]
reasoning effort: none

codex exec の既定は approval: never です。つまりヘッドレス実行では、そもそも承認は求められず、サンドボックスの中で失敗したらその結果がモデルへ返るだけでした。--approve-for-me はそこを on-request引き上げます。承認を減らすフラグではなく、いったん承認要求を発生させたうえで、その可否の判断を人ではなく自動レビューへ回す、という向きの変更です。

サンドボックス側は workspace-write に固定されます。ヘッダーの [workdir, /tmp, $TMPDIR] が書き込み可能なルートの一覧で、これが後段の実測とそのまま一致しました。

2. 併用できないフラグが 3 つある

「粒度」という言葉から、--approve-for-me-s を足して隔離を強める使い方を想定していました。これは通りません。

$ codex exec --approve-for-me -s read-only "say hi"
error: the argument '--approve-for-me' cannot be used with '--sandbox <SANDBOX_MODE>'

$ codex exec --approve-for-me --dangerously-bypass-approvals-and-sandbox "say hi"
error: the argument '--approve-for-me' cannot be used with '--dangerously-bypass-approvals-and-sandbox'

$ codex --approve-for-me -a never "hi"
error: the argument '--approve-for-me' cannot be used with '--ask-for-approval <APPROVAL_POLICY>'

3 つとも引数パースの時点で落ちるため、実行前に気づけます。設定の組み合わせ爆発を CLI 側が禁じている形で、read-only なのに自動承認、のような矛盾した組を作れません。裏を返すと、workspace-write 以外のサンドボックスで自動レビューを使う手段は現時点でありませんでした。

なお codex exec には -a/--ask-for-approval 自体が存在せず、-a を渡すと unexpected argument '-a' found になります。承認ポリシーを明示指定できるのは対話モードの codex 側だけで、exec では --approve-for-me が唯一の切り替え手段でした。

3. workspace-write の境界を codex sandbox で測る

--approve-for-me が固定してくる workspace-write が実際にどこまで許すのかは、codex sandbox サブコマンドで直接測れます。このサブコマンドはモデルを呼ばず、任意のコマンドを Codex のサンドボックスに入れて実行します。

codex sandbox -c sandbox_mode='"workspace-write"' -- bash -c 'echo hi > ./t5.txt'

codex sandbox には -s/--sandbox がなく、モードは -c sandbox_mode=... で渡します。既定と workspace-write を並べた結果です。

試したこと 既定(モード未指定) sandbox_mode="workspace-write"
カレントディレクトリへ書き込み Read-only file system 成功
/tmp へ書き込み Read-only file system 成功
$HOME/root)へ書き込み Read-only file system Read-only file system
カレントディレクトリの読み取り 成功 成功
https://example.com へ HTTP 000(失敗) 000(失敗)

失敗時のメッセージは、権限拒否ではなく bash: line 1: /root/t7.txt: Read-only file system という読み取り専用マウントのエラーでした。ファイルシステムを丸ごと read-only で見せて、許可したルートだけ書けるように重ねる作りだと分かります。

ここで引っかかったのが既定値です。codex exec の既定サンドボックスは workspace-write なのに、codex sandbox サブコマンドの既定は read-only でした。同じ CLI でも入口によって既定が違うため、codex sandbox -- ... で試して「書けないから安全だ」と判断すると、エージェント本体の挙動を見誤ります。

--sandbox-state-disable-network というネットワークを落とすオプションもありますが、単独では使えませんでした。

Usage: codex sandbox --sandbox-state-json <JSON> --sandbox-state-disable-network --config <key=value> <COMMAND>...

--sandbox-state-json とセットで渡す前提のオプションで、codex/sandbox-state-meta から受け取った状態を加工するためのものでした。

4. ネットワークの 000 はサンドボックス由来か

HTTP が 000 で返ったとき、サンドボックスが遮断したのか、実行環境のプロキシ設定が効いていないだけなのかは区別が付きません。ここを混同すると記事ごと間違うため、対照実験で切り分けました。

条件 HTTP ステータス
サンドボックス外(素の shell) 200
サンドボックス内で env | grep -i proxy プロキシ変数は継承されていた
sandbox_mode="danger-full-access" 200
sandbox_mode="workspace-write" 000
workspace-writesandbox_workspace_write.network_access=true 200

プロキシ環境変数はサンドボックスの中にも渡っており、danger-full-access に切り替えるだけで同じ curl200 を返しました。したがって 000 は環境要因ではなくサンドボックスの遮断です。network_access=true を足せば workspace-write のまま通信できることも確認できました。

この 1 行を足すかどうかが、--approve-for-me を使うときの実質的な判断ポイントになります。承認を自動レビューへ委ねる以上、通信の可否は人の目を通らないためです。

5. bubblewrap が無くても動いた

Linux でのサンドボックスは bubblewrap(bwrap)に依存しますが、この環境には入っていませんでした。それでも実行は続きます。

warning: Codex could not find bubblewrap on PATH. Install bubblewrap with your OS package manager.
See the sandbox prerequisites: https://developers.openai.com/codex/concepts/sandboxing#prerequisites.
Codex will use the bundled bubblewrap in the meantime.

同梱の bubblewrap にフォールバックする旨が警告として出て、実際に上の表のとおり隔離は機能していました。CLI によってはここで停止するため、Codex CLI は導入時の前提条件が 1 つ少ない作りになっています。

著者視点の発見ポイント

フラグ名から受ける印象と、実装が置かれている位置がずれていた点が一番の収穫でした。--approve-for-me は「自分の代わりに承認しておいて」という名前どおりの機能ですが、codex exec の文脈では 承認が発生しない状態から、承認が発生する状態へ移す フラグです。すでに approval: never で回している CI に足すと、自動レビューという新しい判断者が増える方向に働きます。

もう 1 つは、併用禁止が 3 つもある点です。設定の自由度を削る仕様は使いにくく見えますが、承認ポリシーとサンドボックスは片方だけ緩めると意味が崩れる組み合わせなので、パースエラーで弾かれるほうが安全でした。実際に筆者が最初に書こうとしたコマンドは --approve-for-me -s read-only で、これは「自動レビューに任せつつ書き込みは許さない」という一見もっともらしい、しかし成立しない指定でした。

最後に、検証の順番として codex sandbox を先に触ったのは正解でした。モデルを呼ばずに境界だけ測れるので、API のコストも認証も要りません。エージェントの隔離設定を検討するときは、まずこのサブコマンドで机上の設定が実際にどう効くかを確かめるのが早い、というのが今回の実感です。

公式ソースの記述との突き合わせ

実測の裏取りとして公式側の記述も確認しました。ここは二次情報です。

--approve-for-me を追加した Pull Request(openai/codex#36373・2026-07-31 マージ)には、approval_policy="on-request"workspace-write サンドボックスで構成すること、対話モードと exec の双方に適用され、root / exec / resume / fork の引数処理に伝播することが書かれています。今回ヘッダーで観測した値と一致しました。

サンドボックスと承認ポリシーの定義は公式ドキュメントにあり、workspace-write は「エージェントはファイルを読み、ワークスペース内を編集し、その境界の中で日常的なローカルコマンドを実行できる」、on-request は「エージェントは既定でサンドボックス内で作業し、その境界を越える必要があるときに尋ねる」と説明されています。--approve-for-me は、この「尋ねる」先を人から自動レビューへ差し替えるスイッチだと読めます。

実務での使いどころ

今回の実測を踏まえた使い分けです。

  • 人が見ていない CI で、書き込みをワークスペースに閉じたまま自動で進めたい場合は --approve-for-me が素直です。既定の never と違い、境界を越える操作が黙って失敗せず、自動レビューの判断を経ます
  • 通信を伴うタスク(依存解決・API 疎通)を含むなら sandbox_workspace_write.network_access=true を明示します。既定では遮断されるため、原因不明のタイムアウトとして現れます
  • 隔離を read-only まで絞りたい場合は --approve-for-me を諦めて -s read-only を選びます。両立できません
  • 事前検証は codex sandbox で行い、既定モードの違い(execworkspace-writesandbox は read-only)を踏まえてモードを明示的に渡します

関連記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?