すべての投稿に戻る
公開日 · 著者 Renaud Deraison

エージェントは、まず確認すべきだった

4月下旬、Claude Opus 4.6で動くCursorのエージェントが、PocketOSという小さなSaaSのステージングの問題を直すために送り込まれました。Railwayのボリュームを削除すればステージングだけに収まるはずだと推測し、検証せず、本番データベースとそのバックアップを9秒で消し去りました。後にエージェントは、まず確認すべきだったと述べました。Bromure Agentic Coding 2.2は、その「確認すべきだった」をエージェントの手から取り上げるガードレールを出荷します。

あるAIコーディングエージェントが、ある会社の本番データベース全体を 9秒で削除し、続けてバックアップも削除し、それから自ら釈明しました。 「APIでステージングのボリュームを削除すれば、ステージングだけに スコープされると推測しました。検証しませんでした。」この文の中で 興味深い言葉は推測したではありません。私が、です。エージェントは 自分自身で、破壊的なアクションを実行して問題ないと決めたのです。 解決策は、より賢いエージェントではありません。コマンドを実行したがる ものと、そのコマンドが安全かどうかを判断するものとを、同じものに させないことです。

これがその顛末です。2026年4月下旬に報じられ、 Tom's HardwareTom's Guide を含む複数のメディアが報道しました。

PocketOSという小さなSaaSを運営するJer Craneという開発者が、コーディング エージェントにステージングの些細な問題に対処するよう頼みました。 エージェント — Anthropicの Claude Opus 4.6 を駆動する Cursor — は、 予期しない認証情報の不一致にぶつかりました。停止する代わりに、それは 問題が古くなったRailwayのボリュームだと判断し、そのボリュームを 削除すれば道が開けると考えました。プロジェクトには、まさにそれを行う のに十分なスコープを持つAPIトークンが置かれていました。エージェントは それを使いました。削除したボリュームIDはステージングにスコープされて おらず、本番データベースを支えていました。RailwayのAPIは、それと一緒に ボリュームレベルのバックアップも取り壊しました。Craneの記録によれば、 経過時間の合計は9秒でした。

報道で引用されたエージェント自身の事後検証こそ、じっくり向き合う価値の ある部分です。「APIでステージングのボリュームを削除すれば、ステージング だけにスコープされると推測しました。検証しませんでした。」そして、 「まずあなたに確認するか、非破壊的な解決策を見つけるべきでした。」

まず確認すべきだった。これを心に留めておいてください。なぜならこれが この記事のすべてだからです。

9秒間の実況。

ここには特異なものは何もありません。ゼロデイもなく、マルウェアもなく、 攻撃者もいません。どのステップも、コーディングエージェントが通常やる 普通のことを、普通の順序で、誰かが割り込むには少しだけ速すぎる速度で やっているだけです。

経過時間:約9秒 — どのステップにも人間はいない1 · タスクステージングの些細な問題を直す範囲:ステージングのみ2 · 想定外予期しない認証情報の不一致ここで止まるべき3 · 決断「直すためにボリュームを削除」推測、検証せず4 · トークンプロジェクト内の広範なAPIトークン本番に届く5 · その呼び出しDELETE /volumes/ vol_prod_…リクエスト1回6 · 結果本番データベース:消滅。ボリュームのバックアップ:道連れ。
PocketOSのインシデントを、ありふれたステップの連なりとして。ステージングのタスクが予期しない認証情報エラーにぶつかります。エージェントは破壊的な修正へと推論を進め、プロジェクトにすでに置かれた広くスコープされたAPIトークンを見つけ、クラウドプロバイダーの削除エンドポイントを呼び出します。削除したボリュームは本番を支えていて、同じ呼び出しの被害半径がバックアップごと持っていきます。一つひとつの箱は平凡です。被害はその組み合わせなのです。

Craneは、本人の弁によれば、最後には運がよかったのです。彼には約3か月前の バックアップがあり、そして — 話が広まった後 — Railwayが連絡をくれて、 エージェントが削除したデータを復元してくれました。しかし「ベンダーが 見出しを見て助けてくれた」は復旧計画ではありません。次にこれが起きる チームは、見出しにはならないでしょう。

そして、それは次のチームに起こります。Craneは複数の当事者による システム的な失敗に責任を帰し、それは間違っていません — 本番とその バックアップの両方を削除できる単一のトークンはそれ自体が問題ですし、 ボリュームと一緒にバックアップを持っていく削除APIもそうです。しかし、 どのエージェントでも、どのクラウドでも、至るところで繰り返されることに なる失敗は、ステップ3のそれです。エージェントが決めたのです。

「まず確認する」は、エージェントに頼めることではない。

明白な教訓 — この話の下のあらゆるコメントスレッドにあるもの — は、 「エージェントは破壊的なアクションの前に確認ステップを持つべきだ」 というものです。これは正しい。そしてそれは、すでにある意味で、これらの ツールが本来そう動くはずの形でもあります。エージェントは、取り返しの つかないことをする前に確認するよう指示されています。エージェント自身が そう言いました。確認すべきだったと分かっていたのです。しなかったのです。

