Claude Code で Bash コマンドの実行確認に「Yes, and don’t ask again」と答えると、そのコマンドが引数ごと allow ルールとして .claude/settings.local.json に保存されます。psql --password=… のようにパスワードを引数に書いたコマンドを承認すれば、パスワードもそのままファイルに残ります。このファイルが GitHub にコミットされ、秘密が公開リポジトリに残っている例が大量に見つかった——という Apiiro の調査が 2026年11月に報じられました。

HOW IT LEAKS漏れるまでの流れ

承認したコマンドが、秘密ごと allow ルールになる

  1. 「Yes, and don't ask again」

    Bash の実行確認でこれを選ぶと、そのコマンドが allow ルールとして .claude/settings.local.json に保存される

  2. 引数の秘密もそのまま残る

    psql --password=… や トークン付きの curl を承認すると、パスワードやキーが平文でルールに入る

  3. 除外が効かない経路でコミット

    自動の除外は“その端末の global excludes”だけ。手で作ったファイル・別の端末やCI・git add -f ではリポジトリに入りうる

  4. 公開リポジトリと履歴に残る

    ファイルを消しても Git の履歴には残る。公開済みなら鍵のローテーションが先

出典: Claude Code 公式ドキュメント(settings / permissions)と Apiiro の調査の報道(2026-11-07 確認)

