承認ダイアログの「Yes, and don't ask again」は、通したコマンドをそのまま設定ファイルへ書き残す。Apiiroが公開リポジトリを数えると、認証情報を含むファイルが1,122件出てきた。
Claude Code secrets leakは便利ボタンから始まる
Apiiroは11月5日、Claude Codeの承認機構を調べた結果を公開した。エージェントがシェルコマンドを実行する前に出す確認で「Yes, and don't ask again」を選ぶと、そのコマンドは許可リストのルールとしてプロジェクト内の設定ファイルに残る。認証情報が入った文字列でも、そのまま保存される。
don't ask again Claude Codeが平文で書くもの
ファイルはJSONで、許可したコマンドが文字列として並ぶ。PGPASSWORD= を付けた psql のコマンドを一度通せば、パスワードを含む行がそのまま残る。sshpass -p や mysql -p も同じ扱いだ。値は暗号化されない。
Apiiro Claude Codeの調査が数えた範囲
Apiiroが見つけた公開コピーは104,185件。調べたリポジトリは103,617件にのぼる。認証情報が入っていたファイルは1,122件で、そこに1,379件の異なる秘密があった。
中身はプロバイダー形式のキーが636件、公開ホスト向けのパスワードやトークンが743件。多いのはデータベースのパスワードで379件だ。Supabaseのサービスロールキーも122件あり、SSHの資格情報43件の一部はsshpassのコマンドにrootのログイン情報として書かれていた。
対象を共有設定やエージェントの会話ログ、git履歴まで広げると、異なる秘密は2,539件になる。これは1,994の公開リポジトリ、63組織にまたがる。2,539は漏れたファイルの数ではない。秘密の種類を数えた数字だ。過去のコミットには734件が残り、フォークは74リポジトリの認証情報を211のコピーへ複製していた。
settings.local.jsonの除外設定はコピーに付かない
Claude Codeはリポジトリ内でこのファイルを作ると、開発者のグローバルなgit除外リストに加える。手元では追跡されない。問題は、その保護がプロジェクトと一緒に移動しないことだ。別のメンバーがcloneし、客先の検証用にforkし、設定を共有用のファイルへ移すと、同じ中身が追跡対象になる。日本の受託開発でよくある「客先リポジトリをforkして検証環境を作る」流れでは、この境目が意識されにくい。
Claude Code credentialsを拾えないスキャナ
Gitleaksは564ファイル、TruffleHogは643ファイルを検出した。どちらも拾えなかったファイルが215件ある。PGPASSWORD=、sshpass -p、mysql -p の形で書かれたパスワードには、プロバイダーを判別できる接頭辞がない。スキャナは鍵の形を覚えており、この書き方には反応しない。
Claude Code credentialsの回収は順番が大事
先に回すべきなのは削除ではなく失効だ。鍵を無効にすれば、履歴に残った文字列は使えなくなる。次にファイルを追跡から外し、リポジトリ内の除外設定を足す。過去のコミット、共有設定、会話ログを確認し、最後にリテラルの秘密を環境変数へ移す。値は1Passwordやクラウドのシークレットマネージャーに置き、CIではGitHub ActionsのSecretsから読む。日本のチームで環境変数のファイルを配って済ませているなら、同じ手順を当てはめたい。
「次から聞かない」は資格情報の保存を決めるボタン
UIの好みに見える設定が、実際には認証情報の保存先を決めている。エージェントを提供する側にとって、許可を永続化する機能は利便性の話ではなく、秘密情報をどこに置くかの設計判断だ。使う側は、許可したコマンドを棚卸しし、平文で残ると困るものは最初から通さない。では、自分のリポジトリは大丈夫か? 一度確認する価値がある。






