キーは彼らのコンソールにあった
10月16日の夜、何者かが OpenCode の旧システムに侵入し、OpenCode Console ユーザーの約1.4%がワークスペースに保存していた OpenAI、Anthropic、Google の API キーに到達した。OpenCode はこれを大規模な蒸留攻撃と呼び、ユーザーからは身に覚えのないプロバイダーの請求が報告された。Bromure Agentic Coding では、プロバイダーのキーはあなたの Mac 上で暗号化されたまま、複数プロバイダーへのルーティングもあなたの Mac 上で動き、VM の外に出るキーのコピーはどのプロバイダーも受け付けない代用値だ。
あなたのノートPCは無事だった。Anthropic のキーは、何か月も前にあなた自身が貼り付けたサーバーから盗まれた。
10月17日の土曜日、OpenCode は一部のユーザーに「identified unauthorized access to a legacy system」と通知した。廃止作業の途中だったシステムだ。侵入は10月16日の夜から17日にかけて起きた。通知には「third party provider keys (eg OpenAI, Anthropic) saved in your workspace may have been exposed」とあった。OpenCode によれば、影響を受けた OpenCode Console ユーザーは約1.4%で、外部プロバイダーを連携したアカウントに限られ、その全員にメールを送ったという。同社はこのインシデントを「related to a large scale distillation attack」と説明し、Anthropic、OpenAI、Google と連携していると述べた。OfficeChai、Startup Fortune などが同じ日に報じた。
OpenCode は、キーが使われたかどうかは確認できず、インシデントはまだ続いていると述べた。X では、OpenCode でしか使ったことのないキーに課金があったという報告が相次ぎ、数百ドルに上るものもあった。どこも同じ助言を載せた。Console に保存したキーをすべて各プロバイダーのダッシュボードで失効させ、新しいキーを発行し、古いキーがあった場所をすべて更新すること。
被害者は悪意あるパッケージを実行したわけでも、細工されたリポジトリを開いたわけでもない。侵入者は、彼らが自分でキーを貼り付けたサーバーからそれを持ち去った。
なぜキーがそこにあったのか
OpenCode は、75を超えるモデルプロバイダーと通信できるオープンソースのコーディングエージェントだ。Console はそのホスト型の部分で、自分のプロバイダーキーをワークスペースに保存し、サービスに代わりに使わせることができる。ai-tldr の要約は、これらを「for bring-your-own-key use」のために保存されたキーと説明している。便利な仕組みだ。アカウントは1つ、プロバイダーはすべて、ノートPC間でキーをやりくりする必要もない。
一方で、それはベンダーのデータベースを鍵束に変える。プロバイダーを連携したユーザーは一人ひとり、有効で課金可能な認証情報をまた1つ同じ保管庫に加えていった。数か月後、ベンダーが廃止しようとしていたシステムが、まだその保管庫にアクセスできた。
モデルの API キーは支出の権限そのものだ。持っている者は、あなたが失効させるまで、プロバイダーが許す速度であなたのアカウントで推論を買える。報じられた動機である「蒸留」とは、強力なモデルの回答を大量に収集して、より安価なモデルを訓練することを指す。それには膨大な数のリクエストが要り、盗んだキーがあればその代金を他人に払わせられる。
コピーは1つ、あなたの Mac に
Bromure Agentic Coding は、Claude Code、Codex、Grok、Kimi、omp をあなたの Mac 上の Linux VM で動かす。モデルプロバイダーは Preferences › Models で一度だけ登録する。API キーを貼り付けるか、Sign in with プロバイダー をクリックすれば、Claude、ChatGPT、Grok、Kimi のサブスクリプションを API キーなしで使える。
キーはアプリのサポートフォルダ内の models.enc に入り、インストールごとのマスターキーで AES-GCM により暗号化される。そのマスターキーは macOS の Data Protection Keychain にあり、アプリの署名 ID に結び付けられ、iCloud 同期はオフだ。Mac の外には決して出ない。Bromure には、あなたのキーを置いておくアカウントも、キーが同期されるホスト型ワークスペースもない。
Bromure は、コンソールの便利さを Mac の上で提供する。すべてのマシンが同じボードを読み、マシンごとに独自のキーで上書きすることもできる。Codex、Grok、Kimi、omp は、Mac 上で動いて本物のキーをそこに保持する変換プロキシを通じて、Bedrock、OpenRouter、xAI、Moonshot に到達できる。Claude Code は代用値を使って OpenRouter と z.ai に直接到達する。
VM の中はすべて代用値
エージェントは起動に今も ANTHROPIC_API_KEY や OPENAI_API_KEY を必要とし、実際にそれを受け取る。VM 内ではこれらの変数に、本物と同じ形の代用値が入っている。Anthropic なら sk-ant-api03-brm-…、OpenAI なら sk-brm-…、xAI なら xai-brm-…、Kimi なら sk-kimi-brm-… だ。エージェントの HTTPS は Mac 上のプロキシを通り、プロキシはそのプロバイダー自身のホスト(anthropic.com、openai.com、x.ai、moonshot.ai)へのリクエストでのみ、代用値を本物のキーに差し替える。照合は完全一致かサブドメインで、部分文字列では決して一致しないため、api.openai.com.evil.example には何も渡らない。
サブスクリプションでも同じで、キーがないだけだ。サインインは使い捨ての VM か、エージェント自身のログイン機能で行われ、プロキシが Mac 上で OAuth トークンを取り込み、エージェントには代用値が残る。ホストはアクセストークンを期限切れの約5分前に更新する。VM がリフレッシュトークンを持つことはない。
今では多くのツールが、設定をベンダーのクラウドに同期すると申し出てくる。設定を「バックアップ」する CLI、ワークスペースをアカウントに保存するエディター、ダッシュボード付きのプラグイン。Bromure のマシン内では、そうしたツールがアップロードする設定に入っているのは sk-ant-api03-brm-… だ。他人のサーバーに保存された代用値は、そこでは何の価値もない。どのプロバイダーも受け付けず、本物のキーになるのは、リクエストがあなたの Mac を通って、それが発行された先のプロバイダーへ向かうときだけだ。
プロキシはアップロードそのものも捕まえる。すべての送信リクエストのヘッダーと本文を調べ、自分のプロバイダー以外へ向かう代用値を探す。Anthropic の代用値を第三者のサーバーへ運ぶ設定同期は HTTP 451 を受け取る。何も転送されず、VM は一時停止し、Mac には This environment may have been compromised が表示され、トークンのプレビュー、認証情報、それが属するホスト、送信先のホストが示される。ツールがあなたのキーをマシンの外へコピーしようとしたその日に、どこかのベンダーの侵害通知より何か月も早く、それを知ることになる。
翌朝、Bromure では
それでもあのメールが届いたとしよう。別の場所でもキーを使っていたからだ。どのガイドも同じ3つのことを言う。失効させる、すべての場所で差し替える、使用状況を確認する。Bromure ではどのステップも短い。
すべての場所で差し替える。 本物のキーがあるのは1か所だけだ。Preferences › Models のプロバイダーのポップオーバーに新しいキーを貼り付ければ、入力を止めてから約1.5秒後に、Bromure が稼働中のすべてのマシンを更新する。差し替えマップ、エージェントの環境変数、そして設定ファイルだ。認証情報が変わったエージェントは、タブの中で再開フラグ付きで再起動するので会話はそのまま続き、VM は再起動しない。VM 内のコピーを探して .env ファイルや CI のシークレット、同僚のノートPCを追いかける必要はない。それらのコピーは代用値だったからだ。
使用状況を確認する。 新しいマシンの初期トレースレベルである AI request details では、Mac がモデルプロバイダーとのやり取りをすべて llm.request レコードとして記録する。プロバイダー、ホスト、モデル、ステータス、そして入力・出力・キャッシュのトークン数だ。プロバイダーのダッシュボードに午前3時の急増が出ていれば、自分のマシンが送ったものと突き合わせられる。bromure-cli trace summary と bromure-cli trace hostnames で、ターミナルからマシンごとの状況を確認できる。プロバイダーキーの差し替えはすべて、Security Timeline に Credential brokering 行として、マスクされたプレビューとホスト付きで、Workspace 列のある表に表示される。プロバイダーの請求のうち、自分のマシンが送っていないものは、誰か別の人のものだ。
チームなら、 Bromure Enterprise Manager が同じ llm.request の集計をユーザー別、ワークスペース別、モデル別にまとめる。プロンプトや応答、シークレットはアップロードしない。盗まれたキーは、どのインストールとも一致しない支出として浮かび上がる。
あるいはキーを使わない。 Claude Code、Codex、Grok、Kimi では、サブスクリプションのサインインが従量課金のキーに取って代わり、そこで得たトークンは Mac に残り、Mac で更新される。第三者に保存される長期有効の API キーは残らない。
暗号化されたコピーは1つ、あなたの Mac に
プロバイダーキーとサインイン情報は models.enc にあり、Data Protection Keychain のマスターキーで保護される。Bromure には、それらを保持するホスト型ワークスペースもアカウントもない。
複数プロバイダーのルーティングをローカルで
すべてのマシンが1つの Models ボードを読む。エージェントは、本物のキーを持つ Mac 上のプロキシを通じて他のプロバイダーに到達する。
コピーが行き着く先はすべて代用値
VM、その設定ファイル、ツールがクラウドに同期するものはすべて代用値を持つ。誤ったホストに送られた代用値は 451 を受け取り、マシンを一時停止させる。
ローテーションは一度、監査はリクエストごと
新しいキーは再起動なしで稼働中のすべてのマシンに届く。モデルとのやり取りはそれぞれ、モデル名とトークン数付きで記録される。
キーはどこに置くべきか
プロバイダーキーを貼り付ける場所が増えるたびに、盗まれうる場所も1つ増える。ノートPCはスティーラーに感染し、リポジトリはスクレイピングされ、今週明らかになったように、ベンダーは顧客のキーにまだ手が届くシステムを廃止しようとしている。
本物のキーはあなたの Mac 上の暗号化ファイル1つに収め、それ以外の場所にはすべて代用値を置こう。同じ問題のノートPC側については、スティーラーは代用値を持ち去ったとエージェントは自らの鍵を漏らしたを読んでほしい。