上原正吉(EarthLink Network Co., Ltd.)。AI会社・AI社員による業務自動化と、人の逐次介入なしに24時間自動開発を回す仕組みを自社で実践しています。開発ノウハウと具体的な設定方法、運用して分かった改善点を公開しています。

この記事は、連載「dotvault の使い方 ── .env を手で配るのをやめ、CI・チーム・AI エージェントに 1 コマンドで配るまで」の第 8 回です。この連載が終わる時に、dotvault を誰でも無料で使える形で公開する予定です。
Claude Code に「この .env を使って動かして」と頼む時、.env の中身を会話に貼り付けるか、.env を読ませることになります。値は会話の記録に残り、Claude Code が動かすコマンドの出力にも出ます。dotvault に値を置いてあっても、Claude Code に dotvault login をさせるには、自分のメールアドレスとパスワードを渡すことになります。
「AI エージェントに secret を渡すには、値そのものか、自分の login を渡すしかない」と考えがちですが、渡すのは dotvault の service token 1 つで足ります。project を 1 つに絞った、値を読み書きするための token(Read/write)です。Claude Code はこの token だけで .env を dotvault に取り込み、pull で受け取ります。人のパスワードは渡しません。使わせなくする時は、console で token を取り消します(Revoke)。
この回では、token を 1 つ発行して Claude Code の設定ファイルに置き、Claude Code に取り込みから pull までを任せ、Revoke で token を取り消すところまでを確かめます。Claude Code は token 1 つだけで 3 つの key を取り込み、pull で 3 つを受け取りました。token を取り消した後に同じ pull を頼むと、AUTH_REQUIRED と終了コード 3 で止まりました。
.claude/settings.local.json の env に DOTVAULT_TOKEN として置きます。 ファイルには token が平文で書かれるので、.gitignore で外します。dotvault init → import → pull → run → whoami を Claude Code が自分で実行し、3 つの key を取り込んで、pull で 3 つを受け取りました。dotvault scan . は、設定ファイルの token を見つけます。 1 つの token を 2 件として出し、終了コード 1 を返します。pull は AUTH_REQUIRED(終了コード 3)で止まりました。AI に渡した token は、取り消して発行し直し(再発行)、設定ファイルの 1 行を書き換えれば済みます。AI が使う API キーの値は、提供元で作り直したキーに dotvault の値を入れ替えます。その仕組みは 11 回目で扱います。7 回目で扱った service token の発行と取り消しの続きです。この回は、同じ画面で作った token を Claude Code に渡します。7 回目を読んでいなくても追えます。
先に、Claude Code に使わせる project を console で作っておきます。ここでは、Projects の New project で demo-agent-app を作りました。作り方は 2 回目と同じです。Read/write の token では project を作れないので、project は人が作ります。
次に、サイドバーの Service Tokens → Create token を開きます。Name を claude-agent、Role を Read/write (member。dotvault の中での役の名前です)、Project を demo-agent-app、Expiry を 30 days にし、Environments は production だけに印を付けました。

Claude Code に import で値を取り込ませるので、Read only ではなく Read/write にします。Environments の欄は、何も選ばなければ全部の環境、選べばその環境だけに使える token になります。Claude Code が取り込む先は production だけなので、production だけにしました。
Create を押すと、token が 1 回だけ表示されます。ここで Copy します。

一覧には 1 行が並びます。Project は demo-agent-app、Envs は production です。

作業するリポジトリ(ここでは ~/dev/demo-agent-app)の .claude/settings.local.json に、token を書きます。Claude Code は、このファイルの env を、自分が実行するコマンドの環境変数として渡します。
{
"env": {
"DOTVAULT_TOKEN": "est_••••"
},
"permissions": {
"allow": [
"Bash(dotvault:*)"
]
}
}
DOTVAULT_TOKEN には、1 節で作った Read/write の token を入れます。import・pull・run が読みます。permissions.allow の Bash(dotvault:*) は、dotvault で始まるコマンドを、毎回の確認なしで実行してよいという許可です。置き場所を、ユーザー全体の ~/.claude/settings.json ではなく、リポジトリの .claude/settings.local.json にしたのは、ユーザー全体に置くと、どのリポジトリで起動した Claude Code にもこの token が渡るためです。このリポジトリでだけ使う token は、このリポジトリに置きます。
このファイルには token が平文で書かれます。.gitignore に .claude/settings.local.json と .env を書いて、commit に入らないようにします。
.env
.claude/settings.local.json
このリポジトリで Claude Code を初めて起動すると、フォルダを信頼するかの確認に、このファイルで許可したコマンドが出ます。

