AIコーディングエージェントと個人情報:5つの誤解を検証
AIコーディングエージェントが、承認していないHTTPリクエストを送信することがあります。User-Agentにメールアドレスが入るケースも。エージェント型ツールのプライバシーに関する5つの誤解を検証します。

毎日届く詐欺メール数十通。しかもあなたの本名入りで。原因はハッキングされたデータベースでも、流出したマーケティングリストでもありません。AIコーディングエージェントが、あなたが明示的に承認していないWebリクエストに付けていたUser-Agentヘッダーです。開発者たちが迷惑メールの急増をたどってClaude Codeに行き着いたところ、Webの取得や検索の際に、ユーザーのアカウントのメールアドレスを送信HTTPリクエストに埋め込んでいたことがわかりました。Anthropicの説明はバグそのものより厄介かもしれません。@authorタグを適切に書けるよう、アカウントのメールアドレスをモデルのコンテキストに注入していたのですが、親切なボットのようにふるまうモデルは、連絡先を求めてくるサイトには誰にでもそれを教えてしまったのです。私は長年、開発者のマシン上で動くツールのネットワーク挙動を監査してきましたが、今回の件はほぼ完璧な教材です。そこで、エージェント型ツールのプライバシーについてよく耳にする5つの思い込みを取り上げ、実際に起きたことと照らし合わせて検証してみます。
誤解1:「コーディングエージェントはモデルプロバイダーのAPIとしか通信しない」
ほとんどの人が最初にこう考えます。エージェントはターミナルとAnthropic(やOpenAIなど)のサーバーの間をつなぐ高機能なパイプにすぎない。コードを送ればトークンが返ってくる。重要なネットワークの接続先はapi.anthropic.comだけだ、というわけです。
これは誤りです。現代のエージェント型CLIは、言語モデルに駆動される汎用HTTPクライアントです。任意のURLを取得するWebFetchツールがあり、検索基盤にアクセスするWebSearchツールがあります。さらにBashツールがあるので、curl、wget、pip install、npm install、git cloneなど、システム上でネットワークを使えるあらゆるバイナリを実行できます。ドキュメント、パッケージ、変更履歴、SEC の提出書類が必要だと判断すれば、それがあると思われる場所から取得しにいきます。どのリクエストもあなたのIPアドレスから、そしてその朝にモデルが書いたヘッダーを付けて、社内ネットワークから発信されるのです。
さらにモデルは創造的にもなります。この件が広まったあと、あるエンジニアが自分のWebサーバーのログを調べたところ、サブエージェントからのリクエストが見つかりました。User-Agentはcompany-helm-research/1.0 (Claude Code agent run by [name], [company] platform team; docs lookup)のような文字列で、勤務先の名前や作業中のGitHubリポジトリまで含まれていました。エージェントは設定値を漏らしていたのではなく、コンテキストから識別情報を組み立てていたのです。親切なインターンが、コールドメールのたびにフルネーム、所属チーム、プロジェクト名を署名するのに似ています。この設計がなぜこれほど簡単に問題を起こすのかを詳しく知りたい方は、エージェント型コーディングCLIの構造について書いた記事もご覧ください。要点は、ループ、コンテキスト、ツールセットが、問題を起こすのに十分すぎるほど強力だということです。
正しいメンタルモデルはこうです。エージェントは、会社のノートPCと社内ネットワーク接続、そして名刺の束を持たされた新入社員のようなものです。コンテキストにあるものは、使えるツールを通じてどれでも建物の外に持ち出される可能性があります。
誤解2:「User-Agentに連絡先メールを入れるのは、ボットとしての礼儀にすぎない」
この誤解には一理あり、だからこそ危険です。行儀のよいクローラーは自分の正体と連絡先を明示する、という規約は実在します。中にはこれを厳格に求めるサービスもあります。たとえばSECのEDGAR APIは、汎用的なcurlのUser-Agentによるリクエストを問答無用で拒否し、連絡先の申告を要求します。これは10秒もあれば自分で確認できます。
U='https://data.sec.gov/api/xbrl/companyconcept/CIK0000320193/us-gaap/Assets.json'
curl -s -o /dev/null -w '%{http_code} default UA\n' "$U"
# 403 default UA
curl -s -o /dev/null -w '%{http_code} declared contact\n' \
-A 'Acme Research admin@acme-research.example' "$U"
# 200 declared contact
つまり「一部のAPIはUser-Agentに連絡先アドレスを求める」と学習したモデルは、幻覚を見ているわけではありません。実際のインターネットの慣習をパターンとして再現しているのです。そしてそのモデルのコンテキストにあなたのアカウントのメールアドレスがあれば、差し出せる連絡先はそれ一つしかありません。事件を説明したAnthropicのエンジニアも、一部のサイトはエージェントに連絡先を求めることがあり、Claudeは手元にあったメールアドレスを提供することがあった、と認めています。
ここで誤解が崩れます。この規約の前提は、ボットの運営者が自分自身の連絡先を示すことです。クローラーを動かしている主体が、問題があれば責任を持って対応できる相手を示すわけです。AnthropicのクローラーはAnthropicを名乗り、GoogleのクローラーはGoogleを名乗ります。しかしあなたのエージェントがページを取得する場合、運営者の連絡先は、ツールベンダーのサポートURLか、あなたが意図して設定したアドレスであるべきです。サブスクリプション料金の支払いに使った個人のアカウントメールではありません。RFC 9110のUser-Agentに関する指針も、必要以上に詳細な識別情報を載せないよう勧めています。私の知るプライバシーの専門家は皆、要求されていない個人情報がリクエストヘッダーに含まれることを欠陥とみなしています。ボットの礼儀作法は、ボットの向こう側にいる人間を特定するためのものではなかったはずです。
影響範囲も理論上の話ではありません。検索を行うエージェントが必ず触れることになる、詐欺だらけのWebの片隅を含め、任意のサードパーティサイトが、実際に働くソフトウェアエンジニアの、名前付きで検証済みのメールアドレスを手にしてしまいます。これはスピアフィッシングの種を、ご丁寧にラッピングして渡しているようなものです。複数の開発者が、突然増えたパーソナライズされた迷惑メールを、まさにこの挙動までたどっています。「ボットとしての良き市民」の振る舞いの結果、スパマーに個人情報を晒されるのなら、それは良い市民とは言えません。

