「とりあえず全部許可」でClaude Codeを動かすと、.envの秘密がそのままAnthropicに渡る話
最初に範囲を区切らせてください。この記事は、GitHubのコミット偽装でもなく、エディタ拡張のサプライチェーン汚染でもありません。話すのは一点だけ、エージェントを動かしている最中に、.env の中身がツール出力に乗ってLLMプロバイダへ渡る経路です。コードを書く本人が一番油断している場所、と言い換えてもいいです。
私も最初は油断していました。Claude Codeを auto 寄りの権限で回して、ターミナルに流れる出力をろくに見ていませんでした。便利だったからです。便利なものは、たいてい後ろから刺さります。
「疑わしきも許可」が秘密を運ぶ仕組み
問題はファイルを直接開く話だけではありません。エージェントが実行したコマンドの出力が、そのまま会話コンテキストに取り込まれ、APIに送られます。これが見落とされがちな漏洩経路です。
具体的にはこうです。エージェントがデバッグのために printenv を打つ。あるいはアプリの起動ログに環境変数が出る。docker inspect の結果に認証情報が混ざる。そのテキストは全部、Claude Codeのコンテキストに入ります。そしてコンテキストはAnthropicのAPIに送られる。AWS_SECRET_ACCESS_KEY が、誰も「漏らそう」と思っていないのに、平文で旅に出るわけです。
OWASPは2026年に「Agentic Security Top 10」を公開しました。その A2(過剰な権限付与)と A4(データ漏洩)は、図解の中の脅威ではなく、auto や --dangerously-skip-permissions を押した瞬間に現実になります。GitGuardianの2026年レポートでは、公開GitHub上で2,900万件のシークレットが検出され、AI支援のコミットはベースラインの約2倍の頻度で秘密を漏らしていた、というデータも出ています。エージェントは秘密を漏らすのが上手いのです。悪意なく、勤勉に。

deny-rules で危険なパターンを明示的に止める
最初の防御線は .claude/settings.json の deny ルールです。deny は allow より常に優先されるので、危険なパターンをここで名指しで潰します。
{
"permissions": {
"allow": [
"Read",
"Bash(npm test *)",
"Edit(src/**/*.ts)"
],
"deny": [
"Read(.env)",
"Read(.env.*)",
"Edit(*.env*)",
"Write(*.env*)",
"Read(*.pem)",
"Read(*.key)",
"Read(credentials.json)",
"Bash(curl * | bash)"
]
}
}
設定の優先順位も押さえておくと効きます。管理ポリシー(/etc/claude-code/settings.json)はユーザーが上書きできないので、チームで強制したいルールはここに置きます。個人の油断を、組織の設定で先回りして潰すわけです。
deny-rules を過信してはいけない理由
ここで正直に書きます。deny ルールだけを信じるのは危険です。2026年に入って、Read の deny ルールが .env に対して実際には効いていない、という不具合が複数報告されました(anthropics/claude-code の Issue #24846 ほか)。deny に .env を入れて「守った」と思い込んだ状態が一番こわい。プロンプトも警告もなく、エージェントが拒否したはずのファイルを読んでいた、という報告です。
つまり deny-rules は「最初の壁」であって「最後の砦」ではありません。鍵をかけたつもりのドアが、たまにノブだけ回ると思っておいたほうがいい。だから層を重ねます。
多層で守る: 設定の外側に防御を置く
秘密を守る一番確実な方法は、そもそもディスク上に平文の秘密を置かないことです。実行時に取得して、ファイルに書かないなら、どんなツールにも読むものがありません。
私が実際にやっている順番はこうです。
.envをディスクから減らす。 本番に近い値はシークレットマネージャ(AWS Secrets Manager、HashiCorp Vault)に寄せ、実行時に注入する。ローカルの.envはダミー値に置き換える。漏れて困らない値なら、漏れても困りません。.gitignoreと除外設定を二重で張る。.env、*.pem、*.key、credentials.jsonをコミット対象から外し、エージェントの除外設定にも入れる。- Hooks で二重チェックする。 権限ルールに加えて、Hooks で危険なツール使用を検査し、Exit code 2 でブロックする。
asyncオプションを使えば、すべてのツール使用を外部ログに記録して後から監査できます。 - APIキーを最小権限+月間上限にする。 エージェント用のキーは、必要最小限の権限と利用上限を設定する。万一漏れても、被害の天井を低くしておく。
- ネットワークを断つ選択肢を持つ。 ローカルファイルだけを触るタスクなら、Dockerコンテナを
--network noneで起動して、外への送信経路ごと塞ぐ。出ていけないなら、漏れようがありません。

5つ全部を最初からやる必要はありません。私のおすすめは、まず 1 と 2 だけ今日やることです。.env をダミーに差し替えて .gitignore を確認する。これだけで、漏れて致命傷になる平文の秘密がローカルから消えます。残りは運用の本気度に合わせて足していけばいい。
エージェント実行時権限は「設定して終わり」ではない
セキュリティは設定ファイルに書いた瞬間に完成、ではありません。CVE情報やOWASPの更新、そして今回の deny-rules の不具合のように、前提が静かに変わります。auto の便利さは本物です。ただ、便利だからといって出力を見なくていいわけではありません。私が一番痛い目を見たのも、ターミナルを見ていなかった時でした。
権限を最小化し、deny で危険を名指しし、その外側に「平文の秘密を置かない」「出口を塞ぐ」を重ねる。エージェント実行時の秘密漏洩は、この多層でほぼ止まります。完璧な一枚の壁を探すより、そこそこの壁を何枚か立てるほうが現実的です。一枚くらい錆びていても、後ろにまだ何枚か残っています。ターミナルを見ていなかった私が、それでも今は安心してエージェントに仕事を任せられているのは、そのおかげです。
Claude Codeの権限モデル・サンドボックス・コスト設計をまとめて知りたい方は、書籍にしました。
この記事は役に立ちましたか?