CloudflareのSecretsと環境変数をどう管理するか【Cloudflare運用記録 #8】
はじめに
こんにちは。
なかのひとカンパニーの archer です。
前回は、GitHub ActionsからCloudflare Workersへ自動デプロイする流れについて書きました。
自動デプロイまで作ると、次に気になるのが、
環境変数やAPIキーをどこに置くか
です。
開発していると、
APIのURL
APIキー
認証Token
外部サービスの秘密鍵
Cloudflareの認証情報
などが増えてきます。
全部 .env に入れておけばいいようにも見えます。
ただ、実際には、
ローカル開発
GitHub Actions
本番Workers
で役割が違います。
今回は、自分がCloudflareを使ううえで意識しているSecretsと環境変数の分け方をまとめます。
まずSecretと普通の環境変数を分ける
Cloudflare Workersでは、通常の環境変数とSecretを分けて管理できます。
自分の場合は、ざっくり、
知られても問題ない設定値
→ vars
外に出てはいけない値
→ secrets
と考えています。
たとえば、
API_BASE_URL
APP_ENV
SITE_URL
などは通常の環境変数で問題ありません。
一方、
API_KEY
ACCESS_TOKEN
DATABASE_PASSWORD
PRIVATE_KEY
などはSecretとして扱います。
Cloudflareの vars は暗号化された秘密情報の保存場所ではありません。
秘密にしたい値は vars に書かない。
ここは単純ですが重要です。
通常の環境変数はWranglerへ書ける
秘密ではない設定値なら、Wranglerの設定ファイルへ書けます。
たとえば、
{
"vars": {
"APP_ENV": "production",
"API_BASE_URL": "https://example.com"
}
}
のような形です。
Workers側では、
env.APP_ENV
env.API_BASE_URL
として利用できます。
設定自体をGitで管理できるので、
どんな環境変数を使っているのか
もコードと一緒に確認できます。
SecretはWranglerから登録する
秘密情報は、設定ファイルへ値を書かずに登録します。
たとえば、
npx wrangler secret put API_KEY
を実行します。
すると値を入力するよう求められます。
登録したSecretはWorker側で、
env.API_KEY
として利用できます。
コードから見ると通常の環境変数と似ていますが、
管理方法が違う
ということです。
API Tokenを、
{
"vars": {
"API_KEY": "xxxxxxxxxxxxxxxx"
}
}
のように書いてGitへcommitすることは避けます。
ローカルでは .dev.vars を使う
ローカル開発では、本番Workersへ登録したSecretをそのまま使いたくありません。
Cloudflareでは、
.dev.vars
または、
.env
をローカル開発用として利用できます。
自分なら、Cloudflare Workers用だと分かりやすいので .dev.vars を使います。
たとえば、
API_KEY="local-api-key"
APP_SECRET="local-secret"
のようにします。
ただし、このファイルはGitへcommitしません。
.gitignore に、
.dev.vars
.dev.vars.*
.env
.env.*
などを入れておきます。
.dev.vars と .env は両方使わない
Cloudflareでは .dev.vars と .env の両方をローカル環境変数として利用できます。
ただし、両方を同時に使う前提にはしない方が分かりやすいです。
.dev.vars が存在すると、Wranglerのローカル開発では .env の値は読み込まれません。
そのため、
これは.env
これは.dev.vars
と分散させるより、
どちらを使うか決める
方が管理しやすいと思っています。
本番のSecretはCloudflareに置く
ローカルでは、
.dev.vars
を使います。
一方、本番ではCloudflare Workers側へSecretを登録します。
npx wrangler secret put API_KEY
という形です。
つまり、
ローカル
↓
.dev.vars
本番
↓
Cloudflare Worker Secrets
と分けます。
同じ変数名でも、値は別です。
たとえば、
ローカル
API_KEY=test_xxxxx
本番
API_KEY=prod_xxxxx
という形にできます。
本番用の秘密情報を、開発PCへ置く必要も減ります。
GitHub Actions用のSecretはまた別
前回の記事では、GitHub ActionsからCloudflareへデプロイするために、
CLOUDFLARE_API_TOKEN
CLOUDFLARE_ACCOUNT_ID
をGitHub Secretsへ登録しました。
ここで少し分かりにくいのが、
GitHub Actions用のSecretと、アプリが使うSecretは別物
というところです。
たとえば、
CLOUDFLARE_API_TOKEN
↓
GitHub ActionsがCloudflareへDeployするため
EXTERNAL_API_KEY
↓
本番Workerが外部APIを使うため
です。
役割を分けると、
GitHub Secrets
→ CI/CDが必要な秘密情報
Cloudflare Secrets
→ 実行中のWorkerが必要な秘密情報
となります。
全部GitHub Secretsへ入れてWorkerへ渡すこともできますが、必要がなければ実行環境側のSecretはCloudflareで管理した方が分かりやすいと思っています。
必要なSecret名だけ設定ファイルに書ける
2026年から、Wranglerでは必要なSecretの名前を設定ファイルへ宣言できます。
たとえば、
{
"secrets": {
"required": [
"API_KEY",
"APP_SECRET"
]
}
}
です。
ここには値を書きません。
書くのは、
このWorkerには、このSecretが必要
という名前だけです。
これがあると、必要なSecretがCloudflare側へ登録されていない状態でDeployしようとした場合、Wranglerが検出できます。
これはかなり便利だと思います。
以前は、
Deploy成功
↓
実行
↓
Secretがない
↓
エラー
となる可能性がありました。
必要なSecretを宣言しておけば、
Deploy前
↓
Secret不足を検出
できます。
秘密の値はGitへ入れずに、
必要なSecretの一覧だけGitで管理する
という形にできます。
stagingとproductionも分ける
サービスが大きくなってくると、
development
staging
production
のように環境を分けることがあります。
Secretも環境ごとに分けます。
たとえば、
staging
API_KEY=staging_xxxx
production
API_KEY=production_xxxx
です。
Cloudflareの環境ごとにSecretは独立して管理できます。
「同じコードだから同じSecretを使う」
必要はありません。
むしろ本番Tokenをstagingでも使う方が危険です。
Next.jsの NEXT_PUBLIC_ には注意する
Next.jsを使っている場合は、もう一つ注意しています。
NEXT_PUBLIC_
です。
たとえば、
NEXT_PUBLIC_SITE_URL
なら問題ありません。
名前の通り、公開されても問題ない値です。
しかし、
NEXT_PUBLIC_API_SECRET
NEXT_PUBLIC_PRIVATE_KEY
のようなものはダメです。
NEXT_PUBLIC_ を付けた環境変数は、Next.jsのBuild時にブラウザへ配信するJavaScriptへ埋め込まれる可能性があります。
つまり、
Secretではありません。
名前に SECRET と書いてあっても、
NEXT_PUBLIC_
を付けた時点で公開情報として考える必要があります。
Secretをログへ出さない
Secretを安全に保存しても、
console.log(env.API_KEY);
としてしまえば意味がありません。
特にエラー調査中は、
環境変数がちゃんと設定されているか確認したい
となりがちです。
そのときも値そのものではなく、
console.log({
hasApiKey: Boolean(env.API_KEY),
});
のように、
存在しているかだけ確認する
ようにしています。
CIログやWorkersログは後から見ることがあります。
一度ログへ出した秘密情報は、保存場所だけ直しても終わりではありません。
現在の分け方
今の自分の考え方をまとめると、こんな感じです。
| 種類 | 保存場所 |
|---|---|
| 公開してよい設定 | Wrangler vars
|
| ローカルSecret | .dev.vars |
| 本番アプリSecret | Cloudflare Workers Secrets |
| CI/CD認証情報 | GitHub Secrets |
| ブラウザで使う値 |
NEXT_PUBLIC_ ※公開前提 |
さらに、
本当に秘密なのか
↓
どの環境で必要なのか
↓
誰が使うのか
を考えて保存場所を決めます。
今回使ったサービスの料金
Workersの通常の環境変数やSecretsを設定すること自体に、
Secret 1個につき月額○円
というような料金が発生するわけではありません。
そのため、今回の構成でSecrets管理のためだけに追加される月額は、
0円
です。
ただし、Secretを使って呼び出す外部APIやサービスには、当然それぞれの料金があります。
また、Cloudflare Workers自体の利用量については、これまでの記事で紹介したFree / Paidの制限が適用されます。
※仕様・料金・制限は2026年9月時点の情報を前提としています。
最新情報はCloudflare公式ドキュメントを確認してください。
まとめ
今回はCloudflare WorkersでSecretsと環境変数をどう管理するかについてまとめました。
自分が意識しているのは、
- 公開してよい値は
vars - 秘密情報はSecrets
- ローカルSecretは
.dev.vars -
.dev.varsをGitへcommitしない - 本番SecretはCloudflareへ登録する
- CI/CD用SecretはGitHub Secretsへ置く
-
NEXT_PUBLIC_は公開情報として扱う - Secretそのものをログへ出さない
- 必要なSecret名は
secrets.requiredで管理できる
というところです。
環境変数は、開発を始めたころは、
「とりあえず .env に入れておくもの」
くらいに考えていました。
でも本番運用まで考えると、
誰が使うのか
どこで使うのか
秘密なのか
を分ける必要があります。
Cloudflareでは、
ローカル
↓
.dev.vars
CI/CD
↓
GitHub Secrets
本番
↓
Cloudflare Secrets
と役割を分けられます。
サービスを公開するところまで自動化したからこそ、
秘密情報まで一緒に自動で流さない
ことも大事だと感じています。
次回は、
Cloudflareで本番障害が起きたとき、どこを見るか
について書きます。
Workers、D1、R2、DNS、Tunnel、GitHub Actionsなど、Cloudflareを使うサービスが増えたときの障害切り分けをまとめる予定です。