許可されるのが Bash(dotvault:*) の 1 つだけであることを確かめてから、Yes, I trust this folder を選びます。
リポジトリには、ダミーの値の .env(DATABASE_URL・OPENAI_API_KEY・FEATURE_FLAGS の 3 行)を置いてあります。Claude Code には、こう頼みました。
Move this repo's .env into dotvault without asking me. The project demo-agent-app already exists. Use the dotvault CLI: init the config as demo-agent-app, import .env into production, pull it back from production, then check two values with
dotvault run -E production -- printenv DATABASE_URLanddotvault run -E production -- printenv FEATURE_FLAGS(one name per command, never print the whole environment), and finish with whoami.
(one name per command, never print the whole environment) は、環境変数の全部を出さないための一言です。dotvault run は、取り出した値を環境変数として子のコマンドに渡します。printenv を名前なしで実行すると、渡した値がすべて画面に出て、Claude Code の会話の記録にも残ります。Mac の printenv は、名前を 2 つ渡しても 1 つ目の値しか出さないので、key ごとに 1 回ずつ頼みます。
$ env A=1 B=2 printenv A B
1
Claude Code は 7 個のコマンドを実行しました。初めの 2 個は dotvault --help などで使い方を読むためのもので、残りの 5 個で取り込みから確かめまでを進めました。ctrl+o で展開した、5 個のコマンドとその出力です。
![Claude Code の実行の画面(ctrl+o の展開表示)。Bash(dotvault init --name demo-agent-app && dotvault import .env -E production) の出力に「Created project-config.json (project=demo-agent-app). Next: dotvault pull (uses DOTVAULT_TOKEN; no login needed)」と「imported 3 keys into .env [demo-agent-app/production]」。Bash(dotvault pull -E production) の出力に、元の 3 行をコメントにしたという warning と「✓ Wrote 3 keys to …/demo-agent-app/.env」「✔ 1 file synced, 0 excluded, 3 keys total」。dotvault run -E production -- printenv DATABASE_URL の出力にダミーの postgres:// の URL、printenv FEATURE_FLAGS の出力に beta-search。Bash(dotvault whoami) の出力に「Service token (DOTVAULT_TOKEN=est_••••…) — CI / Lambda mode」と、whoami はサーバーに問い合わせないという note。](../assets/DVLT-008/8-5-claude-run.png)
project-config.json を作り、「Next: dotvault pull (uses DOTVAULT_TOKEN; no login needed)」と、token があれば login は要らないと案内しました。.env の 3 行は「# dotvault: moved into the managed block below:」を付けてコメントにし、その下の dotvault が管理する範囲に値を書いた、という warning も出ています。DATABASE_URL と FEATURE_FLAGS のダミーの値が、1 つずつ出ました。最後に、Claude Code はこう報告しました。

何を実行し、何が通ったかを、key の数と値の確かめまで含めて返しています。pull で元の行がコメントになったことも、報告に入っています。私が途中で答えたことはありません。
console の Projects で demo-agent-app を開き、Keys の production を選ぶと、Claude Code が取り込んだ 3 つの key が並んでいます。

5 回目の「.npmrc と kubeconfig を、まだ手で渡している」で使った dotvault scan は、est_ で始まる token も見つけます。リポジトリで scan . を実行しました。
$ dotvault scan .
.claude/settings.local.json:3 [dotvault-service-token] dotvault service token — est_•••• (80 chars)
.claude/settings.local.json:3 [generic-assignment] Generic secret assignment — TOKE•••• (90 chars)
2 potential secret(s) found.
$ echo $?
1
1 つの token が、dotvault service token と Generic secret assignment の 2 つの規則で、2 件として出ました。scan は見つけた文字列の初めと終わりを数文字ずつ出すので、そこも伏せています。.env のダミーの値は出ませんでした。
.claude/settings.local.json は .gitignore で外してありますが、5 回目で書いたとおり、scan . は .gitignore で外したファイルも読みます。commit の前のフックに exec dotvault scan . を置いているリポジトリでは、このファイルがあるだけで commit が止まります。その時は、フックの範囲を exec dotvault scan src/ .github/ のように絞ります。逆に、token を誤って commit されるファイル(チームで共有する .claude/settings.json など)に書いた時は、フックが commit を止めます。
Service Tokens の一覧で、claude-agent の行の Revoke(取り消し)を押しました。「Revoke token “claude-agent”? CI jobs and services using it will lose access immediately.」の確認で OK を押すと、Status が revoked になります。

Last used は token ごとに 1 時間に 1 回だけ記録されるので、ここに出ているのは 3 節で Claude Code が最初に token を使った時刻です(init と import を続けて実行したコマンド)。token を取り消した後に、Claude Code に同じ pull を頼みました。

pull は「✖ AUTH_REQUIRED: invalid, expired or revoked service token」で、終了コード 3 で止まりました。Claude Code は、token が取り消されたか期限が切れたと読み、手元の .env は書き換わっていないこと、新しい token を発行すれば pull をやり直せることを返しました。
whoami では、token が取り消されたかどうかは分かりません。3 節の出力の note のとおり、whoami はサーバーに問い合わせないので、取り消した token でも同じ行を出します。確かめる時は pull か dotvault list --project <name> を使います。
token を取り消した後は、.claude/settings.local.json の DOTVAULT_TOKEN の値も消しておきます。
AI に渡した token は、取り消して新しい token を発行し直し(再発行)、.claude/settings.local.json の値を書き換えれば済みます。Claude Code の側で変えるのは、この 1 行だけです。
AI が使うキーの値(この回の OPENAI_API_KEY のような API キー)も、簡単に入れ替えられます。キーそのものは dotvault が作るのではありません。OpenAI などの提供元でキーを作り直し、dotvault に置いた値を新しい値に入れ替えます。取り替えの管理に登録しておけば、漏れた時に retire で誰にも渡らないように止め、新しい値を置けます。キーの入れ替えの仕組みは、11 回目の「漏れた API キーを 1 コマンドで止める」で扱います。
次回は、一人で使ってきた Personal org を Company org に切り替え、人を招待してロールを渡し、辞めた人の権限を止めるところまでを扱います。
dotvault は、.env や設定ファイルの secret をサーバー側に置き、権限のある人・CI・AI エージェントが 1 コマンドで受け取るサービスです(https://dotvault.io)。この連載が終わる時に、dotvault を誰でも無料で使える形で公開する予定です。公開したら、この連載の手順どおりに使い始められます。
興味のある方は、ぜひ「いいね」と記事の購読をお願いいたします。
自社プロダクトは https://www.eln.ne.jp/products にまとめています。
上原正吉。EarthLink Network Co., Ltd. 代表。AI社員に日々の業務を任せ、開発では人が逐一指示しなくても作業が進むHOOTL(Human Out Of The Loop)の仕組みを自社で実践しています。このブログでは、業務自動化と24時間自動開発のノウハウ、具体的な設定方法、日々の運用で見つかった問題と改善を共有します。
また、AIで業務や開発を組み替えたい会社・チーム向けに、AI活用のコンサルティングも受け付けています。ご相談は www.eln.ne.jp からどうぞ。
EarthLink Network は、会社の全業務を AI で回すために、必要になったものを自社で作っています。いま作っているプロダクトの一覧と概要は、こちらにまとめています。
→ EarthLink Network が自社でつくっている18のプロダクト
会社と各プロダクトの詳細は、公式サイト www.eln.ne.jp をご覧ください。