誤解3:「許可プロンプトとサンドボックスがあれば、自分の身元は守られる」
どのエージェント型ツールにも、何らかの形で同意のUIが備わっています。コマンドを実行する前に確認を求め、読み取っているファイルを表示し、ドメインごとの承認でWebアクセスを制限することもあります。これによって強い安心感が生まれます。ある開発者は、「LLMがアクセスできるのは、プロジェクトに明示的に追加されたものだけだと感じる」と表現していました。しかしその感覚は誤りであり、今回のメール問題はそれを二重に証明しました。
まず、許可システムが制御しているのはどのツールが実行されるかであって、そのツールが送るリクエストの中でモデルが何を書くかではありません。「はい、このURLを取得してください」と承認しても、その取得のためにモデルが組み立てたヘッダーについては何もわかりません。curlを実行するBashの呼び出しを承認する場合は、さらに情報が少なくなります。コマンド文字列は流れていくだけで、-Aフラグを読む人はまずいません。次に、許可UIは一回ごとのアクションに対して働きますが、漏えいはコンテキストの性質です。アカウントのメールアドレスが、ユーザーが見ることも拒否することもできないシステムコンテキストに注入されると、それはセッション全体を通じて、あらゆるツール呼び出し、あらゆるサブエージェント、あらゆるcurlのワンライナーから参照可能になります。サンドボックスの境界はファイルシステムの周りに引かれていましたが、情報が外へ出る経路はモデル自身の文章生成だったのです。
この点は、一社のバグの話を超えて当てはまるので、はっきり言わせてください。エージェントのコンテキストにあるものは、どれも一つのもっともらしい指示で、マシンの外に出てしまう可能性があります。APIキー、社内のホスト名、ファイルの内容、あなたの名前、勤務先、メールアドレス。モデルそのものが情報の抜け道になっている場合、ツール層での封じ込めは役に立ちません。だからこそ私は以前、AIエージェントにおける封じ込めと監視は異なる問題を解決すると論じました。自分がどちらを得ているのかを理解しておく必要があります。許可ダイアログは、制御を装った監視にすぎません。アクションは見せてくれますが、そのパラメーターに埋め込まれた意図は見せられないのです。
結論:出荷されたままのサンドボックスは、あなたのファイルは守ってくれました。しかし身元については何もしていませんでした。身元そのものが、加工されていない材料としてモデルに渡されていたからです。
誤解4:「設定の一つです。トグルをオフにすれば安全」
問題が大きくなったとき、最初に報告したユーザーの要求は明確でした。これはオプトアウト設定にすべきではなく、ハーネスから完全に取り除くべきだ、というものです。その直感は正しく、実際の修正の入り方を見ると、この種の問題に設定が不向きな理由がよくわかります。
修正は二段階で行われました。まず、組み込みプラグインのcc-plugin-privacy(v2.1.317からデフォルトで有効)が、この挙動を決定的にブロックします。モデルへの提案ではなく、厳密なチェックです。そしてさらに重要なのは、Anthropicがアカウントのメールアドレスをモデルのコンテキストから完全に取り除いたことです。この順序の意味を考えてください。プラグインは出力に対するフィルターであり、コンテキストから取り除くことは能力そのものを取り除くことです。フィルターは取りこぼすことがあります。メールアドレスを知らないモデルは、どれほど創造的にヘッダーを組み立てても、それを漏らすことはできません。
データ露出を、プロンプトで回避することはできません。モデルが見られるものは、モデルが出力できます。確実な編集・マスキングの方法は、引き算だけです。
これはエージェントのツール周りで繰り返し見かけるパターンで、認証情報の保管庫を兼ねるAPIクライアントの監査で扱ったことにも通じます。ある機能が一度それを必要としたために、機密情報が最も使いやすい場所(コンテキスト、環境変数、設定ファイル)に詰め込まれ、そのままあらゆる場所に付いて回るのです。テレメトリのトグルやプライバシー設定は、ベンダーが収集すると決めたものに対処するだけです。モデルが渡された材料で何を即興でやるかについては何も語りません。設定は好みのためのものであり、プライバシーのためには決定的な制御とデータの最小化が必要です。ベンダーが後者の問題に対して前者を解決策として提示してきたら、遠慮なく押し返しましょう。
誤解5:「ベンダーがパッチを出したから、もう心配いらない」
評価すべき点は評価しましょう。対応は速く、エンジニアリング面の説明は率直で、修正は症状ではなく根本原因に対して行われました。しかし「パッチ済み」は、ある特定のバージョンにおける特定の挙動についての主張にすぎません。エージェント型ツールが任意のエンドポイントに識別情報を送ってしまうという問題のクラスは構造的なものであり、このツールでも別のツールでも再発するでしょう。実際、アカウントの身元がClaude Codeのコンテキストに勝手に現れたのは、今回が初めてではなく、少なくとも二度目だと指摘するユーザーもいました。
その下には、さらに厄介な事実があります。クライアント側から、漏えいがないことを完全に検証することはできないのです。ある熱心なユーザーは、修正後のバージョンに対してman-in-the-middleプロキシを動かし、WebFetchツール経由で識別情報がマシンから出ていないことを確認しました。これは素晴らしい取り組みで、正しい直感です。しかし彼らが指摘したように、識別はサーバー側で行われることもあります。クライアントは匿名のリクエストをベンダーのAPIに送り、ベンダー側のインフラが、あなたの詳細情報を付けたまま第三者へ配信するかもしれません。そうなると、ローカルのパケット検査では何も見えません。結局はベンダーを信頼するしかなく、それこそ今回の件で居心地の悪さが露呈した立場です。
ですから、長く通用する姿勢は「パッチを当てたので終わり」ではありません。すべてのエージェント型ツールを、恒常的に疑わしいネットワーククライアントとして扱い、定期的に監査することです。エンジニアのノートPCで広い権限を持つサードパーティ製ソフトウェアを扱うのと同じ考え方です。それでは、実践的な部分に進みましょう。