30秒でわかる(2026-11-07)

  • ・時系列:公表日は 2026-11-05〜06(Apiiro の調査の報道)。仕組み自体は公式ドキュメントどおりの挙動で、それ以前から公式リポジトリに同種の報告(Issue #13106)がある
  • ・何が起きる:承認したコマンドがパスワードやキーを含んだまま平文で保存され、コミットされると公開リポジトリとGit 履歴に残る
  • ・まず確認:git log --all --oneline -- .claude/settings.local.json で履歴に入っていないか(下の確認手順へ)
  • ・対処:見つかった秘密は先にローテーション→ git rm --cached → プロジェクトの .gitignore に追加

まずやること(立場別)

  • Claude Code を使っている個人:自分のリポジトリで下の確認②(履歴に入っていないか)を実行する。出たら、その中のパスワード・キーをローテーションしてから追跡を外す。
  • チーム・組織の管理者:組織内の全リポジトリで .claude/settings.local.json の追跡と履歴をシークレットスキャンで洗い、テンプレートの .gitignore に1行足す。共有の .claude/settings.json に秘密入りのルールが無いかも見る。
  • 公開 OSS のメンテナ:フォーク元・ミラーにも残るため、該当があれば消す前にローテーション。必要なら利用者に告知する。

土台の考え方は サプライチェーン攻撃とは|手口・防御ツール比較・npm 12の新機構まで実践解説、Claude Code 全体の攻撃面は Claude Code セキュリティ|サンドボックスの守備範囲と公開アドバイザリで見る攻撃面・確認コマンド、秘密の混入を機械で止める方法は シークレットスキャンの入れ方 を参照してください。

何が起きたか——時系列と、数字の読み方

報道によれば、Apiiro は公開 GitHub 上の Claude Code の設定ファイルを大規模に調べ、秘密情報を含むものを数えました。見出しで広まった「1,994 リポジトリで 2,539 件の秘密」は、settings.local.json だけの数ではない点に注意が必要です。報道されている内訳は次のとおりです。

何を数えたか 報道された数
調べた settings.local.json のコピー 104,185 件(103,617 リポジトリ)
そのうち秘密を含んでいたもの 1,122 件(約 1.1%)
共有の settings.json で秘密を含んでいたもの 298 件(76,011 件中)
全体(Git 履歴・共有設定・エージェントの会話記録なども含む) 2,539 件の秘密 / 1,994 リポジトリ

見つかった秘密には、データベースの認証情報、SSH ログイン、クラウドのキーなどが含まれていたと報じられています。一方で、Apiiro は資格情報が有効かどうかを検証しておらず、悪用の有無も示されていない、とされています。割合だけ見れば「約 1.1%」ですが、母数が 10 万件規模なので、公開されている秘密の絶対数は小さくありません。

時系列で見ると、これは突然見つかった欠陥ではありません。公式リポジトリには「.claude/settings.local.json に機微なトークンが保存され、既定で git から除外されない」という報告(anthropics/claude-code Issue #13106)があり、挙動は以前から知られていました。今回の調査は、それが公開リポジトリでどれだけ起きているかを数で示したものです。

なぜ漏れるのか——「Don’t ask again」と settings.local.json の仕組み

Claude Code の公式ドキュメントは、仕組みをこう説明しています。Bash コマンドの許可を求められて「Yes, and don’t ask again」を選ぶと、その承認は allow ルールとして .claude/settings.local.json に保存され、git リポジトリならリポジトリのルートに置かれて、以後は同じコマンドを確認なしで実行できるようになります。ルールは承認したコマンドの文字列から作られるので、引数に書いたパスワードやトークンもそのまま入ります。

settings.local.json は「この端末・このプロジェクトだけの個人用設定」という位置づけで、コミットしない前提のファイルです。公式ドキュメントによれば、Claude Code がこのファイルを初めて書くとき、まだ除外されていなければ **/.claude/settings.local.json をその端末の global git excludes に追加します。ここに抜け道があります。

ASSUMED vs ACTUAL守られている“つもり”と抜け道

自動の除外が効く範囲と、効かない経路

Claude Code が用意している守り

  • 初回作成時に global excludes へ自動追加
  • **/.claude/settings.local.json を全リポで除外
  • 個人用ファイル=コミットしない前提
  • CLI はローカルファイルにだけ書く

それでも入る経路

  • 手で作ったファイルは自動除外されない
  • 除外は端末ごと(別PC・コンテナ・CIは別)
  • git add -f/リポジトリを丸ごとコピー
  • 共有の settings.json に秘密入りルールを書く
出典: Claude Code 公式 settings ドキュメントの記述。右列は想定される経路の整理(2026-11-07)
  • 手で作ったファイル:公式ドキュメント自身が「手で作った場合は自分で .gitignore に追加して」と書いています。自動の除外は Claude Code が書いたときだけです。
  • 端末ごとの設定:global excludes はその端末の git 設定です。別の PC、使い捨てのコンテナ、CI のジョブなど、その設定が無い環境からコミットすれば除外は効きません。
  • 強制追加や丸ごとコピー:git add -f や、.claude/ ごと別のリポジトリにコピーする運用でも入ります。
  • 共有の settings.json:チームで共有する .claude/settings.json は意図してコミットするファイルです。ここに秘密入りの allow ルールを書けば、除外の仕組みとは関係なく公開されます(報道の 298 件はこちら)。

つまり「Claude Code が除外してくれるから大丈夫」は、その端末で、Claude Code が作ったファイルについてだけ成り立つ前提です。リポジトリと一緒に動く .gitignore に書いていなければ、どこかで漏れる余地が残ります。

影響を受ける条件

影響を受けるのは、次の条件が重なった場合です。

  • 引数にパスワード・API キー・トークンなどを書いた Bash コマンドを、「Yes, and don’t ask again」で承認した
  • その .claude/settings.local.json(または秘密入りのルールを書いた共有の .claude/settings.json)が、リポジトリにコミットされた
  • そのリポジトリが公開されている、または第三者がアクセスできる

非公開リポジトリでも、アクセスできる人の範囲やフォーク・ミラーの扱いによっては同じ問題になります。また一度でもコミットされていれば、今のファイルから消していても履歴には残っている点が重要です。

対策——ローテーションが先、除外はその後

WHAT TO DO対処の順番

ローテ → 追跡を外す → .gitignore → 秘密をコマンドに書かない

  1. 1

    見つかった秘密をローテーション

    公開リポジトリや履歴に入ったものは漏れた前提で、パスワード・キーを失効して再発行する。消すより先

  2. 2

    追跡を外す

    git rm --cached .claude/settings.local.json でリポジトリから外す(手元のファイルは残る)

  3. 3

    プロジェクトの .gitignore に足す

    端末ごとの除外に頼らず、リポジトリと一緒に動く .gitignore で止める

  4. 4

    秘密をコマンド引数に書かない

    環境変数やシークレットマネージャ経由にし、承認ルールにパスワードが入らない形にする。シークレットスキャンも回す

出典: Claude Code 公式ドキュメントと報道された推奨対策の整理(2026-11-07)

順番が大切です。ファイルを消すより先に、見つかった秘密を失効・再発行(ローテーション)します。公開リポジトリに一度でも入ったなら、取得された前提で扱うべきだからです。そのうえで次を行います。

# リポジトリから追跡を外す(手元のファイルは残る)
git rm --cached .claude/settings.local.json

# リポジトリと一緒に動く .gitignore に明示する
echo ".claude/settings.local.json" >> .gitignore
git add .gitignore
git commit -m "Stop tracking Claude Code local settings"

履歴から消す(git filter-repo などで書き換える)ことは補助的な手段です。フォークやクローン、キャッシュに残った分は消せないので、ローテーションの代わりにはなりません。

再発防止は「秘密をコマンド引数に書かない」ことが根本です。パスワードは環境変数やシークレットマネージャから渡し、承認ルールにはパスワードが入らない形にします。すでに保存された allow ルールは定期的に見直し、秘密を含むものは削除してください。加えて、コミット前・プッシュ時に秘密を止めるシークレットスキャン(gitleaks や Betterleaks)や、GitHub のプッシュ保護を入れておくと、同じ種類の事故を機械で止められます。

自分のリポジトリを確認する

ここからは読み取りだけの確認です。いずれも陽性(秘密入りのファイルをコミットしてから削除したダミー)と陰性(.gitignore 済みのダミー)の両方で動かし、拾うべきものを拾い、無いときは何も出ないことを確かめています。. は自分のリポジトリのルートに読み替えてください。

# 最新の状態に揃えてから
git fetch --all --prune

# ① 今、追跡されていないか(何か出たら追跡中)
git ls-files -- '.claude/settings.local.json' '**/.claude/settings.local.json'

# ② 過去に一度でもコミットされていないか(出たら履歴に残っている)
git log --all --oneline -- '.claude/settings.local.json' '**/.claude/settings.local.json'

# ③ 手元の設定ファイルに秘密らしき引数が無いか
find . -path '*/.claude/settings*.json' -not -path '*/node_modules/*' \
  -exec grep -nHE -- '--password[= ]|PGPASSWORD=|AKIA[0-9A-Z]{16}|sk-[A-Za-z0-9_-]{20,}|ghp_[A-Za-z0-9]{36}' {} +

# ④ 履歴の中身に秘密が入っていないか
git log --all -p -- '.claude/settings.local.json' '.claude/settings.json' \
  | grep -nE -- '^\+.*(--password[= ]|PGPASSWORD=|AKIA[0-9A-Z]{16}|sk-[A-Za-z0-9_-]{20,}|ghp_[A-Za-z0-9]{36})'

# ⑤ この端末で除外されているか(何も出なければ除外されていない)
git check-ignore -v .claude/settings.local.json

②や④で何か出たら、内容を確かめて該当する秘密をローテーションします。ただし、この結果だけでは安全とは言えません。パターンは代表的な形だけを拾うもので、独自形式のトークンや、コマンドに直接書かれた別の種類の秘密は漏れる可能性があります。網羅的に確かめるなら、gitleaks などのシークレットスキャナでリポジトリ全体と履歴を走査してください。⑤で除外されていても、それはこの端末だけの話です。リポジトリの .gitignore に入っているかも合わせて確認しましょう。

参照ソース