AI コーディングツールに API キーや秘密情報を読ませないための設定:Claude Code・Codex・Gemini CLI 共通の対策
.env や認証情報ファイルを Claude Code、Codex、Gemini CLI に読ませないための具体的な設定(permissions の deny、サンドボックス、除外設定)と、読ませてしまった場合の対処、そもそも秘密情報をリポジトリに置かない構成を解説します。
目次
コーディングエージェントは、指示を実行するために必要だと判断すれば .env や config/secrets.yml を読みます。読んだ内容は API に送信され、ログや履歴に残ります。「.gitignore に入れているから大丈夫」は誤りで、エージェントの読み取りと Git の管理対象は別の話です。
この記事では、Claude Code・Codex・Gemini CLI それぞれで秘密情報の読み取りを防ぐ設定と、ツールに依存しない根本対策をまとめます。
KEY POINT
この記事で分かること
- 3 ツールそれぞれで
.envなどの読み取りを禁止する設定 - MCP サーバー・hooks・CI での漏えい経路と対策
- 秘密情報をリポジトリに置かない構成と、読ませてしまった後の対処
何が漏れるのか
| 経路 | 内容 |
|---|---|
| ファイル読み取り | .env、*.pem、credentials.json、~/.aws/credentials など |
| コマンド出力 | env、printenv、cat ~/.ssh/id_rsa、docker inspect の出力 |
| Git 履歴 | 過去にコミットされた秘密情報が git log -p で表示される |
| MCP サーバー | サーバーに渡したトークン、サーバーが返す内容 |
| コンテキストファイル | CLAUDE.md などに URL やパスワードを書いてしまう |
Claude Code:permissions の deny で禁止する
.claude/settings.json の deny は allow より常に優先され、個人の設定で上書きできません。チームで共有する設定に入れておきます。
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./**/*.pem)",
"Read(./**/*.key)",
"Read(./secrets/**)",
"Read(~/.aws/**)",
"Read(~/.ssh/**)",
"Bash(env)",
"Bash(printenv:*)",
"Bash(cat ~/.aws:*)",
"Bash(cat ~/.ssh:*)"
]
}
}
Bash の deny はコマンド文字列の前方一致なので、書き方を変えられると回避されます。ファイルの Read を禁止する方が確実です。permissions の書き方は settings.json で permissions を設計する を参照してください。
さらに hooks の PreToolUse で、読み取り対象のパスを検査してブロックする方法もあります。
#!/usr/bin/env bash
# .claude/hooks/guard-secrets.sh
file=$(jq -r '.tool_input.file_path // empty')
case "$file" in
*.env|*.env.*|*.pem|*.key|*/secrets/*|*/.aws/*|*/.ssh/*)
echo "秘密情報ファイルの読み取りは禁止されています: $file" >&2
exit 2 ;;
esac
exit 0
Codex:サンドボックスとファイル配置で守る
Codex のサンドボックスは書き込みとネットワークを制限しますが、ワークスペース内のファイル読み取りは制限しません。Codex にはファイル単位の読み取り禁止設定がないため、対策は次の 2 つです。
- 秘密情報をワークスペースの外に置く:
.envはリポジトリ外(例:~/.config/myapp/.env)に置き、アプリからはパスを指定して読む。 - AGENTS.md で明示する: 「
.envおよびsecrets/配下は読まないこと。必要な設定値は.env.exampleを参照すること」と書く。指示ベースなので確実ではないが、誤読の頻度は下がる。
read-only サンドボックスでも読み取りは可能なので、「読ませない」には配置での対策が必要です。サンドボックスの詳細は approval mode と sandbox 設定の違い を参照してください。
Gemini CLI:除外設定と GEMINI.md
Gemini CLI は .gitignore を尊重してファイル探索から除外する設定を持っています(settings.json の fileFiltering 関連。キー名はバージョンで確認してください)。加えて、.geminiignore ファイルで除外パターンを指定できます。
# .geminiignore
.env
.env.*
secrets/
*.pem
*.key
除外はファイル探索(検索・一覧)に効きますが、パスを直接指定した読み取りまで完全に防げるとは限りません。GEMINI.md にも読まないよう明記し、配置での対策と併用してください。
ツールの設定だけに頼らない
3 ツールとも、設定はあくまで「読みにくくする」対策です。確実なのは「読める場所に置かない」ことです。ツールの設定は保険として入れ、根本対策は配置で行ってください。
根本対策:秘密情報をリポジトリに置かない
.env.exampleを用意する: キー名だけを書いた雛形をコミットし、AI にはこちらを参照させる。- シークレットマネージャーを使う: 1Password CLI、AWS Secrets Manager、Doppler などから実行時に注入する。ファイルとして存在しなければ読まれない。
- direnv や環境変数:
.envrcはシェルが読むもので、エージェントがcatしない限り内容は渡らない。ただしenvコマンドの実行は禁止する。 - Git 履歴の掃除: 過去にコミットした秘密情報は
git log -pで読まれる。失効させたうえで、必要なら履歴から除去する。
MCP サーバー経由の漏えい
MCP サーバーに env で渡したトークンは、サーバープロセスには渡りますが、モデルには直接送られません。ただし、サーバーが返す内容(API のレスポンス)はモデルに送られます。「設定情報を取得する」ツールがトークンを含む結果を返す設計になっていないか確認してください。設定ファイルにトークンを直接書かないのは大前提です(MCP サーバーの追加方法)。
CI・クラウド実行での注意
GitHub Actions や Codex クラウドでは、Secrets や環境変数がコンテナに渡されます。エージェントが env を実行すればその内容を読めます。
- CI のワークフローでは、エージェントに渡す環境変数を必要最小限にする
- 本番の認証情報は CI のエージェントに渡さない。テスト用の値を使う
- クラウド実行の環境設定にも、本番の値を登録しない
読ませてしまった後の対処
送信済みのデータを取り消す方法はありません。対処は次の順です。
- 該当のキー・トークン・パスワードを失効させ、再発行する
- 失効までの間に不正利用がなかったか、サービス側のログを確認する
- 読まれた経路(どの設定が抜けていたか)を特定し、deny や配置を修正する
- Git 履歴に含まれていた場合は、失効に加えて履歴の除去を検討する
「今回は自分しか見ていないから」と失効を省略しないでください。データの保持期間中にどう扱われるかは、契約とプランに依存します(Claude Code のデータ利用)。
まとめ
.gitignoreはエージェントの読み取りを防がない。ツールごとの除外設定が必要- Claude Code は
denyのRead(...)、Codex は配置と AGENTS.md、Gemini CLI は.geminiignoreと GEMINI.md - 根本対策は「読める場所に置かない」。
.env.exampleとシークレットマネージャーを使う - 読ませてしまったら、失効・再発行が唯一の確実な対処
よくある質問
- .gitignore に入っているファイルは AI に読まれませんか?
- 読まれる可能性があります。.gitignore は Git の管理対象を決めるだけで、エージェントのファイル読み取りを制限するものではありません。ツールごとの除外設定が必要です。
- 誤って秘密情報を読ませてしまったらどうすればよいですか?
- そのキーやトークンを失効させて再発行してください。送信済みのデータを取り消すことはできないため、ローテーションが唯一の確実な対処です。
- MCP サーバー経由で秘密情報が漏れることはありますか?
- あります。MCP サーバーに渡した環境変数や、サーバーが返した内容はモデルに送られます。トークンは環境変数で渡し、サーバーの返す内容に秘密情報が含まれないか確認してください。
参考にした一次情報
この記事は公式ドキュメントを基に AI が下書きを作成し、運営者が内容を確認して公開しています。誤りを見つけた場合はお問い合わせからお知らせください。