dotenvx で暗号化、1Password CLI で注入 — .env 平文ゼロのローカル開発環境を構築する
@higa_toshiki 氏のポストが、ローカル開発で .env の平文を排除する実践的な手法を紹介しています(いいね 217、ブックマーク 255)。
ローカルに.envの平文を置きたくないけど、ローカルで開発したいこともあるので、
- dotenvxで.envを暗号化
- 1 password cli で key を注入する を使ってます。 (元木さんの言うように「秘密情報の平文はクラウドに置こう」に則る形)
引用元の @swarm_ai_cloud 氏のポストでは、AI CLI の .env 読み込み防止機能への疑問が呈されています。
AI のCLIには.env読まない仕様があるって?そんなん信用できるか?AI CLIはバージョンが上がればバグが混入し弾くファイル設定していても普通に読んだりするし
Claude Code が .env ファイルを自動的に読み込むことが確認されている今、「deny ルールで防ぐ」だけでは不十分という指摘は的を射ています。本記事では、higa 氏が紹介する2つのツール — dotenvx と 1Password CLI — の仕組みと実践的なセットアップ手順を解説します。
2つのアプローチの組み合わせ
higa 氏のワークフローは、2つの異なるアプローチを組み合わせています。
| ツール | アプローチ | 何を守るか |
|---|---|---|
| dotenvx | .env ファイル自体を暗号化 | ファイルを読まれても平文が漏れない |
| 1Password CLI | クラウド Vault からランタイム注入 | そもそもファイルにシークレットを置かない |
[dotenvx のアプローチ]
.env(暗号化済み)→ dotenvx run → 復号してプロセスに注入
→ .env.keys(秘密鍵)が必要
→ Git にコミット可能
[1Password CLI のアプローチ]
1Password Vault(クラウド)→ op run → プロセスに注入
→ Touch ID / マスターパスワードで認証
→ ディスクに平文が一切残らない
両者は排他的ではなく、用途に応じて使い分けるのが現実的です。
dotenvx — .env ファイルを暗号化して Git にコミットする
dotenvx とは
dotenvx は、.env ファイルの暗号化に対応した次世代の dotenv ツールです。オリジナルの dotenv の作者である Mot 氏が開発しており、週間100万回以上インストールされています。
従来の dotenv は「.env を読み込んで環境変数にセットする」だけのツールでしたが、dotenvx は暗号化・複数環境対応・クロスプラットフォームサポートを追加しています。
暗号化の仕組み
dotenvx は ECIES(Elliptic Curve Integrated Encryption Scheme) を採用しています。
暗号化フロー:
1. 各シークレットを AES-256 で暗号化(個別の一時鍵を使用)
2. AES 鍵を Secp256k1 楕円曲線暗号の公開鍵で暗号化
3. 暗号化されたシークレットを .env に書き戻し
復号フロー:
1. .env.keys から DOTENV_PRIVATE_KEY を読み込み
2. 秘密鍵で AES 鍵を復号
3. AES 鍵でシークレットを復号
4. 環境変数に注入
| ファイル | 内容 | Git にコミット |
|---|---|---|
.env | 暗号化されたシークレット + DOTENV_PUBLIC_KEY | 可能(推奨) |
.env.keys | DOTENV_PRIVATE_KEY(復号鍵) | 絶対に不可 |
セットアップ
| |
暗号化の実行
| |
暗号化後の .env ファイル:
| |
.env.keys ファイル(Git に含めない):
| |
暗号化された .env を使って実行
| |
個別のシークレットを追加・更新
| |
AI エージェントに対する防御効果
dotenvx で暗号化された .env ファイルは、Claude Code が読み取っても暗号文しか見えません。
# Claude Code が .env を読んだ場合
DATABASE_URL="encrypted:BDzX9aK3..." ← 平文ではない
ただし、dotenvx run の子プロセスとして Claude Code を起動した場合は、復号されたシークレットが環境変数として渡されるため、この防御は無効です。
1Password CLI — クラウド Vault からランタイム注入
1Password CLI とは
1Password CLI(op) は、1Password の Vault に保存されたシークレットをコマンドラインから操作するツールです。op run コマンドで、シークレットを子プロセスの環境変数に注入できます。
lkr / aws-vault との違い
| 特徴 | 1Password CLI | lkr | aws-vault |
|---|---|---|---|
| 保存先 | 1Password クラウド | macOS Keychain | macOS Keychain |
| 対象 | 全種類のシークレット | LLM API キーのみ | AWS 認証のみ |
| チーム共有 | 可能(Vault 共有) | 不可(ローカルのみ) | 不可 |
| 認証 | Touch ID / マスターPW | Keychain | Keychain |
| 料金 | 有料($2.99/月〜) | 無料 | 無料 |
最大の違いは対象範囲です。lkr は LLM API キー、aws-vault は AWS 認証情報に特化していますが、1Password CLI は DATABASE_URL、SECRET_KEY、STRIPE_API_KEY などあらゆるシークレットを管理できます。
セットアップ
| |
シークレットの保存
1Password アプリまたは CLI でシークレットを Vault に保存します。
| |
op run — シークレット参照の解決
.env ファイルにシークレット参照(op:// URI)を記述し、op run で解決します。
| |
| |
このとき:
opが.env内のop://参照を検出- 1Password Vault からシークレットを取得(Touch ID で認証)
- 復号した値を環境変数として子プロセスに注入
- プロセス終了で環境変数は消える
- ディスクに平文は一切書き出されない
環境変数として直接設定する方法
| |
1Password Environment の活用
1Password の Environment 機能を使うと、.env ファイルすら不要になります。
| |
Environment は 1Password アプリの Developer セクションで作成・管理します。UNIX named pipe(FIFO)を使ってマウントされるため、ディスク上に平文ファイルが存在しません。
dotenvx + 1Password CLI の実践ワークフロー
higa 氏のワークフローを具体的に構築します。
使い分けの指針
| シナリオ | 推奨ツール | 理由 |
|---|---|---|
| チーム共有の開発環境変数 | dotenvx | 暗号化した .env を Git で共有できる |
| 個人の API キー・シークレット | 1Password CLI | チーム共有不要、クラウド保管で安全 |
| CI/CD 環境 | dotenvx | DOTENV_PRIVATE_KEY を CI の Secret に設定するだけ |
| ローカル開発 | 1Password CLI | Touch ID で認証、ディスクに平文なし |
パターン1: dotenvx でチーム共有 + 1Password で個人キー
| |
パターン2: 全て 1Password に統一
| |
Makefile での統合
| |
AI エージェントからの防御 — 限界と多層防御
dotenvx の防御効果
| 攻撃ベクトル | 防御効果 |
|---|---|
.env ファイルの直接読み取り | 有効 — 暗号文しか見えない |
.env.keys の読み取り | 無効 — 秘密鍵が取れれば復号可能 |
| 子プロセスの環境変数読み取り | 無効 — dotenvx run の子プロセスには平文が渡る |
1Password CLI の防御効果
| 攻撃ベクトル | 防御効果 |
|---|---|
| ファイルの読み取り | 有効 — ディスクに平文がない |
op run の子プロセスの環境変数 | 無効 — 注入された環境変数は読める |
/proc/<pid>/environ の読み取り | 無効 — 同一ユーザーのプロセスなら読める |
Michael Hannecke 氏の指摘にある通り、op run -- pytest のようにテストを実行すると、テストプロセスの環境変数に Vault のシークレットが注入されます。Claude Code が同じユーザーで動作していれば、/proc/<pid>/environ 経由でアクセス可能です。
根本的な限界
swarm_ai_cloud 氏の指摘の核心はここにあります。どのツールを使っても、復号されたシークレットが実行プロセスに渡る限り、同一プロセスまたは同一ユーザーの他プロセスからの読み取りは防げないということです。
多層防御の構成
完全な防御は不可能でも、複数の層を重ねてリスクを下げることは可能です。
レイヤー 1: ファイル暗号化(dotenvx)
→ .env を読まれても暗号文しか見えない
レイヤー 2: クラウド保管(1Password)
→ ディスクに平文ファイルが存在しない
レイヤー 3: deny ルール(Claude Code settings)
→ .env / .env.keys の読み取りをブロック
レイヤー 4: プロセス分離
→ Claude Code とシークレットを使うプロセスを分離
レイヤー 5: 別ユーザー実行(上級)
→ Claude Code を別ユーザーで実行し、/proc 経由のアクセスを遮断
他のツールとの比較
| ツール | 対象 | 保存先 | チーム共有 | 料金 |
|---|---|---|---|---|
| dotenvx | 全種類 | 暗号化ファイル(Git) | 可能 | 無料 |
| 1Password CLI | 全種類 | 1Password クラウド | 可能 | 有料 |
| lkr | LLM API キー | macOS Keychain | 不可 | 無料 |
| aws-vault | AWS 認証 | macOS Keychain | 不可 | 無料 |
| Doppler | 全種類 | Doppler クラウド | 可能 | 有料 |
| AWS Secrets Manager | 全種類 | AWS | 可能 | 従量課金 |
dotenvx と 1Password CLI の組み合わせは、「チーム共有の設定は dotenvx で Git 管理、個人のシークレットは 1Password で安全に保管」という使い分けができる点が強みです。
まとめ
- dotenvx は .env を暗号化する: ECIES + AES-256 で暗号化し、Git にコミット可能にする。Claude Code が
.envを読んでも暗号文しか見えない - 1Password CLI はクラウドからランタイム注入する:
op runでシークレットを子プロセスに注入し、ディスクに平文を一切残さない - 両者は補完的: dotenvx はチーム共有の設定管理に、1Password CLI は個人のシークレット管理に向いている
- lkr / aws-vault との違いは対象範囲: 1Password CLI は DB 接続情報や SaaS キーなど全種類のシークレットを扱える
- 根本的な限界は残る: 復号されたシークレットが環境変数に載る以上、同一プロセスからの読み取りは防げない
- 多層防御が現実解: ファイル暗号化 + クラウド保管 + deny ルール + プロセス分離を組み合わせる
- 「秘密情報の平文はクラウドに置こう」: higa 氏の実践は、ローカルに平文を置かない原則を具体化している
参考
- @higa_toshiki のポスト
- @swarm_ai_cloud のポスト
- dotenvx 公式サイト
- dotenvx - GitHub
- Encryption | dotenvx
- Load secrets into the environment | 1Password Developer
- Use secret references with 1Password CLI | 1Password Developer
- op run | 1Password CLI
- 暗号化に対応した次世代dotenvツールdotenvxを使う - Zenn
- Your Vault Protects Your Secrets — Until Claude Code Runs Your Tests - Medium
- Securing MCP servers with 1Password | 1Password Blog
- Claude Code Automatically Loads .env Secrets - Knostic
- Claude Code 時代の .env 管理(関連 Gist)
- lkr × LLM APIキーをmacOS Keychainで安全管理(関連 Gist)
- aws-vault × .env廃止でClaude Code時代のAWS認証管理(関連 Gist)