Claude Codeの秘密情報対策|読み取り禁止(deny)設定で防げること・防げないこと【実測】ARTICLE
ARTICLEAI開発
Claude Code のようなエージェント型の AI コーディングツールは、指示に応じて自分でリポジトリのファイルを開き、コマンドを実行します。便利な反面、「不具合の原因を調べて」と頼んだだけで、.env や本番環境の設定ファイルに書かれたパスワードや API キーまで AI が読んでしまう、ということが起こりえます。
これを防ぐ仕組みが、Claude Code の読み取り禁止(permissions.deny)の設定です。本記事では、この設定をリポジトリに置いてチーム全員に効かせる方法と、K.S.Rogers で実際に6つの読み取り経路を試した結果をもとに、設定で防げること・防げないことを整理します。外注先に AI 利用のルールを約束してもらう発注側の視点は、システム開発を外注するときのAI利用ルールで扱っています。
この記事の要点
.claude/settings.jsonのpermissions.denyに読み取り禁止のルールを書いてコミットすると、そのリポジトリで Claude Code を使う全員に同じ制限がかかります。deny は個人の allow で上書きできません- 実測では、Read ツールと
catなどによる読み取りは止まりました。一方、ファイル名を指定しない検索、スクリプト経由の読み取り、環境変数に入れて使う経路は止まりませんでした- 設定は「うっかり読まれる」を大きく減らしますが、万能ではありません。本番の認証情報を手元に置かない運用と、人の行動ルールを組み合わせます
読み取り禁止(deny)の設定の基本
設定ファイルの置き場所
Claude Code の設定ファイルは、置く場所によって誰に効くかが変わります(出典:Claude Code Docs「Settings files and precedence」)。
| ファイル | 効く範囲 | Git |
|---|---|---|
.claude/settings.json(リポジトリ直下) | そのリポジトリを使う全員 | コミットする |
.claude/settings.local.json(リポジトリ直下) | 自分だけ、そのリポジトリだけ | コミットしない(.gitignore に入れる) |
~/.claude/settings.json | 自分だけ、すべてのプロジェクト | — |
読み取り禁止のルールは、.claude/settings.json に書いてコミットします。リポジトリを取得した人全員に、同じ制限が自動でかかります。メンバー1人1人に設定を頼む必要がなく、設定の変更も PR レビューを通して記録に残せます。
設定のサンプル
多くのリポジトリで共通して使える、読み取り禁止の例です。
{
"permissions": {
"deny": [
"Read(**/.env)",
"Read(**/.envrc)",
"Read(**/*.pem)",
"Read(**/*.key)",
"Read(**/*.p12)",
"Read(**/*.pfx)",
"Read(**/id_rsa)",
"Read(**/id_ed25519)",
"Read(**/*credentials*.json)",
"Read(**/service-account*.json)",
"Read(**/.htpasswd)",
"Read(**/*.tfvars)",
"Read(**/*.tfstate)",
"Read(**/*.tfstate.backup)",
"Read(~/.ssh/**)",
"Read(~/.aws/**)",
"Read(~/.config/gcloud/**)"
]
}
}
このうえで、プロジェクトごとの本番・ステージングの設定ファイル(config/ 配下の環境別の設定、database.yml など)を追加します。まだ存在しないファイルの種類(*.pem など)も、将来の混入に備えて先に入れておくと安心です。ホームディレクトリの ~/.ssh や ~/.aws はリポジトリの外ですが、AI から読める場所なので対象に含めます。
判断の基準は、ファイルの種類ではなく、書かれている値です。同じ設定ファイルでも、テンプレートやダミーの値しか入っていないものは対象外にし、本番の値が入るものを対象にします。
実測:6つの読み取り経路で何が止まったか
K.S.Rogers で、Claude Code v2.1.270 を使って検証しました(2026年9月)。秘密の値を入れたファイルを deny の対象にしたうえで、確認のダイアログの影響を除くため、試すコマンドはあえて allow に入れた状態で、6つの経路を試しています。
| # | 経路 | 結果 | 分かったこと |
|---|---|---|---|
| 1 | Read ツールでファイルを開く | ブロック | 拒否のメッセージが返り、中身は AI に届かない |
| 2 | Bash で cat <ファイル> | ブロック | allow に Bash(cat *) を書いた状態でも拒否された。deny は allow より優先される |
| 3 | Bash で grep -rn PASSWORD . | 止まらない(値が表示された) | ファイル名を指定せずに全体を検索する経路は、deny の対象外 |
| 4 | Bash で python3 -c "print(open('<ファイル>').read())" | 止まらない(値が表示された) | Claude Code が「ファイルを読むコマンド」と認識しない経路は、deny の対象外 |
| 5 | Bash で source <ファイル> して環境変数を使う | 止まらない(値を表示しないまま使えた) | 値を画面に出さずに、環境変数として使う経路は止められない |
| 6 | deny の対象外のファイルを読む | 通常どおり読める | 関係ないファイルまで止める、ということは起きなかった |
設定で担保できること
- Read の deny は、Bash の
cat・head・tail・sedや、リダイレクト(> ファイル< ファイル)にも効きます(上の表の1・2)。ファイルを開く代表的な方法は、1つのルールでまとめて止められます - deny は allow より優先されます。ルールは deny → ask → allow の順に評価されるため、メンバーが個人の設定に allow を書いても上書きできません(上の表の2)
- ブロックするときは確認のダイアログが出ません。「ダイアログが出たが、よく読まずに許可してしまった」という経路がなくなります
- deny はリポジトリを信頼(trust)する前から効きます。リポジトリを取得した直後から有効です
- Read の deny は、同じファイルへの Edit・Write も止めます。AI が秘密ファイルを書き換えたり、新しく作ったりすることも防げます
- シンボリックリンク経由の読み取りも止まります。リンクそのものとリンク先のどちらかが deny に一致すれば遮断されます
設定で担保できないこと
- ファイル名を指定しない読み取り(表の3)。
grep -r "password" .のような全体検索では、中身が出力されます - AI が書いたスクリプトなど、読み取りと認識されないコマンド(表の4)。Python や Node.js のスクリプトからファイルを開くと、中身が出力されます
- 値を「見ずに使う」こと(表の5)。
source .envで環境変数に入れてから DB や API に接続する、設定ファイルを指定して DB クライアントを起動する、といった方法では、AI は値を一度も表示しないまま認証情報を使えます - 人がファイルを開いてコピーし、チャットに貼り付けること
バージョンによる違い
上の挙動は、Claude Code のバージョンによって違います。K.S.Rogers の確認では、次のバージョンから動作が変わっていました。
| 挙動 | 必要なバージョン |
|---|---|
| Read の deny が Edit も止める | v2.1.208 以上 |
| Read の deny が Write も止める | v2.1.228 以上 |
入力リダイレクト(< ファイル)も検査する | v2.1.257 以上 |
| シンボリックリンク経由でディレクトリを指定した deny が効く | v2.1.268 以上 |
チームで運用するなら、必須は v2.1.208 以上、推奨は v2.1.268 以上のように下限を決め、メンバーの参画時と定期の棚卸しのときにバージョンを確認します。
落とし穴:親のディレクトリで起動すると、子の設定は読まれない
見落としやすいのが、どのディレクトリで Claude Code を起動したかです。プロジェクトの設定(.claude/settings.json)は、セッションを起動したディレクトリのものが読まれます(出典:前掲「Settings files and precedence」)。
たとえば、Docker Compose などで1つの親ディレクトリの下に複数のリポジトリを並べて開発している場合、親ディレクトリで Claude Code を起動すると、読まれるのは親の設定だけで、各リポジトリに置いた設定は読まれません。いちばんよく使う起動方法で、設定が効いていない、ということが起こります。
この場合は、親ディレクトリの設定に、配下のすべてのリポジトリ分の deny をまとめて入れておきます。
ほかのAIツールの読み取り制限
Claude Code 以外のツールにも、リポジトリ側で読み取りを制限する仕組みがあります(2026年9月時点)。
| ツール | 仕組み | 注意点 |
|---|---|---|
| Cursor | リポジトリ直下の .cursorignore(.gitignore と同じ書き方) | 公式に「ベストエフォートで、ブロックを保証しない」と明記。エージェントのターミナルや MCP のツールからの読み取りは止められない(出典:Cursor Docs「Ignore File」) |
| Gemini | Gemini CLI は .geminiignore、Gemini Code Assist は .aiexclude | Web やアプリで使う場合は対象外 |
| ChatGPT(Codex) | .codex/config.toml のファイルシステムの権限設定で、対象を deny にする | プロジェクトの設定は、そのプロジェクトを信頼(trust)したときだけ読み込まれる。初回に信頼する手順を案内する |
| GitHub Copilot | Content exclusion(リポジトリ・Organization の設定) | Copilot Business または Enterprise が必要。個人向けのプランでは使えない(出典:GitHub Docs「Content exclusion for GitHub Copilot」) |
| ChatGPT・Claude・Gemini の Web やアプリ、Microsoft 365 Copilot | —(ファイルを自分で読まない) | 人が貼り付ける使い方なので、行動ルールで対応する。デスクトップアプリで MCP などのローカル連携を有効にしている場合は、エージェント型として扱う |
どのツールも、Claude Code と同じ対象ファイルを指定しておくと、管理が楽になります。GitHub Copilot をチームで使うなら、読み取りを制限できない個人向けのプランは使わない、と決めておくのが安全です。
設定で防げない経路への対策
設定の限界を踏まえると、最も確実なのは、AI が読める場所に本番の認証情報を置かないことです。
- 手元の開発環境では、ダミーや開発用の値だけを使う ―― 本番やステージングの認証情報は、開発者の PC の
.envに置かない - 認証情報はシークレット管理のサービスに置く ―― クラウドのシークレット管理機能などを使い、必要なときに必要な権限の人だけが取り出す形にする
- 漏れても影響が小さい権限にする ―― 開発用のキーは権限を絞り、定期的に作り直す
deny をすり抜ける経路(全体検索・スクリプト経由・環境変数経由)を実行前に検出して人の確認を求める hooks の設定は、続編のClaude Codeに秘密情報を扱わせないhooksの設定例で解説しています。設定一式は GitHub で公開しています。
そのうえで、人の行動ルールを決めます。
- 認証情報を、AI のプロンプトやチャットに貼り付けない
- 本番の設定ファイルの中身を、AI に読み上げさせたり要約させたりしない
- AI が
grepでの全体検索や、スクリプトでのファイル読み取りをしようとしたら、対象を確認してから許可する - 誤って読ませてしまったときは、すぐに報告し、該当する認証情報を無効にして作り直す
チームとして約束すべきルールの全体像(使ってよいツール、秘密情報の区分、レビュー、棚卸し、事故のときの対応)は、システム開発を外注するときのAI利用ルールにまとめています。
K.S.Rogers の支援
K.S.Rogers では、自社の開発で AI コーディングツールの利用ルールと、リポジトリ側の読み取り禁止の設定を運用しています。開発チームへの AI ツールの導入、利用ルールと設定のひな形づくり、既存のリポジトリの秘密情報の棚卸しなどのご相談は、お問い合わせからどうぞ。
まとめ
- Claude Code の読み取り禁止は、
.claude/settings.jsonのpermissions.denyに書いてコミットします。全員に同じ制限がかかり、個人の allow では上書きできません - 実測では、Read ツールと
catなどは止まり、ファイル名を指定しない検索、スクリプト経由、環境変数に入れて使う経路は止まりませんでした - バージョンによって効く範囲が違うため、下限を決めて確認します。親のディレクトリで起動すると、子の設定は読まれない点にも注意します
- Cursor・Gemini・Codex・GitHub Copilot にも読み取りを制限する仕組みがありますが、それぞれ条件や限界があります
- 最も確実なのは、AI が読める場所に本番の認証情報を置かないことです。設定と行動ルールを組み合わせて運用します
よくある質問
Q.Claude Code に .env ファイルを読ませない方法はありますか?
A.あります。プロジェクトの .claude/settings.json の permissions.deny に "Read(**/.env)" のようなルールを書きます。この設定をリポジトリにコミットすると、そのリポジトリで Claude Code を使う全員に同じ制限がかかります。ただし、ファイル名を指定しない検索やスクリプト経由の読み取りは止められないため、行動ルールと併用します。
Q.permissions.deny を設定すれば、Bash の cat でも読めなくなりますか?
A.K.S.Rogers の検証(Claude Code v2.1.270)では、Read の deny に一致するファイルは、Bash の cat でも読み取りが拒否されました。allow に Bash(cat *) を書いた状態でも拒否され、deny が allow より優先されることを確認しています。一方、grep -rn での全体検索や、python3 で開いて出力する方法では値が表示されました。
Q.個人の設定で deny を上書きできますか?
A.できません。ルールは deny、ask、allow の順に評価され、deny に一致した操作は、個人の設定(~/.claude/settings.json や .claude/settings.local.json)に allow を書いても許可されません。
Q.Cursor や GitHub Copilot にも同じような設定はありますか?
A.あります。Cursor は .cursorignore、Gemini CLI は .geminiignore、Codex は .codex/config.toml のファイルシステムの権限設定、GitHub Copilot は Content exclusion で読み取りを制限できます。ただし Cursor は公式にベストエフォートと明記しており、GitHub Copilot の Content exclusion は Copilot Business または Enterprise が必要です。