secretを安全に配る — .env を1コマンドで配る dotvault を作りました

上原正吉(EarthLink Network Co., Ltd.)。Claude Codeを開発の主体に据え、20を超えるプロダクトを1人で同時に開発・運用しています。これは、その現場の実測記です。

secretを安全に配る — .env を1コマンドで配る dotvault を作りました

secretを安全に配る — .env を1コマンドで配る dotvault を作りました

結論

  • 何を作ったか: .env(環境変数=接続先やパスワードなどの設定をまとめて書くファイル)・.npmrc(パッケージ取得の認証情報)・kubeconfig(サーバー群への接続情報)・証明書などの秘密を、dotvault pull の1コマンドで各自のパソコンや Continuous Integration(変更を継続的に検証する自動化、CI)に配るサービスです。
  • なぜ作ったか: APIキーや .env は、GitHubに置けばセキュリティ違反、AIに渡せば「露出したからローテーションしろ」。配ることができないのに、配らなければいけない。この矛盾を、根本から解消するためです。

本文(読了 約9分)

この記事は、secret管理サービス dotvault の開発の経緯と、どんな機能があるか、どう開発したかを綴っていくシリーズの1本目です。まず「なぜ作ったか」から話します。

配ることができないのに、配らなければいけない

開発には、APIキーや .env(環境変数=接続先やパスワードなどの設定をまとめて書くファイル)の共有が必ず要ります。起動用の .env は開発者同士で共有する必要がありますし、CI(変更を継続的に検証する自動化)にも渡さないと動きません。

ところが、これをGitHub(コード共有サービス)に送ろうとすると、セキュリティ違反だから .gitignore にかけろと言われます。Claude Code などのAIサービスに渡そうとすると、APIキーが露出したからローテーション(キーの作り直し)しろと言われます。配ることができないのに、配らなければいけない。私はこの矛盾が問題だと感じていました。

結局、SlackやNotionなど別のサービスを使って配ることになり、非常に使いにくい。しかも .env は、誰かが変更してもGitに載らないので他の開発者に周知されません。「起動用の環境変数が足りなかった」「値が変わっていた」で開発が止まるトラブルも、しょっちゅうありました。これは自社だけの話ではありません。いろいろな現場で開発のコンサルティングをしているときにも、同じ問題に何度も当たりました。

だから「.envファイルを持たない」

そこで、根本的に考えを変えました。プロジェクトに .env ファイルを持たない、という選択です。

secretは全部 dotvault に登録します。利用者は npm のCLIコマンドで一度ログインしてしまえば、あとは dotvault pulldotvault run を使えます。プロジェクトごとに秘密キーを持つ必要がありません。

効いてくるのは、環境変数が掛け算式に増えるところです。プロジェクト数 × 環境(development・staging・production)で管理対象は膨らんでいきます。dotvault なら、何個のプロジェクトがあっても、何個の環境があっても、1つのログインで全員に同じsecretが同期されます。この「全員で同期される」が、私が欲しかったものです。

いま動いているものから話します

まず、完成した姿から見てください。

dotvault は、秘密を配るためのサービスです。Software as a Service(クラウド越しに使う業務ソフトウェア、SaaS)として、いま実際に動いています。

管理コンソールには、プロジェクト・サービストークン(機械用のAPIキー)・メンバー・監査ログが並びます。誰が、どの秘密に、いつ触れたのか。全部ここに残ります。

短いスクリプトで済ませず、サービスとして作りました。組織で使うには、秘密を配る手順だけでは足りないからです。誰に何を許すか。機械にどこまで渡すか。渡したあと、誰が触れたか。プランごとの利用上限をどう適用するか。この四つを仕組みとして管理します。外部決済や自動請求は、この仕組みには含めていません。

dotvault の管理コンソール。Projects・Service Tokens・Members・Audit Log が一覧で並ぶ(画面はデモデータ・匿名)

秘密を配るだけなのに、なぜここまで管理画面が要るのか。組織で使うには、保管だけでなく、権限と監査まで必要だからです。まず、これを作った理由から説明します。

なぜ保管だけでは足りないのか

守る対象と配布先を明確にします。秘密情報は、許可された人や実行環境へ必要な範囲だけ渡って初めて利用できます。

秘密が漏れる主な原因の一つは、置き場所が多すぎることです。チャット、メール、各自のパソコン、いくつものサーバー。写しが増えるほど、漏れる経路も増えます。個別に隠す手順を増やすより、置き場所をひとつに絞るほうが管理しやすくなります。

.env の値は、許可された人やサーバーへ配布して利用します。

dotvaultは、秘密情報を保管するだけでなく、許可された相手へ必要な範囲だけ配布します。

保管場所、権限、監査を一元管理する

そこで dotvault は、秘密の保管場所をコードリポジトリから分けました。

サーバー側の正本はdotvaultに置き、KMS(Key Management Service)で暗号化して保管します。dotvault pullは取得した値をローカルの.envファイルへ書き込むため、そのファイルをGitの追跡対象から外す運用は別に必要です。

そのうえで、環境ごとに分けます。development(開発)・検証環境(検証)・本番(本番)。それに、どの環境からも参照する _shared(共通)。同じ名前の設定でも、開発用と本番用は別物です。そこを混ぜません。

そして、キーひとつごとに、監査ログが残ります。誰が、いつ、どの値を、読んだのか。変えたのか。全部が記録されます。

値を1か所で直すと、利用者は次の dotvault pull またはプロセス起動時に新しい値を取得できます。ただし、すでに dotvault pull で取得した古い .env ファイルは自動では削除されず、起動済みプロセスの値も再起動まで変わりません。更新元を1か所に寄せ、再取得の手順を揃えることで、環境ごとの設定差を減らします。

