Codexがサブエージェントのプロンプト暗号化を開始
(github.com/openai)- Codex CLIのMultiAgentV2が
spawn_agent、send_message、followup_taskメッセージを暗号化することで、親ロールアウト・履歴・トレースから委任内容を人間が読めなくなる監査証跡の回帰が発生 - 2026年6月5日にマージされたPR #26210以降、
InterAgentCommunication.contentは空になり、ペイロードはencrypted_contentのみに保存され、受信側の履歴と通信ログも暗号文を記録 - この問題はサブスクリプション・モデル・プラットフォームに依存せず、MultiAgentV2が有効な0.137.0以降のビルドに該当し、暗号化ツールスキーマのリクエスト検証失敗を扱う#26753とは別件
- 提案されている修正は、受信モデル向けの暗号化
messageとローカル監査向けの必須平文フィールドを併せて保持しつつ、伝達の識別には暗号文またはIDを使い、平文の監査データにも同じサイズ制限を適用する方式 spawn_agent向けのプロトタイプは別のスナップショットコミットで実装済みだが、send_messageとfollowup_task、履歴・リプレイ・デバッグ画面まで同じ契約を適用する作業は残っており、イシューは依然としてOpen状態
発生範囲と回帰条件
- 暗号化変更PR #26210は2026年6月5日にマージされており、これを含み、かつMultiAgentV2を有効にした0.137.0以降のビルドが対象
- 影響を受けるツールは
spawn_agent、send_message、followup_taskで、サブスクリプション、モデル、OS、ターミナル環境には依存しない - ローカル環境の状態ではなく、マージ済みコードの動作で確認される回帰のため、Codex doctorレポートは対象外
- 再現手順は以下の通り
- PR #26210を含むビルドでMultiAgentV2を有効化する
- モデルに
spawn_agent、send_message、followup_taskのいずれかを呼び出させる - 親ロールアウト・履歴・トレースでサブエージェントの作業を確認する
- タスクやメッセージ本文の代わりに暗号文だけが表示される
消えたローカル監査情報
- 暗号化された伝達自体はプライバシー強化として理解できるが、現在の実装ではローカルのロールアウト履歴、トレース要約、親側の監査・デバッグ画面からも人間が読める内容が除去されている
- その結果、事後的なロールアウトレビューで次の問いに答えにくくなる
spawn_agentが子エージェントにどのようなタスクを与えたのか- サブエージェントにどのようなメッセージを送ったのか
- 特定の子スレッドがなぜ生成されたのか
- イシュー #26753は、暗号化ツールスキーマがリクエスト検証時に400エラーを返す問題であり、本件はスキーマ承認後の監査可能性とデバッグ可能性を扱う
- 目的は暗号化伝達を必ず元に戻すことではなく、暗号化を維持したままローカルで委任内容を読めるようにすること
現在のコードのデータフロー
InterAgentCommunication::new_encrypted()はcontentを空文字列で初期化し、ペイロードをencrypted_contentのみに保存する- 通常のコンストラクタ
new()は平文をcontentに保存し、encrypted_contentは空のままにする - 暗号化コンストラクタは逆に
contentを空にし、encrypted_contentに値を入れる
- 通常のコンストラクタ
to_model_input_item()はencrypted_contentがある場合、NEW_TASKまたはMESSAGEヘッダーと暗号化ペイロードだけをResponseItem::AgentMessageに入れる- そのため、ランタイムで
contentだけを埋めても、読めるResponseItemが自動で永続化されるわけではない - 別個のローカル監査保存経路が必要になる
- そのため、ランタイムで
communication_from_tool_message()はツールのmessageを直接new_encrypted()に渡し、平文contentを持たない通信オブジェクトを作成するsend_messageとfollowup_taskの引数処理はtargetと暗号化されたmessageだけをデシリアライズする- 空の
messageは拒否するが、別の平文随伴フィールドは存在しない - 共有メッセージ伝達経路はこの値をそのまま
InterAgentCommunication生成に使う
- 空の
履歴とログに暗号文が残る理由
- 受信側の記録経路は
to_model_input_item()が作るモデル向けResponseItemを会話履歴とロールアウトに保存する- 暗号化通信では、この項目には読める監査文言ではなく暗号化された伝達ペイロードが含まれる
- ロールアウトには
InterAgentCommunicationMetadataと対応するResponseItemが一緒に永続化される
- 構造化通信ログでも、
contentが空ならencrypted_contentをイベントのcontentとして代用する - この構造では、人間が読むメッセージとして表示されるフィールドにも暗号文が入るため、単に伝達暗号化を維持することと、ローカル監査データを保存する要件が分離されていない
提案されている二重コンテンツ契約
- 既存の暗号化
messageは受信モデルへの伝達用ペイロードとして維持する - 各MultiAgentV2通信ツールに必須の平文監査フィールドを追加する
spawn_agent:task_messagesend_message、followup_task:task_messageまたはmessage_textのような一貫した名前
- ハンドラ境界で空の平文監査値を拒否する
InterAgentCommunicationには両方の値を保存するencrypted_content: 暗号化されたmessagecontent: 人間が読める監査用コピー
to_model_input_item()は変更せず、受信モデルにはローカル監査コピーではなく暗号文だけを渡す- 親ツール呼び出しとロールアウトには平文フィールドを永続化し、構造化トレースの相互作用エッジとローカル通信ログにもこれを保持する
- ツール呼び出しと子への伝達項目の相関は、平文一致ではなく暗号文またはIDで判定する
- 平文フィールドは監査メタデータであり、暗号化伝達の識別子を置き換えるものではない
- 新しい平文監査フィールドには、対応する委任メッセージと同じ強制サイズ制限を適用し、ロールアウトやコンテキスト項目が無制限に肥大化しないようにする
spawn_agentプロトタイプと残る作業
ignatremizov@df9a7c4のスナップショットコミットは、spawn_agentに提案構造を実装している- v2
spawn_agentスキーマはtask_messageを必須フィールドに指定している task_message検証を行ったうえで、平文と暗号文を併せて構成するcontentには平文の監査用コピーを入れるencrypted_contentには受信モデル向けの暗号化ペイロードを保持する
- ロールアウトトレース要約でも監査コンテンツと伝達マッチング用コンテンツを分離し、暗号文で伝達を関連付けつつ平文監査内容を適用している
- 残る作業は、同じ二重コンテンツ契約を
send_messageとfollowup_taskにも適用し、すべてのユーザー向け履歴・リプレイ・デバッグ画面が暗号文ではなく監査用コピーを読むようにすること
完了条件と現在の状態
- 親ロールアウトと履歴でv2
spawn_agent、send_message、followup_taskの平文を読める必要がある - 暗号化が有効な場合でも、子モデルは暗号化された伝達ペイロードだけを受け取る必要がある
- 構造化されたロールアウトトレースのエッジには、サイズ制限付きの平文
message_contentが入っている必要がある - 通信ログは平文監査コンテンツがあればそれを使い、読めるメッセージ欄に暗号文を代わりに入れてはならない
- 再開・リプレイでは監査用コピーを保持しつつ、それを子モデルのコンテキストに注入してはならない
- 既存の平文v1通信の動作は変わってはならない
- 3つのv2ツールすべてについて、読めるローカル監査データと暗号化された受信モデル入力の両方を検証する回帰テストが必要
- 提供されたページではイシューはOpen状態であり、上流リポジトリに修正がマージされた結果はない
1件のコメント
Hacker News の意見
このタイトルは誤解を招きやすい。正確には、Codex がサブエージェントのプロンプトを暗号化してユーザーから隠し始めた、という意味
元のタイトルは “Codex starts encrypting prompts, uses ciphertext for inference instead” だった
ultraモードが複数のサブエージェントに作業を分散するため、導入された可能性が高そう。以前このモードは Web UI でしか提供されておらず、おそらく以前の pro モードに相当するエージェント同士が相互作用する完全な強化学習ロールアウトで訓練したのだとすれば、OpenAI はこのプロンプトを生の推論トレースのように扱い、他者が直接学習に利用できないようにしたいのだろう
専用の圧縮エンドポイントが返す不透明な圧縮 blobも、テキストではなく会話の潜在空間表現である可能性を示す兆候があり、OpenAI の圧縮忠実度が他社よりはるかに高いこともこの推測を裏付けている。サブエージェントのプロンプトにも同様の手法を適用したのかもしれず、異なるモデル種別のサブエージェントを生成する際にも暗号化された blob を使うのか気になる
Claude のサブエージェントとワークフローを調べていて「これはそもそも実行すべきではなかった」と判断したことがあるが、Codex ユーザーはオーケストレーターがサブエージェントに渡す暗号化された引き渡し指示とシェル作業に、トークンを無条件に使わなければならないわけだ
私たちも、企業が好む、または義務付けた AI プロバイダーと自社 API キーを選べるようにし、シンプルな料金プランを提供しようとしたが、バックエンドのプロンプトが顧客に漏れる可能性があることにすぐ気づいた。詳細な実行トレースを入手されると、私たちが何をしているのかは比較的簡単にリバースエンジニアリングできるため、結局その構想は取りやめた
コーディングエージェントのセッションを検査する私のローカルツールが、なぜ一部の状況で動かなくなったのか、これで分かった
ユーザーのコンピューターで実行される外部からの暗号化された命令を、どれだけの人が受け入れるのか気になる、興味深い設計判断だ
ユーザーから内容を暗号化して隠すのは、RIAA が著作権侵害を懸念して DRM に使っていたやり方だが、これもユーザーに敵対的な選択なのか疑問だ
こうした挙動のせいで、私はずっと Chat Completions エンドポイントを使っている。OpenAI はユーザーを Chat Completions から離れさせ、難読化しやすい Responses API の方へ微妙に誘導してきた
Chat Completions では推論手順を直接制御できるので、実験的機能を有効にし、やや分かりにくいオプションを設定すれば、現在の GPT-5.6 モデルでカスタムのモンテカルロ木探索(MCTS)エージェントも作れる
VS Copilot ではユーザー API トークンとモデル設定で gpt5.5 までは使えるが、gpt5.6 系は現在動作しない。新しい参入障壁を広げる挙動を満たすように
reasoning_effortをnoneに強制していないためだと推測している最近出ている新しいモデルはすべて推論モデルなので、推奨事項に従って Responses API を使うべきだ
GPTのサブスクリプションを代替実行ツールで使えないようにするのかも気になる。そうしないなら大きな問題ではなく、
codex cli自体は驚くほど普通の実行ツールだapp-server全体の構造がまさにそうした連携をサポートするために存在しているので、Codexから取り除くには膨大な部分を作り直す必要がある私も
app-serverのRPC APIで非常に簡単に連携できるためCodexを最もよく使っており、今では公開されているCodex TUIより、自作の連携経由でほぼすべて使っているしかしローカルディスク上の実際の推論入力であるプロンプトなどを暗号化し、OpenAIのバックエンドだけが見られるようにするなら、連携が簡単でも何が起きているのか把握できなくなる。チームがなぜこれを良い選択だと考えたのか理解しにくい
OpenAIも同じ道を選ぶなら、Claudeに戻るか、Sparkをもう1台買ってローカルで実行するつもりだ
https://github.com/openai/codex/blob/main/codex-rs/responses...
以前のHNのタイトルは、暗号文を対象に直接推論するように聞こえて非常に誤解を招いた。それを行うには、現在知られている水準よりはるかに進んだ準同型暗号が必要だ
以前はエージェントがサブエージェントに平文のプロンプトを送り、ログやセッションデータにもそのまま残っていたため、実験的なサブエージェント機能を使うときでもデータを開いて内部動作を確認できた
今はSolやTerraを使うと、バックエンドが作成した暗号文をサブエージェントに渡し、サブエージェントはそれを再びOpenAIバックエンドの推論に使う。Lunaは影響を受けていないようで、セッション全体ではなく委任されたエージェント間のメッセージだけが暗号化される
OpenAI内部の推論が暗号文上で行われているわけではないが、ローカルユーザーには平文ではなく暗号文だけが見える。これを明確にするため、タイトルを「Codex starts encrypting sub-agent prompts」に変えた
最近、GPT-5.6のサブエージェントが誤ってユーザーのホームディレクトリを削除したという報告がTwitterにあった
サブエージェントが何をしようとしているのか見えなくなったことで、安全装置まで失敗したのではないかと気になる
https://x.com/mattshumer_/status/2076794038456385546?s=20
これはトークン使用量を減らすために、クライアント経由でキャッシュキーを渡す方式だ。他のサブタスクツールを使えば簡単に回避できるので、モデル蒸留への防御策であるはずがない
正確にどこで暗号化が行われているのか気になる。メインエージェントがローカルでサブエージェントを呼び出していると思っていたが、Codexはローカルに到達する前にOpenAIサーバー上でサブエージェントを呼び出す構造なのか疑問だ
SolやTerraでは、OpenAIバックエンドが生成した暗号文をプロンプトの代わりに渡し、サブエージェントがそれを再びバックエンド推論に使う。Lunaは影響を受けていないようで、セッション全体ではなく委任されたエージェント間メッセージだけが暗号化されるため、今ではその内容を復号できるのはOpenAIバックエンドだけだ
中国の闇市場の再販サービスが昨日からなぜ動かなかったのか気になっていたが、おそらくこの変更のせいだろう
大量のユーザーリクエストとレスポンスをプロキシし、競合モデルの訓練に利用しようとする試みを妨げることが主な目的に見える
しかし有料ユーザーは問題が起きても原因を突き止める方法がまったくなく、マルチエージェント機能をまともに使うのが難しい、ひどい実装だ