秘密の鍵の扱い

AIの道具は、読んだものを文脈としてモデルへ送り、書いたものをコミットし、走らせた命令の出力を記録に残す。鍵はこの流れのどれにも乗せない。漏れたら、消すより先に無効にする。

2026年11月時点の GitHub、OWASP、Claude Code の公式文書で書いています。鍵は、APIキー、アクセストークン、パスワード、秘密鍵、接続文字列を指します。

要点

  • 漏れる経路は、コミット、ログと出力、AIへ渡す文脈、設定ファイルの4つ。
  • 鍵はリポジトリの外に置き、AIの道具がその場所を読めないよう、拒否の設定とサンドボックスで止める。
  • 鍵の権限は用途ごとに最小にし、長く使う鍵より期限の短い資格情報を使う。
  • 漏れたら、無効化、差し替え、使われた跡の調査、履歴とログの掃除の順。履歴を書き換えても無効化の代わりにならない。
  • GitHub の secret scanning と push protection は最後の網で、置き場所の設計の代わりにならない。

漏れる経路

手元の鍵は、AIの道具を通じて、モデルの提供元と会話の記録、コミット、命令の出力、設定ファイルの4つへ流れ得る 開発の機械 .env 鍵の置き場所 AIの道具 読む、書く、命令を走らせる 出力を文脈に入れる 読む、cat する 1 AIへ渡す文脈 モデルの提供元へ送信。手元の会話の記録 2 コミット 直書き、.env の追加、試験用の値 3 ログと出力 デバッグの表示、env の出力、CIのログ 4 設定ファイル MCP や compose の設定への直書き
図1 AIの作業で鍵が漏れる4つの経路
経路起きる形止める所
AIへ渡す文脈不具合を調べるため .env や資格情報のファイルを読む。鍵の載ったログを貼る。読んだ中身は会話の一部になる読み取りの拒否、サンドボックス。鍵の載ったログを貼らない
コミット動作を確かめるため鍵を直書きし、そのまま残す。.env を加える。試験の値に本物の鍵を使う.gitignore、コミットの前の検出、push protection
ログと出力デバッグの表示、env の出力、誤りの報告に載った接続文字列。CIのログ鍵を表示しない。CIの値を1つずつ秘密に登録する
設定ファイルMCPの接続や compose の設定に鍵を直書きし、設定と一緒にコミットする環境変数の参照にする
  • Claude Code は、利用者の指示とモデルの出力のすべてを提供元へ送る。手元では会話の記録を ~/.claude/projects/ に平文で既定30日残す[1]。AIが読んだ鍵は、この2か所に入る。
  • GitHub Actions のログは登録した秘密の値を伏せるが、値を変換した形は伏せられる保証が無い。複数の値を1つの JSON などにまとめず、値ごとに秘密に登録する[2]。
  • CWE は、ソースへの直書きを CWE-798、ログへの書き出しを CWE-532 として扱う[3][4]。

置き場所

場面置き場所
本番クラウドの秘密の管理の仕組みか、実行時に注入する環境変数。リポジトリにも、イメージにも焼き込まない
CICIの秘密の機能。クラウドへは OpenID Connect で入り、長く使う鍵を置かない[2]
手元リポジトリの外か、無視の設定をしたファイル。AIの道具の読み取りを拒否する
設定ファイル値ではなく変数の参照を書く

.claude/settings.json 鍵のファイルを読ませない

{
  "permissions": {
    "deny": ["Read(./.env)", "Read(./.env.local)", "Read(./secrets/**)"]
  }
}

この拒否は Read の道具と cat .env のような読む命令の両方に効くが、ファイルを開くスクリプトは止めない。OSの水準で止めるには、拒否の規則を引き継ぐサンドボックスを併せて使う[5]。

.mcp.json 値ではなく参照を書く

{
  "mcpServers": {
    "tickets": {
      "type": "http",
      "url": "https://mcp.example.com/mcp",
      "headers": { "Authorization": "Bearer sk_live_9f3a..." }
      "headers": { "Authorization": "Bearer ${TICKETS_TOKEN}" }
    }
  }
}

