Claude Code 時代の .env 管理 — 「平文で置かない」秘密情報の新しい守り方
@yousukezan 氏のポストが、AI 駆動開発における秘密情報管理の盲点を端的に指摘しています。
Claudeが社内に広がるほど、.envが危ない。Cowork時代に必要なのは「便利さ」より秘密情報の置き場所
引用元の Qiita 記事では、Claude Code や Cowork が「チャットで質問するだけのツール」から「ローカルファイルに直接アクセスする開発エージェント」へ進化したことで、従来の .gitignore だけでは守りきれない脅威が生まれていると論じています。本記事では、この問題の技術的背景と実践的な対策を掘り下げます。
何が変わったのか — 脅威モデルの転換
従来の開発ワークフローでは、.env ファイルの脅威モデルは明確でした。
| 脅威 | 対策 |
|---|---|
| Git リポジトリへの混入 | .gitignore に記載 |
| 本番環境への漏洩 | 環境変数やシークレットマネージャで注入 |
| 他人のマシンへの流出 | ローカルに置く前提なので問題なし |
ところが、Claude Code のような AI エージェントがローカルファイルを直接読み書きする時代になると、第三の脅威が加わります。
| 新しい脅威 | 内容 |
|---|---|
| AI エージェントによる読み取り | .env がツールの入力コンテキストに載る |
| 意図しないクラウド送信 | 読み取った内容が LLM の API リクエストに含まれる |
| 組織内の横展開 | Cowork で複数人が同じプロジェクトを触る際の露出 |
IPA「情報セキュリティ 10 大脅威 2026」でも「AI の利用をめぐるサイバーリスク」が初選出で 3 位にランクインしており、この脅威モデルの転換は業界全体の認識となりつつあります。
Claude Code は .env をどう扱うのか
自動読み込み問題
セキュリティ研究者 Dor Munis 氏の調査によると、Claude Code は .env、.env.local などのファイルを自動的に読み込み、API キーやトークンをメモリに展開していることが判明しています。プロキシ認証情報が意図せず読み込まれ、HTTP 407 エラーとプロキシ料金の異常な高騰として問題が顕在化しました。
settings.json の deny ルール — 期待と現実
Claude Code の公式ドキュメントでは、settings.json で .env へのアクセスを拒否する設定が案内されています。
| |
しかし、GitHub 上では deny ルールが実際には機能しないという複数の Issue が報告されています。The Register の報道でも、Claude Code が ignore ルールを無視してシークレットファイルを読み込む問題が取り上げられました。
つまり、settings.json の deny だけに頼るのは現時点では不十分です。
PreToolUse フックによる防御
より確実な防御策として、Claude Code の PreToolUse フックが挙げられます。これはツール呼び出しの前に実行されるシェルスクリプトで、ファイルパスをチェックして .env へのアクセスをブロックできます。
| |
ただし、これも Claude Code 内部の自動読み込みには対応できないため、根本的な解決にはなりません。
LLM Key Ring(lkr)— 「平文を置かない」アプローチ
元記事で注目されているのが、2026 年 3 月 1 日に公開された LLM Key Ring(lkr) です。Rust 製の macOS Keychain 管理 CLI で、設計思想は「そもそも平文ファイルにキーを置かない」というものです。
1Password CLI や Doppler のようなチーム向けソリューションは、外部アカウント、サブスクリプション、バックグラウンドデーモンが必要です。lkr は「個人の開発マシンで LLM キーを安全に管理する」という一点に絞り、macOS 組み込みの Keychain だけに依存する軽量設計を選んでいます。
.env ファイルの具体的な攻撃ベクトル
lkr の作者は、.env がなぜ危険かを 4 つの攻撃ベクトルで整理しています。
| 攻撃ベクトル | 説明 |
|---|---|
| バージョン管理への混入 | .gitignore に頼るヒューマンエラー。うっかりコミットは後を絶たない |
| シェル履歴への漏洩 | export OPENAI_API_KEY=sk-... が ~/.bash_history に残る |
| プロセス情報への露出 | ps コマンドで環境変数が見える |
| AI エージェントによる抽出 | プロンプトインジェクションでローカルコマンド実行 → 自動的にシークレット取得 |
4 番目が AI 時代に特有の脅威です。AI エージェントがコマンドを実行できる以上、シークレットの抽出は「スクリプト化可能」になっています。
インストール
| |
Rust 1.85 以上と macOS が必要です。現時点では Homebrew 配布やバイナリリリースは提供されていません。
コマンド詳細
lkr set — キーの保存
対話的プロンプトでキーを入力します。CLI 引数では受け付けないため、シェル履歴や ps への漏洩を防ぎます。
| |
Keychain 内では com.llm-key-ring というサービス名の下に provider:label 形式(例: openai:prod)で保存されます。
lkr exec — 推奨ワークフロー
最も安全な使い方です。キーを子プロセスの環境変数にのみ注入し、stdout やファイルには一切出力しません。
| |
プロバイダー名から環境変数名への変換は規約ベースです。
| Keychain ラベル | 注入される環境変数 |
|---|---|
openai:prod | OPENAI_API_KEY |
anthropic:main | ANTHROPIC_API_KEY |
admin キーは exec では注入されません。推論用(runtime)と課金管理用(admin)を明確に分離することで、権限の最小化を実現しています。
lkr get — 手動取得(フォールバック用)
環境変数が使えない場面での手動取得手段です。
| |
デフォルトの動作:
- 出力はマスク表示(末尾 4 文字のみ)
- クリップボードに自動コピー、30 秒後に自動消去
- 消去前に SHA-256 でクリップボード内容を照合し、ユーザーが別の内容をコピーしていた場合は消去をスキップ
オプション:
| オプション | 動作 | TTY ガード |
|---|---|---|
--show | 全文を表示 | 非対話環境ではブロック |
--plain | 生値をフォーマットなしで出力 | 非対話環境ではブロック |
--force-plain | TTY ガードを手動で上書き | ガード無効化(自己責任) |
lkr gen — 設定ファイル生成(最終手段)
テンプレートファイルから Keychain の値を解決して設定ファイルを生成します。平文ファイルが残るため、exec が使えない場合の最終手段と位置づけられています。
| |
動作の特徴:
- 出力ファイルのパーミッションは
0600(所有者のみ読み書き可能) .gitignoreに出力ファイルが含まれていない場合は警告を表示adminキーは明示的に除外
JSON テンプレートにも対応しています。MCP サーバーの設定などに便利です。
| |
| |
lkr list — 保存済みキーの一覧
デフォルトでは runtime キーのみ表示します。
キー分類: runtime vs admin
lkr のキー管理の中核にある設計です。
| |
| 分類 | 用途 | exec | gen | list(デフォルト) |
|---|---|---|---|---|
| runtime | 推論 API 呼び出し | 使用可 | 使用可 | 表示 |
| admin | 課金・使用量管理 | 使用不可 | 使用不可 | 非表示 |
推論用キーと管理用キーでは侵害時の影響が異なります。推論キーが漏洩した場合は不正利用による課金増加で済みますが、admin キーが漏洩した場合はアカウント全体の制御を奪われるリスクがあります。この分離により「全キーを一括注入」という安易な運用を防ぎます。
TTY ガード — AI エージェント対策の核心
lkr の最も特徴的な防御機構です。3 つのレイヤーで非対話的なキー抽出を阻止します。
レイヤー 1: 生値出力のブロック
| |
検出方法は IsTerminal(fd レベルの isatty チェック)を使用しています。CI や TERM 環境変数は容易に偽装できるため、意図的に無視しています。
レイヤー 2: クリップボードコピーのブロック
| |
lkr get key && pbpaste のような抽出チェーンを防ぎます。
レイヤー 3: exec ワークフローの優先
そもそもシークレットを出力しない exec を推奨ワークフローとすることで、出力ブロックに依存しない設計を実現しています。
既知の制限: IDE の統合ターミナル(pty)は isatty(true) を返すため、TTY ガードはバイパスされます。完全な防御ではなく、攻撃コストを上げる設計です。
メモリ保護 — Zeroizing
全てのシークレット値は String ではなく Zeroizing<String> で保持されます。スコープを抜けてドロップされる際に、メモリ上の値がゼロ埋めされてから解放されます。
ヒープダンプやコアファイルからのシークレット復元を防ぐ仕組みで、以下の全てのパスに適用されています:
- API キーの取得・保存時の一時バッファ
- 暗号化操作の中間値
execでの子プロセス環境変数の構築時
脅威モデルの範囲
| 対応する脅威 | 緩和策 | 関連コマンド |
|---|---|---|
.env の平文キー | Keychain に暗号化保存 | set / get |
| CLI 引数・履歴への漏洩 | 対話的プロンプト入力 | set |
| クリップボードの残留 | 30 秒自動消去(ハッシュ照合) | get |
| 非 TTY からのキー抽出 | TTY ガード | get |
| 権限の混在 | runtime / admin 分離 | exec / gen |
| メモリ上の残留 | Zeroizing<String> | 全コマンド |
| 対応しない脅威 | 理由 |
|---|---|
| root アクセス | ユーザーセッション内では Keychain にアクセス可能 |
gen 出力ファイルの読み取り | 同一権限のプロセスから読める |
| IDE 統合ターミナル | isatty(true) を返すため TTY ガードが効かない |
| 子プロセスのログ出力 | exec 後の環境変数を子プロセスがログに書く可能性 |
既存ツールとの比較
| ツール | 対象スコープ | 外部依存 | 運用コスト |
|---|---|---|---|
| 1Password CLI | チーム全体のシークレット | 外部アカウント、サブスクリプション | 高い |
| Doppler | チーム全体のシークレット | クラウドプラットフォーム | デーモン常駐、設定複雑 |
| aws-vault | AWS 認証情報のみ | AWS 固有 | 単一プロバイダー |
| lkr | 個人の LLM API キー | macOS Keychain(組み込み) | ゼロ(シングルバイナリ) |
lkr は「個人の開発マシンで LLM キーだけを守る」という明確なスコープで、チーム・クラウド基盤を不要にしています。
Doppler — チーム向けシークレット管理の本命
@ryoppippi 氏は、「.env はもう作るな」という @swarm_ai_cloud 氏のポストを引用し、端的にこう述べています。
doppler.com 使おうぜ
lkr が「個人の開発マシン」に特化しているのに対し、Doppler はチーム全体のシークレット管理を担うクラウドプラットフォームです。47,000以上の組織で利用され、月間300億回以上のシークレット読み取りを処理しています。
なぜ .env ファイルはスケールしないのか
Doppler の公式ブログ「Goodbye .env Files」では、.env ファイルの構造的な問題が3つ指摘されています。
1. パース処理の不統一
.env ファイルには標準仕様が存在しません。ライブラリごとにパース挙動が異なります。
| 記法 | Python dotenv | Node.js dotenv | bash |
|---|---|---|---|
KEY = value(スペースあり) | 動作する | 動作する | エラー |
\n(改行文字) | 自動変換 | そのまま | 挙動不定 |
| 複数行の値 | 対応 | 部分対応 | 非対応 |
Doppler はシークレットを JSON 形式で管理することで、この曖昧さを排除しています。JSON は仕様が厳密で、数値・文字列・改行の扱いに曖昧さがありません。
2. 共有の非効率性
チームに新しいメンバーが加わったとき、.env ファイルはどう渡されるでしょうか。現実には Slack の DM やメールで平文のキーが送られ、最小権限の原則が破られています。メンバーの退職時にキーをローテーションする運用も、.env ベースでは困難です。
3. 環境間の不整合
開発・ステージング・本番で異なる .env ファイルを手動管理するため、「本番だけ動かない」「ステージングで検証したキーと本番のキーが違う」といった問題が日常的に発生します。
Doppler の仕組み
Doppler の中核は プロジェクト × 環境(Config) のマトリクスでシークレットを管理する設計です。
プロジェクト: my-api
├── dev (開発環境)
├── stg (ステージング)
├── prd (本番)
└── ci (CI/CD)
各 Config に対して個別のシークレットセットを定義し、環境ごとの差異を一元管理します。
インストールと初期設定
| |
doppler setup を実行すると、カレントディレクトリに .doppler.yaml が生成され、以降のコマンドは自動的にこのプロジェクト・環境を参照します。
主要コマンド
doppler run — .env 不要のシークレット注入
Doppler の最も重要なコマンドです。lkr の exec と同様に、シークレットを子プロセスの環境変数として注入します。
| |
ファイルに平文を書き出すことなく、実行時にのみシークレットが環境変数に注入されます。プロセスが終了すればシークレットは消えます。
doppler secrets — シークレットの管理
| |
既存の .env ファイルからの移行は doppler secrets upload .env の一コマンドで完了します。
マウントモード — ファイルベースのアプリケーション向け
環境変数ではなくファイルからシークレットを読む必要があるアプリケーション向けに、マウントモードが用意されています。
| |
このとき生成されるファイルは Linux の名前付きパイプ(named pipe) です。通常のファイルのように読み取れますが、ディスク上に平文が残りません。Doppler プロセスが終了すると自動的にクリーンアップされます。
セキュリティ機能
| 機能 | 説明 |
|---|---|
| 監査ログ | 全てのシークレットアクセスを Git スタイルのログに記録 |
| ロールバック | 変更履歴から任意のバージョンに戻せる |
| RBAC | ロールベースのアクセス制御。環境ごとに権限を分離 |
| サービストークン | 本番環境用の制限付きトークン。特定の Config のみアクセス可能 |
| シークレット参照 | 共通シークレットを参照で管理し、重複を排除 |
| Webhook | シークレット変更時にリアルタイム通知 |
SOC 2 および ISO 認証を取得しており、年間稼働率 99.99% の実績があります。
料金プラン
| プラン | 料金 | 対象 |
|---|---|---|
| Free | 無料(5ユーザーまで) | 個人・小規模チーム |
| Team | $21/ユーザー/月 | 中規模チーム |
| Enterprise | 要問い合わせ | 大規模組織 |
特徴的なのは、マシン ID(サービストークン)には追加課金がない点です。CI/CD パイプラインや本番サーバーからのアクセスが増えても、人間のユーザー数のみで課金されます。
40以上のインテグレーション
Doppler は主要なクラウドプロバイダーや CI/CD ツールと直接連携できます。
| カテゴリ | 対応サービス |
|---|---|
| クラウド | AWS Secrets Manager, GCP Secret Manager, Azure Key Vault |
| CI/CD | GitHub Actions, CircleCI, GitLab CI |
| PaaS | Vercel, Heroku, Fly.io, Railway |
| コンテナ | Docker, Kubernetes |
| フレームワーク | Next.js, Django, Rails |
AWS Secrets Manager や GCP Secret Manager との連携では、Doppler をシークレットの「真実の源泉(Single Source of Truth)」として、クラウドプロバイダーのシークレットマネージャーに自動同期する構成が可能です。
lkr との使い分け
| 観点 | lkr | Doppler |
|---|---|---|
| 対象 | 個人の LLM API キー | チーム全体のシークレット |
| ストレージ | macOS Keychain(ローカル) | クラウド(Doppler サーバー) |
| OS 対応 | macOS のみ(現時点) | macOS / Linux / Windows |
| チーム共有 | 非対応 | RBAC・監査ログ付きで共有 |
| 環境管理 | なし(単一マシン) | dev / stg / prd を一元管理 |
| CI/CD 連携 | なし | 40以上のインテグレーション |
| 料金 | 無料(OSS) | 5ユーザーまで無料、以降有料 |
| AI エージェント対策 | TTY ガード、Zeroizing | run コマンドによる実行時注入 |
個人開発では lkr の軽量さが魅力です。macOS ユーザーであれば、外部アカウント不要で即座に導入できます。チーム開発では Doppler の環境管理・RBAC・監査ログが不可欠です。
両者は排他的ではなく、併用も可能です。たとえば、個人の LLM API キーは lkr で管理し、プロジェクト共有のシークレット(データベース接続情報、外部 API キー等)は Doppler で管理する運用が考えられます。
Doppler 以外の選択肢 — クラウドネイティブなシークレットマネージャ
本記事の本質的なメッセージは「Doppler を使え」ではなく、「平文の .env をローカルに置くな。何らかのシークレットマネージャから実行時に注入せよ」 という点です。既にクラウドインフラを運用しているなら、そのプロバイダのシークレットマネージャを使う方が自然な場合もあります。
クラウドプロバイダ別の比較
| 項目 | AWS Secrets Manager | GCP Secret Manager | Azure Key Vault | HashiCorp Vault | Doppler |
|---|---|---|---|---|---|
| 料金 | $0.40/シークレット/月 + $0.05/1万API呼び出し | 6バージョンまで無料、以降$0.06/バージョン/月 | $0.03/1万操作 | OSS版は無料、Enterprise版は有料 | 5ユーザーまで無料 |
| ローカル開発 | AWS CLI 経由で取得 | gcloud CLI 経由で取得 | az CLI 経由で取得 | vault CLI 経由で取得 | doppler run で注入 |
| 本番注入 | ECS/Lambda にネイティブ統合 | Cloud Run/GKE にネイティブ統合 | App Service/AKS にネイティブ統合 | Kubernetes/Nomad 統合 | Webhook/SDK で同期 |
| 自動ローテーション | RDS/Redshift/DocumentDB 対応 | なし(手動/Cloud Functions) | 証明書・キーの自動ローテーション | 動的シークレット生成 | Webhook で外部連携 |
| クラウド依存 | AWS に閉じる | GCP に閉じる | Azure に閉じる | クラウド非依存 | クラウド非依存 |
| 学習コスト | IAM ポリシーの理解が必要 | IAM の理解が必要 | RBAC の理解が必要 | 独自の概念が多い | 比較的シンプル |
AWS Secrets Manager — ECS/Fargate ユーザーの最適解
AWS をインフラとして使っている場合、AWS Secrets Manager は最も自然な選択肢です。特に ECS Fargate を使っているなら、タスク定義から直接シークレットを参照でき、.env ファイルもシークレット管理ツールも不要です。
ECS タスク定義での直接参照
| |
この構成では、シークレットは ECS が起動時にコンテナの環境変数として注入します。Dockerfile にも docker-compose.yml にも .env にも平文は残りません。
ローカル開発での取得
| |
シェルスクリプトでの一括注入
Doppler の doppler run に相当する仕組みは、シェルスクリプトで構築できます。
| |
| |
自動ローテーション
AWS Secrets Manager の強力な機能の1つが、RDS・Redshift・DocumentDB との自動ローテーションです。Lambda 関数を設定すると、指定した間隔でパスワードを自動的に更新し、アプリケーション側の変更なしに新しい認証情報が適用されます。
| |
Terraform での管理
インフラを Terraform で管理しているなら、シークレットの定義もコード化できます。
| |
どのツールを選ぶべきか — 判断フロー
既にクラウドプロバイダを使っている?
├── Yes → そのプロバイダのシークレットマネージャを使う
│ ├── AWS (ECS/Lambda) → AWS Secrets Manager
│ ├── GCP (Cloud Run/GKE) → GCP Secret Manager
│ └── Azure (App Service/AKS) → Azure Key Vault
│
├── マルチクラウド or クラウド非依存 → Doppler or HashiCorp Vault
│ ├── チーム規模が小さい → Doppler(セットアップが簡単)
│ └── 大規模 or 高度な要件 → HashiCorp Vault(動的シークレット)
│
└── 個人開発 + macOS → lkr(ゼロコスト、ゼロ依存)
重要なのは 「どのツールを選ぶか」ではなく「.env に平文を置かない」という原則です。どのシークレットマネージャを選んでも、AI エージェントが平文ファイルを読み取るリスクは排除できます。
ローカル開発の「鶏と卵」問題 — aws-vault で解決する
AWS Secrets Manager を選んだ場合、ローカル開発では「AWS の認証情報自体をどこに置くか」という問題が残ります。~/.aws/credentials に平文のアクセスキーを置けば、Claude Code がそれを読み取るリスクがあります。
.env に API キーを置きたくない
→ AWS Secrets Manager から取得しよう
→ AWS のアクセスキーはどこに置く?
→ ~/.aws/credentials に平文で置いている...
→ Claude Code はこれも読める
この「鶏と卵」問題を解決するのが aws-vault です。
aws-vault とは
aws-vault は、AWS の認証情報を OS のセキュアなキーストア(macOS Keychain、Windows Credential Manager、Linux Secret Service)に暗号化保存し、STS(Security Token Service)経由で一時的な認証情報を生成して提供するツールです。99designs 社が開発したオープンソースソフトウェアで、GitHub スター数は8,000以上の広く使われているツールです。
設計思想は「長期的な認証情報を安全に保管しながら、短命な一時認証を動的に生成する」というもので、lkr の exec コマンドと同じ発想です。
インストール
| |
初期セットアップ
| |
この時点で ~/.aws/credentials にはアクセスキーが書き込まれません。認証情報は macOS Keychain(または選択したバックエンド)に暗号化保存されます。
基本的な使い方
| |
aws-vault exec が生成する一時認証情報のデフォルト有効期限は 1時間 です。期限が切れれば自動的に無効になるため、万が一漏洩しても被害を限定できます。
~/.aws/config との連携
aws-vault は ~/.aws/config(認証情報ではなく設定ファイル)を読み取り、IAM ロールの切り替えや MFA を自動的に処理します。
| |
| |
セッション管理と MFA
aws-vault は一度 MFA 認証を通過すると、セッションをキャッシュします。同じプロファイルで再度 exec を実行しても、セッションが有効な間は MFA の再入力を求められません。
| 設定 | デフォルト | 説明 |
|---|---|---|
AWS_SESSION_TOKEN_TTL | 1時間 | GetSessionToken の有効期限 |
AWS_ASSUME_ROLE_TTL | 1時間 | AssumeRole の有効期限 |
AWS_MIN_TTL | 5分 | 残り時間がこれ以下なら再取得 |
キーローテーション
アクセスキーの定期的なローテーションも aws-vault から実行できます。
| |
IAM のベストプラクティスである90日ごとのキーローテーションを、コマンド一つで実行できます。
バックエンドの選択
| バックエンド | OS | 特徴 |
|---|---|---|
| macOS Keychain | macOS | デフォルト。OS 組み込みの暗号化ストレージ |
| Windows Credential Manager | Windows | OS 組み込み |
| Secret Service | Linux | GNOME Keyring / KWallet |
| Pass | Linux/macOS | GPG ベースのパスワードマネージャ |
| 暗号化ファイル | 全 OS | ファイルベースのフォールバック |
| |
AWS Secrets Manager + aws-vault の組み合わせ
aws-vault で AWS 認証情報を保護した上で、AWS Secrets Manager からアプリケーションのシークレットを取得する構成が、AWS 環境での最適解です。
| |
この構成では以下が全て平文ファイルから排除されます。
| 認証情報 | 保存場所 | 取得方法 |
|---|---|---|
| AWS アクセスキー | macOS Keychain | aws-vault が管理 |
| AWS 一時認証情報 | メモリ上のみ | STS が発行、1時間で失効 |
| DB パスワード等 | AWS Secrets Manager | AWS CLI で実行時に取得 |
| LLM API キー | macOS Keychain(lkr) | lkr exec で実行時に注入 |
~/.aws/credentials も .env もディスク上に存在しないため、Claude Code が読み取れる平文の認証情報はありません。
Claude Code の deny 設定との併用
念のため、Claude Code の設定で AWS 関連ファイルへのアクセスも拒否しておくと多層防御になります。
| |
aws-vault と lkr は併用すべきか、一本化すべきか
aws-vault と lkr は仕組みが似ています。どちらも「OS Keychain に暗号化保存し、exec で実行時に注入する」設計です。両方必要なのか、一本化できるのか、判断に迷う方も多いでしょう。
守る対象が異なる
似ているのは仕組みだけで、守る対象と機能は明確に異なります。
| aws-vault | lkr | |
|---|---|---|
| 守る対象 | AWS 認証情報 | LLM API キー |
| STS 一時認証 | あり(IAM ロール・MFA 対応) | なし |
| TTY ガード(AI エージェント対策) | なし | あり |
| キーの種類分離 | IAM ロールで分離 | runtime / admin で分離 |
| AssumeRole | 対応 | 非対応 |
| キーローテーション | rotate コマンドで対応 | 手動 |
aws-vault は AWS の STS・AssumeRole・MFA という AWS 固有のフローに深く統合されており、汎用的なキー管理ツールではありません。lkr は LLM API キーに特化しており、AWS の認証フローは扱えません。
3つの構成パターン
パターン A: aws-vault + lkr(併用)
| |
| メリット | デメリット |
|---|---|
| LLM キーはオフラインでも使える | ツールが2つ必要 |
| lkr の TTY ガードで AI エージェント対策 | チームメンバーの学習コストが増える |
| 各ツールが最適な対象に特化 |
パターン B: aws-vault のみ(LLM キーも AWS Secrets Manager に集約)
| |
| メリット | デメリット |
|---|---|
| ツールが1つで済む | ローカル開発でも毎回 AWS API 呼び出しが必要 |
| シークレットの管理場所が一元化 | オフラインで動かない |
| チームメンバーの学習コストが低い | AWS Secrets Manager の料金が発生 |
| IAM ポリシーでアクセス制御可能 | lkr の TTY ガードは使えない |
パターン C: lkr のみ(AWS を使わない場合)
AWS を使わないプロジェクトであれば、lkr だけで十分です。
| メリット | デメリット |
|---|---|
| 最軽量。外部依存ゼロ | AWS 認証情報の管理は別途必要 |
| macOS のみで完結 | チーム共有機能なし |
| TTY ガードで AI 対策 | Linux / Windows 未対応(現時点) |
判断基準
AWS(ECS/Fargate)を運用している?
├── Yes → aws-vault は必須
│ │
│ LLM API キーの管理をどうする?
│ ├── シンプルさ重視 → AWS Secrets Manager に集約(パターン B)
│ └── オフライン動作・AI対策重視 → lkr を併用(パターン A)
│
└── No → lkr のみ(パターン C)
ECS Fargate を運用しているなら、aws-vault は日常の AWS 操作で毎日使うため、導入コストは既に払っています。その上で LLM API キーをどこに置くかは、「毎回 AWS API を叩く煩わしさ」と「ツールを増やす煩わしさ」のどちらを許容するかで決まります。
ローカル開発で python manage.py runserver を起動するたびに AWS API を叩くのが気にならないなら パターン B(aws-vault 一本化) が最もシンプルです。オフラインでも作業したい、または Claude Code の TTY ガード対策を重視するなら パターン A(併用) が適しています。
アーキテクチャと今後の展開
ワークスペース構成は lkr-core(ビジネスロジック、KeyStore トレイト)と lkr-cli(CLI インタフェース)に分離されています。KeyStore トレイトがストレージバックエンドを抽象化しているため、テスト時は MockStore で差し替え可能です。
今後のロードマップ:
- Linux:
libsecret統合 - Windows: Credential Manager 統合
現時点では SaaS バックエンドやマルチマシン同期、チームコラボレーション機能は計画されていません。
Claude Code の apiKeyHelper との連携
Claude Code 自身にも、API キーを動的に取得する apiKeyHelper という仕組みがあります。settings.json にシェルスクリプトを指定すると、Claude Code は静的な環境変数の代わりにスクリプトの出力を API キーとして使用します。
| |
lkr と apiKeyHelper を組み合わせることで、Anthropic API キー自体も .env から排除できます。デフォルトでは 5 分ごとにキーが再取得され、CLAUDE_CODE_API_KEY_HELPER_TTL_MS 環境変数で TTL のカスタマイズも可能です。
なお、apiKeyHelper は Claude Code 自身が対話的に実行するため、--plain オプションが TTY ガードにブロックされることはありません。
多層防御の実践ガイド
1 つの対策に頼るのではなく、複数の層で防御する設計が重要です。
レイヤー 1: ファイルシステムから平文を排除
| |
レイヤー 2: Claude Code の設定で防御
| |
deny ルールの不具合が報告されていますが、修正された際に即座に有効になるよう設定しておくことに意味があります。
レイヤー 3: コンテナによる隔離
最も確実な方法は、Claude Code をコンテナ内で実行することです。
| |
シークレットはコンテナ起動時の環境変数として注入し、ファイルとしてはマウントしません。
レイヤー 4: チーム全体の設定配布
プロジェクトの .claude/settings.json をリポジトリにコミットすることで、チーム全員に同じ deny ルールを適用できます。
| |
エンジニアの役割の変化
元記事が指摘するように、AI ツールの導入が進むほど、エンジニアに求められるスキルが変化します。
| 従来のスキル | AI 時代に加わるスキル |
|---|---|
| コード設計 | AI がアクセスしてよい範囲の設計 |
| テスト設計 | 秘密情報フローの分離設計 |
| デプロイ設計 | 事故防止のための初期設定配布 |
| コードレビュー | AI が生成したコードのセキュリティ監査 |
技術選定の基準も「AI を導入できるか」から「AI を安全に常用できるか」へシフトしています。Cowork のように複数の AI エージェントが並行してコードベースに触る環境では、この設計能力がプロジェクトの安全性を左右します。
まとめ
- 脅威モデルの転換: AI エージェントがローカルファイルを直接読む時代になり、
.gitignoreだけでは.envを守れない - Claude Code の自動読み込み:
.envファイルが意図せず LLM のコンテキストに載るリスクが確認されている - deny ルールの限界:
settings.jsonの deny 設定には既知の不具合があり、単独では不十分 - LLM Key Ring (lkr): 「平文を置かない」「必要な瞬間だけ注入」という設計で、AI 時代のキー管理を実現
- 多層防御が必須: ファイル排除、設定、コンテナ隔離、チーム設定配布の 4 層で守る
- エンジニアの新しい役割: AI が触れる範囲の設計と秘密情報フローの分離が、コード記述と同等に重要になる
- 1 日で OSS を公開する文化: 問題を発見して即座にツール化する開発文化が、AI 時代のセキュリティを支える
参考
- @yousukezan 氏のポスト
- Claudeが社内に広がるほど、.envが危ない(Qiita)
- Stop Storing LLM API Keys in Plaintext .env Files — Introducing LLM Key Ring (DEV Community)
- Claude Code Automatically Loads .env Secrets, Without Telling You (Knostic)
- Claude Code settings - 公式ドキュメント
- Claude Code Security Best Practices (Backslash)
- Critical Security Bug: deny permissions in settings.json are not enforced (GitHub Issue #6699)
- Claude Code ignores ignore rules meant to block secrets (The Register)
- IPA 情報セキュリティ 10 大脅威 2026
- Claude Code Authentication - 公式ドキュメント
- @ryoppippi のポスト(Doppler 推奨)
- @swarm_ai_cloud のポスト(.env はもう作るな)
- Doppler - Centralized Secrets Management Platform
- Goodbye .env Files - Doppler Blog
- Doppler CLI Guide
- Why syncing .env files doesn’t scale - Doppler Blog
- AWS Secrets Manager Documentation
- Using AWS Secrets Manager with ECS
- GCP Secret Manager Documentation
- Azure Key Vault Documentation
- HashiCorp Vault Documentation
- aws-vault - GitHub
- aws-vault Usage Guide
- AWS Vault: Tutorial, best practices & limitations - Doppler