dotvault の環境変数管理。development・staging・production・_shared に分かれ、キーごとに監査ログが付き、KMS で暗号化されている(画面はデモデータ・匿名)

管理コンソールでは、プロジェクト、サービストークン、メンバー、監査ログを管理します。これらを使って、配布先と配布範囲を制御します。

  • メンバーは、人に対して権限を割り当てます。この人はこのプロジェクトのこの環境まで、という線を引きます。
  • サービストークンは、CI やサーバーに対して権限を割り当てます。機械にも、必要な分だけを渡します。

dotvault のサービストークン管理。CI やサーバー(機械)に、プロジェクト単位・権限単位でトークンを発行し、失効(revoke)もできる。秘密の値は発行時に一度だけ表示(画面はデモデータ・匿名、メールアドレスは除去済み)

  • 監査ログは、渡したあとに「誰が触れたか」を残します。渡して終わり、にしません。

秘密の置き場所と権限を管理します。これで保管側の問題に対応しました。

受け取りは1コマンドで終わる

次に、配布方法を説明します。

どれだけ安全に保管しても、受け取るのが面倒なら、人はまた手でコピーを始めます。だから、受け取りは1コマンドで終わる必要があります。

dotvaultでは、.envファイルが必要な環境ではdotvault pullを使います。1コマンドで、その人に許された秘密を手元のパソコンやCIの宣言済みファイルへ書き出します。

dotvault pull の1コマンドで、許可された秘密情報を手元へ書き出す様子(画面は再構成・匿名、数値は実測)

dotvault pull で取得できるのは、許可された範囲だけです。開発の権限しか持っていない人が dotvault pull を実行しても、本番の秘密は降りてきません。取得値はローカルファイルへ書かれるため、リポジトリへ登録しない設定と運用が必要です。ファイルを作らない実行経路には、dotvault run -- <command> を使います。

dotvaultは、配り先、配る範囲、操作記録を仕組みとして管理します。秘密を共有しないのではなく、誰に何を渡したかを追跡できる配布経路へ置き換えました。

利用する人に、AWS アカウントは要りません。難しい設定も要りません。入った人は、pull するだけです。

新しく入った人は、権限が付いていれば自分で dotvault pull を実行でき、誰かが.envを送るのを待つ時間を減らせます。ファイルを必要としないCIでは、dotvault run -- <command>がキー値を子プロセスの環境変数へ渡し、.envファイルを生成・変更しないことを実装とテストで確認しました。キー値は子プロセスの終了後、そのプロセス環境には残りません。一方、dotvault pull で作成済みのファイルを自動削除することや、発行済みの秘密を自動失効することまでは確認していません。

人だけでなく、AIにも配れます。開発でAIサービスにsecretを参照させたい場面は増えていますが、チャットに貼れば露出です。dotvault は API と MCP(Model Context Protocol、AIツールが外部サービスへ安全に接続する規格)の連携を持っていて、AIサービスから秘密情報を安全に読み書きし、APIキーを取り出して他のサービスへアクセスする、という使い方ができます。

設計時には、DopplerとInfisical(既製の秘密情報管理サービス)を比較対象にしました。自分たちの組織構造、権限の境界、プラン別の利用制限へ合わせるため、自作を選びました。ここで扱うプランは利用上限と機能制限であり、Stripeなどの外部決済や自動請求ではありません。

5月末に仕様書から書き始め、6月の1か月で、組織、権限、監査ログ、プラン別の利用制限までを127コミットで組み上げました。Stripe連携、自動請求、セルフサービス課金は今回の初版(v1)の対象外としました。作る範囲は、「秘密なのに配らないといけない」という課題から決めました。

減らした手作業と人が担当する判断

dotvault導入前は、秘密情報を貼り付けて送り、パスワードを別便で伝え、受領を確認していました。dotvault pullを使うと、権限を確認したうえで必要な値を1コマンドで書き出せるため、この手作業を減らせます。

誰にどの秘密情報を許可するかは、人が判断します。判断後のファイル生成、子プロセスへの環境変数注入、操作記録はdotvaultが処理します。人は権限と利用範囲を決め、定型的な配布処理はサービスへ任せる分担です。


この dotvault についての記事は、開発の経緯・どんな機能があるか・どう実装したかを、順次シリーズとして公開していきます。 興味のある方は、ぜひ「いいね」と記事の購読をお願いいたします。

dotvault は secret を1コマンドで配るサービスとして提供しています。詳しくは https://dotvault.io をご覧ください。 そのほかの自社プロダクトは https://www.eln.ne.jp/products にまとめています。

筆者について

上原正吉。EarthLink Network Co., Ltd. でAI開発をしています。2025年からClaude Codeを開発の主体に据え、今は20を超えるプロダクトを1人で同時に開発・運用しています。この連載では、その現場で実際に起きたこと(うまくいったことも、失敗も)を、数字と一緒に書いていきます。

また、AIで業務や開発を組み替えたい会社・チーム向けに、AI活用のコンサルティングも受け付けています。ご相談は www.eln.ne.jp からどうぞ。


EarthLink Network は、会社の全業務を AI で回すために、必要になったものを自社で作っています。いま作っているプロダクトの一覧と概要は、こちらにまとめています。

EarthLink Network が自社でつくっている18のプロダクト

会社と各プロダクトの詳細は、公式サイト www.eln.ne.jp をご覧ください。

secretを安全に配る — .env を1コマンドで配る dotvault を作りました