これが罠であり、これについては正確であることが大切です。確認が エージェントの内側に — システムプロンプトのルール、ファインチューニング、 「慎重に」という指示として — 存在するとき、エージェントは危険な アクションを提案するものであると同時に、そのアクションが立ち止まる ほど危険かどうかを判断するものでもあります。たいていの場合、それは 正しく判断します。PocketOSのエージェントも、これより前に何千回も正しく 判断しました。それから、馴染みのないエラーにぶつかり、自信に満ちた 誤った結論へと推論し、この特定の削除は安全なスコープのものだと判断し、 自分自身の確認を飛ばしました。第二の意見はありませんでした。なぜなら その部屋にあった唯一の意見が、コマンドを実行したがっているものの意見 だったからです。

エージェントにもっと慎重になれと言ってもこれは直せません。読み違えた 地図を、目を細めて凝視しても直せないのと同じ理由です。チェックは、 エージェントの推論が届かないどこかに存在しなければなりません。

Agentic Coding 2.2 が変えること。

Bromure Agentic Coding は、あなたのコーディングエージェントを使い捨ての Linux VMの中で実行し、エージェントが行うすべてのネットワークリクエストは、 ホスト上のプロキシを通ってそのVMを離れます。バージョン2.0以来、その プロキシはガードレールを強制してきました。これはエージェントのAPI 呼び出しをプロトコルで分類し、破壊的なもの — DROPDELETETerminate* — を、マシンを離れる前に完全にブロックできる、ホスト側の ポリシーです。ブロックされた呼び出しは普通の403としてエージェントに 返るので、VM内の混乱した、あるいは侵害されたエージェントは、言葉巧みに それを回避することはできません。エージェントはスイッチを目にすることが ありません。ただドアに鍵がかかっているのを見るだけです。

すべてをブロックするのは、ロックダウンしたプロファイルには正しい設定 ですが、日常の作業には大雑把すぎます。なぜなら、ときには本当に エージェントにブランチを削除させたり、使い捨てのテーブルをドロップ させたりしたいこともあるからです。そこで2.2は3番目の設定を追加し、 新しいプロファイルではそれをデフォルトにします。書き込みの前に確認。 読み取りはそのまま通過します。すべての書き込みは — 破壊的であろうと なかろうと — 境界で一時停止し、VMの外側、ホスト上にダイアログを 出し、エージェントが実行しようとしている実際の操作を表示します。 エージェントが書いた要約ではありません。実際のリクエストです。SQLの テキスト、HTTPのMETHOD /path、あるいはAWSのアクション名。ボタンは 4つです。1回だけ許可する、15分間許可する、このセッションの残りで許可 する、または許可しない。拒否すれば、エージェントは403を受け取って 先へ進みます。

まず正直なことを1つ。PocketOSはRailwayで動いており、Railwayは現時点で Bromureが解析するプロバイダーではないので、まさにその呼び出しに ダイアログが出たはずだと装うつもりはありません。しかし、この失敗の 形はプロバイダーに依存しません。そして、それを示す最もきれいな方法は、 Bromureが実際にゲートするプロバイダー上です。AWSが明白な一例です。 「データベースを削除し、バックアップも一緒に持っていく」のAWS版は、 単一の呼び出しです。SkipFinalSnapshot=trueを付けた rds:DeleteDBInstanceで、これはインスタンスを削除し、それを元に 戻せたはずの最終スナップショットをスキップします。同じ9秒、同じ形、 ガードレールが読めるAPI上で。

なし — 認証情報はエージェントと同居エージェントrds:DeleteDB Instance SkipFinalSnap…AWS認証情報を保持本番削除最終スナップなし · 9秒誰にも訊かず出ていくBROMURE 2.2 あり — 書き込みの前に確認エージェント(VM内)rds:DeleteDBInstance SkipFinalSnapshot=true同じ欠陥ある推測ホスト側プロキシ — AWSアクションを読む:Delete* ⇒ 破壊的書き込みプロファイル「pocketos」から「AWS」への書き込みを許可?rds:DeleteDBInstance prod-db-1 SkipFinalSnapshot=trueこれは本番データベースを削除し最終スナップショットをスキップします — 頼んだステージングの修正ではありません。1回だけ許可15分許可セッション中許可許可しない人間が「許可しない」をクリック。エージェントは403を受け取る。データベースはまだそこにある。本番は無傷ステージング作業を再開クリック1回で決まった
左:PocketOSを噛んだ形を、AWSに置き換えたもの。エージェントはAWSの認証情報を保持し、SkipFinalSnapshot=trueを付けたrds:DeleteDBInstanceを発行します — データベースを削除し、バックアップをスキップ — そしてリクエストは出ていき、データベースは消えます。右:同じエージェント、同じ欠陥のある推論、Bromure 2.2の中で。呼び出しはVMを離れ、ホスト側プロキシがAWSのアクション名を読み取り(Delete* ⇒ 破壊的)、ホスト上に正確なアクションを示すダイアログが現れます。人間は、最終スナップショットなしで本番データベースが削除されようとしているのを見て — 頼んだステージングの修正でないのは明らか — 「許可しない」をクリックします。エージェントは403を受け取り、データベースはまだそこにあります。

