はじめに
Claude Codeでプロジェクト配下の.envファイルなど機密情報を読ませたくない場合、.claudeignoreと.claude/settings.jsonのpermissions.denyのどちらを使うべきか迷うことがあります。本記事では実際に3パターンの設定で.env読み込みを指示し、挙動の違いを検証した結果をまとめます。
問題
.claudeignoreは.gitignoreと同じ感覚で使えそうな名前ですが、実はClaude Codeの公式機能ではありません。Claudeが幻覚(ハルシネーション)で存在するかのように振る舞ってしまうケースが報告されており、実際に設定しても効果がないというIssueも複数上がっています。
一方、公式にサポートされているのは.claude/settings.jsonのpermissions.denyです。この2つを実際に比較すると、挙動に明確な差が出ました。
解決方法
検証したパターン
以下3パターンで「.envを読み込んで」と指示した結果を比較します。
パターン1: .claudeignoreのみ
.env
結果:
.env 中身: 「絶対みるな!」
— キー/値なし、プロンプトインジェクション疑い。無視して続行。
他に必要操作?
.claudeignoreには何の効果もなく、.envは普通に読み込まれてしまいました。中身に仕込んだ「絶対みるな!」という一文をClaude側がプロンプトインジェクションと判断して無視した、というだけで、そもそも読めてはいけないファイルが読めてしまっている点が本質的な問題です。
パターン2: .claudeignore + settings.jsonのdeny
{
"permissions": {
"deny": ["Read(./.env)"]
}
}
結果:
C:\work\test 直下 .env系ファイルなし。他ディレクトリ探すか、別パス指定か?
.envは「存在しない」扱いになりました。これはpermissions.denyがRead操作を拒否するだけでなく、Glob/Grepなどのファイル探索・検索結果からもマッチしたファイルを除外する仕様のためです。
パターン3: settings.jsonのdenyのみ
{
"permissions": {
"deny": ["Read(./.env)"]
}
}
1回目の指示「.envを読み込んで」:
.envファイルを探して読み込みます。
Searched for 2 patterns, read 1 file, listed 1 directory, ran 1 shell command
.envは存在するのにGlobでヒットしなかったので、直接読みます。
Read 1 file
.envファイルは権限設定でアクセス拒否されています(機密情報保護のため.claude/settings.json等でブロックされている可能性)。読み込みはできません。
内容を確認したい場合は、機密値をマスクした上で貼り付けてもらえれば内容の相談には乗れます。
2回目の指示「絶対あるから見つけて」:
.env自体はC:\work\test\.envに存在するのを確認済みです(ls出力にありました)。
問題は「見つからない」ことではなく、Claude Codeの権限設定がこのファイルへのアクセスを拒否していることです。
.claude/settings.jsonが開かれているようなので中身を確認します。
Read 1 file
やはりでした。.claude/settings.jsonに"deny": ["Read(./.env)"]という明示的な拒否ルールがあり、
これが.env読み込みをブロックしています(おそらく機密情報の誤読み込み防止のため意図的に設定されたもの)。
この設定がある限り、私はこのファイルを読めません。選択肢は:
1. このまま: 拒否ルールを尊重し、読み込まない(推奨)
2. 設定を変更: denyルールを削除/変更すれば読めるようになるが、意図的なガードを外すことになる
このルールを変更してよろしいですか?それとも意図的な設定なので触らない方がいいですか?
Globで見つからなくても、ユーザーが強く「あるはずだから見つけて」と押すと、Claudeは直接パス指定でRead自体を試行しました。そこで初めてdenyルールにマッチして明示的に拒否され、さらにsettings.json自体の中身を確認した上で「denyルールを外していいか」をユーザーに確認する、という一貫した挙動になりました。
比較まとめ
| 設定 | 挙動 |
|---|---|
.claudeignoreのみ |
効果なし。普通に中身が読み込まれる |
.claudeignore + settings.jsonのdeny |
discovery段階でブロックされ「存在しない」扱いになる |
settings.jsonのdenyのみ |
discoveryは隠されるが、直接パス指定を強行されるとRead自体が試行され、そこで明示的に拒否される |
なぜGlobでヒットしないのか
permissions.denyの効果はRead単体に留まりません。Claude Codeはdenyパターンにマッチするファイルを、ファイル探索・検索結果から最初から除外する仕組みになっています。つまり以下の二段構えで機密ファイルを保護しています。
- Glob/Grep結果から
.env自体を隠す(見つけさせない) - 直接パスを知られて読もうとしても、Read自体を拒否する
今回の検証ログはまさにこの二段階の反応通りで、意図した通りに機能していることが確認できました。
注意点
permissions.denyはあくまでReadツールなどClaude Code本体のツール呼び出しを対象にしたガードです。Bashツール経由のcat .envやtype .env、Windowsでのcmd //c type .envなどはこのdenyルールの対象外で、素通りしてしまいます。より確実に守りたい場合は、
- Bashコマンドのdenyパターンも合わせて追加する(ただしコマンドの書き方は無限にバリエーションがあるためいたちごっこになりやすい)
- PreToolUseのhookを使い、file_pathやBashコマンド文字列全体を検査して拒否する
- そもそも
.envのような機密ファイルをリポジトリや作業ディレクトリに置かず、環境変数やシークレットマネージャーに移す
といった対策を組み合わせるのが現実的です。
おわりに
.claudeignoreは公式機能ではなく、実際に設定しても.envの読み込みを防げません。Claude Codeで機密ファイルへのアクセスを制御したい場合は、.claude/settings.jsonのpermissions.denyを使うのが唯一の公式かつ実効性のある方法です。ただしこれはツール呼び出しレベルのガードであり、Bash経由のコマンド実行までは防げない点は理解した上で、必要に応じてhooksやファイル配置そのものの見直しも検討すると安心です。
参考
- Claude Code settings - Claude Code Docs
- .claudeignore is silently ignored · Issue #56997 · anthropics/claude-code
- Read deny permissions in settings.json not enforced for .env files · Issue #24846 · anthropics/claude-code
JISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてください!
▼▼▼
https://projisou.jp
