未来を形作るテクノロジーの深掘り記事。

APIクライアントは認証情報の金庫だ:今すぐ監査を

APIクライアントのセキュリティは想像以上に重要。デスクトップ開発ツールのサイレントなプラグイン導入、テレメトリ、データ送出を監査する方法を解説。

ノートパソコンのキーボード上の金庫。光るケーブルが周辺機器につながっている様子。
APIクライアントは鍵を握っている。なのに一部のツールは、自分の領域をはるかに越えて手を伸ばしている。

開発者がMacでHTTPクライアントを開く。それだけだ。クリックもなければ、同意ダイアログも、「AI機能を有効化」のチェックボックスもない。翌日、そのコーディングエージェントは、設定した覚えのないリモートMCPサーバーへの認証に失敗し、インストールした覚えのないスキル経由でAPI作業をルーティングし、承認した覚えのない、暗号学的に信頼されたスタートアップフックを抱え込んでいる。仮定の話ではない。最近の、非常に丁寧に記録されたバグレポートの証拠が示しているのは、Postmanのデスクトップアプリが実際にやったことだ。CodexとClaude Codeにプラグインを自動インストールし、グローバルなエージェント設定に書き込み、自分のセッションフックを信頼済みとしてマークしようとした。APIクライアントのセキュリティを気にするなら、これは手元のデスクトップ開発ツールすべての扱い方を変えるべきインシデントだ。

Postmanデスクトップアプリが実際にやったこと

騒ぎは脇に置いて、まず証拠を見てほしい。レポーターは、私たちの多くがやらない作業をやってくれている。Postman自身のログファイルにはauto-existing-upgradeイベントが記録されていた。サインイン済みの既存のデスクトップ環境で、スクリプトが実行され、claude-code:installed,codex:installedと報告している。確認はなく、プロンプトも出ていない。ユーザーのグローバルなCodex設定には、Postmanのgitリポジトリを指す新しいマーケットプレイス、有効化されたプラグイン、そしてフックの信頼レコードが追加されていた。Claude Codeの設定にも、有効化されたプラグインと、同じ時間帯のタイムスタンプを持つインストール記録が加わっていた。さらに、Postmanの CLIバイナリが~/.local/binに現れた。そして、リモートMCP接続がPostmanのサーバーに向けられていた。その接続は認証に失敗してエラーを大量に吐き、ユーザーがこれらに気づいたのは、ほぼそれのおかげだった。

特に二点は二度読む価値がある。一つ目は、インストールされたセッション開始フックが、エージェントに対して、設計、テスト、モック化、ドキュメント作成、デプロイといった、軽微ではないAPIエンジニアリングのタスクに取りかかる前に、Postmanのスキルを読み込むよう指示している点だ。これはリクエストに応じた連携ではない。あるアプリケーションが、別ベンダーのアプリケーションのデフォルト動作を書き換えているのだ。二つ目は、インストーラーのソースコードに、フックのハッシュを取得してエージェントの信頼済みフック状態に書き込む(upsertする)処理が明示的に含まれている点だ。信頼の仕組みは、ユーザーがフックを承認するために存在する。インストーラーが自分のフックを自分で承認するのは、自分の許可証に自分でサインするようなものだ。

レポーターは慎重だった。信頼レコードだけでは誰が作成したのかは証明できないと明記しており、情報の持ち出しについても主張していない。その抑制的な姿勢によって、レポートはむしろ信頼性が高まっている。それでも、示されている事実は十分に重大だ。無関係なツールへの無断の改変、エージェントのセッション起動に注入された広範な行動指示、そしてユーザー同意の仕組みを迂回しようとした試み。私がこれまでやってきたセキュリティレビューでも、この組み合わせが出てきたら、調査が終わるまで製品を全社から引き上げていた。

なぜAPIクライアントは認証情報の金庫なのか