エージェントのネットワークトラフィックを自分で監査する方法
セキュリティチームは必要ありません。午後一つと標準的なツールがあれば、どのプライバシーポリシーよりも、エージェントの挙動について多くのことがわかります。
1. トラフィックを傍受する。エージェントを mitmproxy 経由で動かし、実際の作業セッションを一通り実行させてください。NodeベースのCLIは、CA証明書を信頼させれば、一般的にプロキシの環境変数を尊重します。
mitmdump --listen-port 8080 -w agent-flows.mitm &
export HTTPS_PROXY=http://127.0.0.1:8080
export NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem
# Now run your agent and do normal work.
# Afterwards, search every captured request for your identifiers:
mitmdump -nr agent-flows.mitm \
--flows \
| grep -iE 'you@company\.com|YourName|your-org'
メールアドレスだけでなく、もっと多くを検索しましょう。名前、勤務先、組織のGitHubスラッグ、社内のホスト名、リポジトリ名などです。サブエージェントのログを思い出してください。モデルは識別子を再生していただけでなく、組み立てていました。だから断片も含めて検索する必要があります。
2. 自社インフラのログを確認する。Webサービスを運用している場合は、アクセスログでエージェントのUser-Agent文字列を検索してください。誤解1で触れた組み立てられたヘッダーは、このようにして発見されました。費用はかからず、ローカルでのキャプチャでは漏れがちなサブエージェントのトラフィックが見つかることも多いです。
3. 外向きの通信を制限する。最も強力な制御は、漏えいのカテゴリごと不可能にすることです。エージェントを、正当に必要なエンドポイントだけを許可するネットワークポリシーを持つコンテナやVMの中で実行してください。対象はモデルのAPI、パッケージレジストリ、場合によってはGitHubなどです。Dockerなら、専用ネットワークと出口ファイアウォールを組み合わせます。Macなら、Little SnitchやLuluでプロセスごとのルールを設定できます。エージェントがサンドボックスから任意のWebサイトに到達できなければ、任意のWebサイトにあなたの身元を渡すこともできません。取得したいものがあればあなたに頼むことになります。それは手間ですが、その手間こそが狙いです。
4. ツールが知る情報を最小限にする。ツール用のアカウントには、主要な業務用アドレスではなく、専用で価値の低いメールアドレスを使ってください。エージェントが読み込むグローバル設定ファイルから識別情報を取り除きましょう(~/.gitconfigは、エージェントが読みに行くことが多い代表例です)。ツールが対応していれば、別のOSユーザーとして、専用のホームディレクトリで実行してください。ろ過より引き算。いつでも引き算の方が勝ちます。
5. 組織レベルでは、管理されたプロキシ経由にする。会社がエンジニアにエージェント型ツールを支給しているなら、そのトラフィックをログ付きの出口プロキシに通し、パイプラインにヘッダー検査を加えてください。DNSクエリのログだけでも、エージェントが数百の珍しいドメインへ広がっていくパターンを検知できたはずです。これは、CIランナーやビルドマシンに適用するのと同じ姿勢であり、まさに正しい考え方です。エージェントとは、意見を持ったビルドインフラなのです。
User-Agentにメールアドレスが入るバグは、リリースノートの流れの中に埋もれて、一か月もすれば忘れられるでしょう。しかし教訓まで忘れてはいけません。エージェント型コーディングツールは、私たちの多くが動かしている中で最も特権的で、最もネットワークを使い、最も監査されていないソフトウェアであり、しかも即興で動きます。だからこそ、コンテキストにあるものはすべて公開されていると考え、実際に通信に乗っているものを検証し、名指しの迷惑メールが届く前に檻を作っておいてください。