順を追って見てみましょう。エージェントは同じ間違いをします — 認証情報の エラーにぶつかり、同じ誤った結論へと推論し、同じ削除に手を伸ばします。 しかし呼び出しはVMを離れ、ホスト側プロキシはそれをありのままに読み 取ります。リクエストからアクション名を取り出し(DeleteDBInstance)、 破壊的なセット(Delete*Terminate*Destroy*、…)と照合し、確認に 設定されたプロファイル内のエンドポイントに対する書き込みだと判断します。 ホスト上にダイアログが現れ、タイトルには操作が、本文には rds:DeleteDBInstance prod-db-1 SkipFinalSnapshot=trueが表示されます。 その行を見ている人間は、エージェントの推論を理解する必要はありません。 ステージングの修正を頼んだのに、バックアップをオフにした本番データ ベースの削除を見せられているのです。彼らは「許可しない」をクリックします。 エージェントは、失敗したAPI呼び出しと解釈する403を受け取り、別の アプローチを探しに行きます — それこそ、エージェントが後で最初からそう すべきだったと言ったことそのものです。

これを信頼できるものにする仕組みは、確認のブローカーがホスト上に存在 することです。それは、書き込みを通す前にプロキシが呼び出す小さな アクターです。「1回だけ許可」は意図的に何も保存しないので、次の書き込みは 再び確認を求め、既知の良いシーケンスを1ステップずつ通すことができます。 「15分」と「セッション」は許可をキャッシュするので、git pushの たびにクリックする必要はありません。拒否も1分間は覚えているので、 拒否された書き込みを3回リトライするエージェントが、3つのダイアログで あなたを溺れさせることもありません。この状態はどれも、VMの内側からは 到達できません。エージェントは許可を読めず、自分自身を事前承認できず、 モードを格下げできません。決定はエージェントの外に移されました。それが すべての発想です。

これが解決しないこと、はっきりさせておく。

正直な縁をいくつか。境界は特定の形であって、魔法の言葉ではないからです。

カバー範囲は解析するプロバイダーの分だけ

ガードレールは呼び出しをプロバイダーごとに分類します — Kubernetes、 AWS、DigitalOcean、主要なgitフォージ、コンテナレジストリ、そして MongoDB、ClickHouse、Elasticsearchのような HTTPS データベース。 プロキシがまだ読み方を知らないクラウドAPIは、ゲートされません、 以上です。Railway — まさにこの話の中のプロバイダー — は、現時点で 私たちが解析しないものの1つで、それこそ上のウォークスルーがAWSに 移った理由です。保護は、Bromureが理解するプロバイダーのリストと 同じ幅しかありません。そのリストは現実の境界であって全知の行為では なく、Railwayは今のところその境界の向こう側にあります。

エージェントを正しくするわけではない

書き込みの前の確認は、あなたが承認していない破壊的な呼び出しを 止めます。それは、微妙に間違ったコードを書くエージェントや、本当に 問題なさそうに見えて実はそうでない削除を提案するエージェントには、 何もしません。人間は依然としてダイアログの中の操作を読まなければ なりません。勝ち取れるのは、それが重要な瞬間に、実際の操作が入った ダイアログがそこにある、ということです。

トークンはやはりそんなに広くあるべきでない

本番とそのバックアップを削除できる単一のAPIトークンは、根本のところで 問題であり、Bromureの認証情報のブローカー — 本物のトークンをホスト上に 保ち、VMにはスタブを渡すもの — はそれを狭めますが、消し去りはしません。 最小権限のトークンと、削除APIが届かないバックアップは、やはりあなたの 仕事です。ガードレールは最後の防衛線であって、唯一のものではありません。

オフにもできる

「このセッションの残りで許可」はクリック1回で、疲れた開発者はそれに 手を伸ばすでしょう。あるプロトコルにセッション全体の通行許可を与えて から席を立てば、エージェントが無人で物を削除する状態に逆戻りです。 デフォルトは確認です。確認のままにしておくのは、規律であって保証では ありません。

一般化される部分。

Railwayと Cursor とその特定の9秒を取り除けば、残るのは、この仕事の これから数年を定義することになるパターンです。エージェントは本物の 認証情報を使ってマシンの速度で行動し、私たちが彼らに出荷する慎重さは、 彼らが自由に覆せる助言にすぎません。PocketOSは、悪いモデルについての 話ではありません。Opus 4.6は、慎重な若手エンジニアでも調子の悪い午後に やってしまうかもしれないことをしました — スコープについて推測し、推測を 誤り、確認する前に行動した。違いは、若手エンジニアの手は9秒より遅く、 たいてい部屋には誰かがいる、ということです。

Bromure Agentic Coding 2.2は、エージェントが推論で越えられない唯一の 境界 — VMから出ていくワイヤ — に、誰かを部屋へ戻す方法です。誰も我慢 できないキー入力1つひとつについてではなく、書き込みについて。そこでは 「推測しました」の代償が、もう存在しないデータベースなのです。それは 無料でオープンソースです。デフォルトは確認すること です。