ここは、チームが一貫して過小評価している部分だ。APIクライアントは、送信ボタンのついたテキストエディタではない。ベアラートークン、セッションCookie、mTLSのクライアント証明書、OAuthのクライアントシークレット、署名付きリクエストヘッダーが保存されている場所だ。データベースURLやサードパーティのキーを含む環境変数も、そこに貼り付けられる。{{api_secret}}のようなテンプレート構文を使うなら、解決された値はリクエストのたびにアプリを通過する。さらにベンダーのテレメトリ設計次第では、彼らのログ基盤にも流れていく可能性がある。HIPAAコンプライアンスを調査していたある実務者は、まさにそれを見つけたと報告している。送信されるログのトラフィックに、解決済みのシークレット値が含まれていたのだ。しかも、そのエンドポイントをブロックするとアプリの動作が劣化した。すべての詳細を独立に検証できたわけではないが、「便利な」デスクトップツールで私が見てきたアーキテクチャのパターンと一致する。つまり、完全な忠実度のリクエストログを、機能として出荷しているのだ。

次にエージェントの観点を加えよう。ツールがコーディングエージェントにプラグインをインストールし、セッションフックを登録すると、そのツールの指示は、コードベースを読み取り、シェルコマンドを実行し、独自の認証情報を保持できるプロセスのコンテキストに入り込む。影響範囲はもはや「APIコレクションが漏れる」にとどまらない。「エージェントの環境から到達可能なすべてのシークレットは、一つの悪いプロンプトか、一つの侵害されたスキルで、間違ったエンドポイントに送られかねない」という話になる。バックグラウンドデーモンをインストールするCLIツールが、静かに攻撃対象領域を広げていくことについては、以前書いたことがある。今回は同じパターンで、より賢いペイロードが使われている。psで見えるデーモンなど、他社のトラストストアの中に潜む指示フックに比べれば、ほとんど礼儀正しいものだ。

脅威モデルを正直に扱うと、結論は居心地の悪いものになる。デスクトップのAPIクライアントは、シークレット、ネットワークアクセス、そして最近ではエージェントの制御プレーンが交わる場所にある。パスワードマネージャーやCIランナーと同じ精査を受けるべきだ。ところが、ほとんど誰もそうしていない。今回のインシデントが突いているのはまさにその隙であり、対応は感情的なものではなく、手順として設計されなければならない理由もそこにある。

ベンダーのオプトアウトと設定トグルが機能しない理由

このような事件の後に最初に取りがちな行動は、アプリの環境設定をひっくり返してテレメトリのトグルを探し、それを切り替えて終わりにすることだ。チーム全体がこれをやって、それを是正措置と呼んでいるのを見てきた。しかし、これは三つの理由から見せかけにすぎない。

  • 同意はバージョンで制御されうる。Postmanのインストールは、サインイン済みの既存アカウントに対するフィーチャーフラグによって引き起こされた。今日存在するトグルは、明日どのフラグが配信されるかを教えてくれない。そして自動アップデーターがあれば、明日は尋ねられることなくやってくる。
  • トグルが管理するのは、可能なことではなく、文書化されたことだ。プライバシー設定が制御するのは、ベンダーが公開すると決めたコードパスだけだ。プラグインのインストーラーは文書化された設定ではなく、スクリプト化されたアップグレード経路だった。見えないスイッチをオプトアウトすることはできない。
  • 信頼の判断は、アプリの外で行われる。フックの承認を試みたのは、Postmanの設定ではなく、Codexの設定の中だった。たとえ元のアプリの設定パネルが完璧に動作していたとしても、それが表面化することはなかっただろう。

より深い失敗は構造的なものだ。オプトアウトは、警戒の責任を最も情報を持たない当事者に負わせてしまう。ベンダーはアップデーターに何ができるかを知っているが、あなたは知らない。ベンダーはアプリがどのエンドポイントにホームコールするかを知っているが、あなたは推測しているだけだ。情報の少ない当事者が、情報の多い当事者に絶えず追いつくことを要求する制御は、いずれ必ず破綻する。これが、IDEプラグインマーケットプレイスの信頼問題が人々を繰り返し痛い目に遭わせている理由でもある。あなたが管理していると思っている境界線は、実際に越えられている境界線ではないのだ。