Claude Code は .mcp.json の command、args、env、url、headers で ${VAR} を展開する[6]。プロジェクトの .mcp.json はコミットされて共有される前提のファイルなので、値を書かない。

権限を最小にする

鍵が漏れたときの被害は、その鍵でできることの範囲で決まる。OWASP は、鍵には役目に要る最小の権限だけを付け、技術者が全部の鍵に触れる形にしないよう求める[7]。

  • 用途ごとに別の鍵にする。AIの作業で使う鍵は、読み取りだけ、1つのリポジトリだけ、検証の環境だけ、のように絞る。
  • 期限の短い資格情報を使う。OWASP は、アプリケーションを再起動しても、ビルドを終えても、発行済みの資格情報は無効にならないと注意している[7]。
  • GitHub Actions の GITHUB_TOKEN は、要る権限だけを付け、要るジョブにだけ広げる[2]。
公表された事例 AWS-2025-015

AWS は2025年7月23日、Amazon Q Developer の VS Code 拡張の1.84.0に悪いコードが入っていたと公表した。ビルドの設定にあった GitHub のトークンが要る範囲より広く、それを使った者が公開のリポジトリにコードを入れ、自動で配布物に含まれた。AWS によれば、そのコードは構文の誤りで動かず、サービスや利用者の環境に影響しなかった。AWS は資格情報を無効にして差し替え、コードを除き、1.85.0を出した[8]。広すぎるトークン1つが、AIの道具の配布物に手を入れる道になった例である。

漏れたときの順

漏れた鍵は、無効化、差し替え、使われた跡の調査、履歴とログの掃除、再発を止める仕組み、の順に扱う 1 無効化 すぐ。最優先 2 差し替え 新しい鍵を配る 3 跡の調査 使われたかを見る 4 掃除 履歴とログ 5 再発の止め 置き場所と検出 4を先にしない 複製と fork とキャッシュに残る。消しても、鍵は生きたまま
図2 漏れた鍵を扱う順
  • GitHub は、機密のデータが秘密の値なら、最初に無効化か差し替えをするよう書く。履歴を書き換えて強制 push しても、複製、fork、キャッシュされた表示に残り得る[9]。
  • OWASP の手順も、漏れた鍵のすぐの無効化、新しい鍵の作成と配布、漏れた場所からの除去、鍵の発行と利用の記録による調査を並べる[7]。
  • AIとの会話で鍵を読ませたときも、漏れとして扱う。会話の記録に残り、提供元へ送られている[1]。

GitHub の検出の仕組み

仕組みすること限り
secret scanning全部のブランチの履歴、PRとディスカッションの本文とコメント、wiki を走査する。公開のリポジトリでは無料で自動。提携先の形式の鍵は提供元へ直接知らせる見つけるのは入った後。組織の非公開のリポジトリは GitHub Secret Protection が要る
push protection鍵を含む push を止める。利用者の側の保護は、公開のリポジトリへの push で既定で有効書き込み権限があれば理由を付けて越えられる。越えた記録は警告と監査ログに残る

出典は GitHub Docs[10][11]。手元のコミットの前で止めるなら、gitleaks や TruffleHog のような検出の道具を pre-commit に置く。OWASP も、コミットとPRの前の開発者の段階での検出を勧める[7]。

参照

  1. Data usage Anthropic
  2. Secure use reference GitHub Docs
  3. CWE-798 Use of Hard-coded Credentials MITRE
  4. CWE-532 Insertion of Sensitive Information into Log File MITRE
  5. Best practices for Claude Code Anthropic
  6. Connect Claude Code to tools via MCP Anthropic
  7. Secrets Management Cheat Sheet OWASP Cheat Sheet Series
  8. AWS-2025-015 Amazon Web Services、2025年7月23日
  9. Removing sensitive data from a repository GitHub Docs
  10. About secret scanning GitHub Docs
  11. About push protection GitHub Docs