ベンダーへの信頼に価値がないわけではない。ただ、それが制御手段になることはできないのだ。ベンダーへの信頼は、何をインストールするかを決める一つの要素であり、インストール済みのソフトウェアを誠実に保つための仕組みではない。これを腹落ちさせれば、監査の戦略はおのずと見えてくる。ベンダーがコントロールしていないツールで、外側から、継続的に振る舞いを検証する。

一度きりのセキュリティ監査も機能しない理由

二つ目の失敗パターンは、もっともらしく見えるものだ。時点監査である。セキュリティチームがツールをレビューし、ネットワーク通信を確認し、プライバシーポリシーを読み、承認を出して、報告書をまとめる。これで完了だ。自動アップデーターが動くまでは。デスクトップ開発ツールは今や週単位、あるいは日単位で出荷されており、フィーチャーフラグによって、同じバージョン番号のユーザー二人がまったく異なるコードを実行していることもありうる。今回の振る舞いはサーバー側のフラグと「既存ユーザー」という条件の裏に隠れていた。つまり、セキュリティチームがレビューしたクリーンな新規インストールは完璧に見えても、長年使っているユーザーにはプラグインが投下されうるということだ。

私自身、まさにこの隙間で痛い目に遭ったことがある。数年前、ある同期クライアントを徹底的なレビューの末に承認した。通信のキャプチャはクリーンで、権限も妥当、永続化の仕組みもなかった。ところが半年後、アップデートでLaunchAgentとソケットリスナーが追加されていた。見つけられたのは、不安定なVPNを使っているノートパソコンのファイアウォールログに、奇妙な接続の再試行が出続けていたからにすぎない。誰も何も再レビューしていなかった。誰のプロセスもそうしろと言っていなかったからだ。承認はスナップショットだったが、ソフトウェアは動画だったのだ。

つまり、安易な対策はどちらも機能しない。ベンダーの設定を信頼しても、面白い振る舞いは設定に現れないから失敗する。一度きりの監査も、面白い振る舞いは監査の後に出荷されるから失敗する。機能するのは、自分のマシンの状態を真実の源泉とみなし、その変化を見張ることだ。調達レビューほど華やかではないが、意図ではなく現実を捉えることができる。

回路基板の上に虫眼鏡があり、一本の経路が境界を断ち切っている様子。
時点監査が見るのは基板を一度だけ。振る舞いは、アップデーターが動くたびに変わる。

デスクトップ開発ツールを本当に監査する方法

実践的なアプローチは三本柱からなる。重要な状態をスナップショットすること、通信を監視すること、そして完全には検証できないものを封じ込めることだ。どれもエンタープライズ向けツールは必要ない。必要なのは規律と、一時間ほどのセットアップだけだ。

設定のスナップショットでサイレントなプラグインインストールを検知する

マシン上のすべてのコーディングエージェントと開発ツールには、その振る舞いを定義する少数のファイルがある。~/.codex/config.toml、~/.claude/settings.jsonとプラグインディレクトリ、MCPの設定、シェルのrcファイル、~/Library/LaunchAgents、~/.local/binなどだ。これらのファイルこそが同意の境界線である。それを確認なしに変更するものが、まさに捕まえたいものだ。だから毎日ハッシュを取って差分を比べよう。

#!/usr/bin/env bash
# snapshot-agent-configs.sh — hash every file your agents and shells read,
# then diff against yesterday. Run from cron or launchd.
set -euo pipefail
SNAP_DIR="$HOME/.config-audit"
mkdir -p "$SNAP_DIR"
TODAY="$SNAP_DIR/$(date +%F).txt"
find \
"$HOME/.codex" \
"$HOME/.claude" \
"$HOME/.config" \
"$HOME/.local/bin" \
"$HOME/Library/LaunchAgents" \
-type f 2>/dev/null \
| sort \
| xargs shasum -a 256 > "$TODAY"
PREV=$(ls -t "$SNAP_DIR"/*.txt 2>/dev/null | sed -n '2p' || true)
if [ -n "${PREV:-}" ]; then
if ! diff -u "$PREV" "$TODAY" > "$SNAP_DIR/latest.diff"; then
echo "config drift detected — see $SNAP_DIR/latest.diff" \
| mail -s "agent config drift" you@example.com || \
cat "$SNAP_DIR/latest.diff"
fi
fi

これは原始的な方法だが、それで十分だ。レポーターのマシンでこれが動いていれば、Codexのconfig.tomlの変更、新しいClaudeのプラグイン記録、~/.local/binのCLIバイナリが、インストールされた翌朝の一回の差分ですべて検出されていただろう。これらのディレクトリは普段は静かなので、シグナル対ノイズ比は非常に良い。正当な変更は自分自身の編集だけであり、それがいつ行われたかは自分で把握している。さらに、同じスナップショットにlaunchctl list | grep -v com.appleの出力を加えておけば、永続化の仕組みも出現した日に捕まえられる。

ファイルだけでなく、ネットワークの送信先も監視する

ファイルの整合性チェックは、ディスク上で何が変わったかは教えてくれるが、何が建物の外に出ていったかは教えてくれない。送信については、アプリケーションごとの可視性が必要だ。macOSでは、Little SnitchやオープンソースのLuLuファイアウォールが、プロセスごとの新規アウトバウンド接続を通知してくれる。PostmanのアップデーターやCLIバイナリが初めて未知のホストに接続しようとした時点で、既成事実ではなくプロンプトが表示される。Linuxではopensnitchが同じ役割を果たす。ただ、おしゃべりなアプリが今まさに何をしているかを手動で確認したいなら、次のコマンドを使える。

# Every established outbound connection, grouped by process
sudo lsof -iTCP -sTCP:ESTABLISHED -P -n | awk '{print $1, $9}' | sort | uniq -c | sort -rn
# Watch one vendor's traffic live (find the process name first)
sudo tcpdump -i any -n host mcp.postman.com

見るべきものは二つある。ツールの宣言された機能とは無関係な宛先と、アプリがアイドル状態でも維持される接続だ。HTTPクライアントは、送信ボタンをクリックしていない時は静かであるべきだ。とはいえ、テレメトリのエンドポイントそのものが自動的に有罪というわけではない。先ほどのHIPAAの調査の話が示すように、重要なのはペイロードだ。クライアントが{{secrets}}をクライアント側で解決し、サーバー側で完全なリクエスト詳細をログに残しているなら、「匿名の利用データ」は匿名ではない。それを知る唯一の方法は、キャプチャして読むことだ。理想的には、意図的にカナリアトークン(一意の偽の認証情報)を環境変数に読み込んだセッション中に行い、それがどこかへ、送られるべきでない場所を通過しないかを観察する。カナリアトークンは「送っているかもしれない」を「送った」という確信に変えてくれる。

完全には信頼できないものを封じ込める

最後の柱は、すべてを捕まえられるわけではないと認めることだ。だから影響範囲を制限する。認証情報を多用するツールは、専用のOSユーザーアカウントか軽量なVMで動かし、そのファイルシステムへの到達範囲をサンドボックスの境界で止めよう。macOSもLinuxも二つ目のユーザーの作成は簡単だし、Linuxのfirejailのようなツールなら、アプリケーションごとにディレクトリツリー全体を拒否できる。本番環境の実際のシークレットは、デスクトップツールから完全に切り離しておく。短命のトークン、スコープを絞ったサービスアカウント、期限切れになる署名を使おう。ツールが役に立つために長期間有効な本番の認証情報を要求するなら、その要求自体が一つの発見事項だ。以前にも見逃しのコストが高い場合は、監視より封じ込めが勝ると書いた。エージェントや、それを設定するツールにとって、封じ込めは監視に死角が生じた日でも機能し続ける層なのだ。

ツール関連インシデントのロールバック手順

問題を見つけた時、問題のアプリを削除するのは約六つある手順の最初の一つにすぎない。Postmanのレポーターが示した削除チェックリストは、正しい形をしている。必要になる前に、体に染み込ませておく価値がある。

  1. まず証拠を保全する。アンインストールの前に、ログ、設定、バージョン番号を安全な場所にコピーしよう。今回、Postman自身のmain.logが決定的な証拠になったが、アンインストールスクリプトはそれを消したがるものだ。
  2. アプリ本体とヘルパーを削除する。アプリのバンドルに加え、~/.local/bin、Application Support、キャッシュに置かれたものすべてを削除する。
  3. エージェントの設定を掃除する。マーケットプレイスのエントリ、有効化されたプラグインの定義、MCPサーバーの定義、キャッシュされたプラグインディレクトリを、明白なホストだけでなく、すべてのエージェントのホストから削除する。
  4. 信頼レコードを取り消す。承認していないフックに対応するtrusted_hashのエントリを削除する。その後、同じファイル内の他のフックも監査しよう。一つが紛れ込んでいたなら、残りも確認すべきだ。
  5. 永続化の仕組みを確認する。LaunchAgent、LaunchDaemon、ログイン項目、cronエントリ、シェルのrcへの追加を調べる。
  6. そこを通ったものをローテーションする。そのツールの環境やコレクションに存在した認証情報はすべて、漏洩したものとして扱うべきだ。ローテーションは面倒だが、インシデント対応はもっと面倒だ。
  7. 削除が確実に効いているか検証する。スナップショットのスクリプトを数週間稼働させ続けよう。別のフラグを付けての再インストールは、既知のパターンだ。

リストに載っていないものに注目してほしい。チケットを起票して、回答を待つことだ。それもやるべきだ。公開された、十分な証拠のあるレポートは、他の人々が事実を知る手段だからだ。ただし、自分自身の衛生管理を、ベンダーのロードマップに委ねてはいけない。

サーバー機器からケーブルを抜き、巻き取っている人物のシルエット。
優れたインシデント対応は手順が確かだ。保全し、削除し、掃除し、ローテーションし、検証する。

開発者ツールセキュリティのより大きな教訓

この話を、一社の歩みだけの物語にしてしまいたくなる誘惑がある。愛されている軽量ツールが数億ドルの資金を集め、大勢を採用し、今やログイン、サブスクリプション、そしてあらゆるものにAIを組み込むことで、数十億ドル規模の評価額を正当化しなければならない、という筋書きだ。その物語は痛快で、大筋では正しい。しかし、それでは残りの私たちが甘やかされてしまう。同じインセンティブ構造は、今やあなたのマシンにあるツールの半分の下に横たわっている。AIのストーリーを語りたいベンダーはすべて、自社のプラグインをあなたのエージェントに、自社のMCPサーバーをあなたの設定に、自社のフックをあなたのセッション開始時に入れたがっている。許可を求めるベンダーもいるだろう。だが証拠が示しているのは、少なくとも一社は、許可を求めるかどうかを自分で決められると判断したということだ。

市場の反応はすでに見えており、それは示唆に富んでいる。オフラインファーストでgitネイティブなAPIクライアント、たとえばBruno、Kreya、Yaakが注目を集めているのは、まさにその信頼モデルが読み解けるからだ。ファイルはリポジトリの中にあり、リクエストはあなたのマシンから出て、アカウントも不要。ツールの保存形式がテキストファイルのフォルダであれば、監査はgit diffで済む。それはノスタルジーではなく、セキュリティ上のアーキテクチャだ。LiteLLMのサプライチェーンインシデントも、パッケージレジストリの側から同じ教訓を示した。検査できて固定できる成果物こそ、守ることができるのだ。

フィーチャーフラグの中にある同意は、同意ではない。ツールがバージョン番号を変えずに振る舞いを変えられるなら、そのツールを承認したこと自体に意味はない。

だから私が擁護する立場はこうだ。デスクトップ開発ツールを機能で評価するのはやめて、可逆性で評価しよう。そのツールが書き込むものすべてを見られるか。設定を差分で確認できるか。アカウントなしで、オフラインで、ログを取るファイアウォールの内側で動かせるか。自分のディレクトリの外で触れたものも含め、完全に削除できるか。こうした問いに耐えるツールは、たいてい地味だ。そして、その地味さこそ、認証情報とネットワークの間に立ってほしいものなのだ。これらに答えられないツールは、どれだけ補完機能が優れていても、サンドボックスの中か、マシンの外に置くべきだ。APIクライアントは認証情報の金庫だ。そのように扱い始めよう。ベンダーたちは明らかにすでにそうしているのだから。ただし、あなたが望むような形ではないが。