Worker の設定とシークレットを管理する

CloudflareBeginner
オンラインで実践に進む

はじめに

サポートサービスでは、設定変更を安全にプレビューできる場所が必要です。この実験では、同じコードを preview 環境と live 環境で実行し、それぞれの公開ラベルとシークレットを分離します。また、ヘルスチェックは公開したまま、合成メンテナンスエンドポイントを保護します。

自分の Cloudflare 学習用アカウントを使用し、これまでの実験で学んだデバイス認証、デプロイメント、ログの知識を活用してください。この実験は /home/labex/project/worker-config で独立して開始します。Node.js 22.22.0、プロジェクトローカルの Wrangler 4.131.1、小規模なヘルスルート用フィクスチャがあらかじめ用意されています。以前の VM やクラウドリソースは再利用しません。両方のデプロイメントは破棄可能で、メンテナンス操作はドライランです。生成した合成トークンだけを使用してください。Workers Free と workers.dev でこの小規模な演習を実行できます。リクエストはアカウントの使用量に加算されます。購入済みのドメイン、データベース、有料アップグレードは必要ありません。

最後に、両方のクラウドデプロイメントとローカルのトークンファイルを削除し、VM を終了する前にログアウトします。作業中は同じターミナルを開いたままにしてください。

Preview と live の設定を分離する

このステップでは、用意されている同じヘルスハンドラーを、2 つの名前付き環境で使用します。ここでの live も破棄可能な学習用デプロイメントです。どちらの環境も実際の本番データを処理しません。preview は Wrangler の環境名であり、バージョンプレビュー URL ではありません。

準備済みのプロジェクトに移動し、ヘルスルート用フィクスチャを確認します。Node とプロジェクトローカルの Wrangler はすでにインストールされています。

cd /home/labex/project/worker-config
node --version
npx wrangler --version
cat src/index.js

Node のバージョンは v22.22.0、Wrangler のバージョンは 4.131.1 と表示されます。ハンドラーは、シークレットではない表示用の値を env から読み取ります。自分の環境で同じ構成を作る場合は、Node をインストールし、wrangler@4.131.1 をプロジェクトの開発用依存関係として追加してください。既存の依存関係は npm ci で再現します。

破棄可能なベース名を生成します。コマンド置換によって、ランダムな 16 進数の出力がシェル変数に挿入されます。後続のコマンドで使うため、このターミナルを開いたままにしてください。

WORKER_NAME="labex-config-$(openssl rand -hex 6)"

heredoc を使って設定を書き込みます。終端マーカーを引用符で囲んでいないため、$WORKER_NAME が置換されます。main は共通のコードを指定し、compatibility_date はランタイムの動作を指定します。env オブジェクトは、--env preview--env live の設定を上書きします。これらのバインディングは継承されないため、各環境で vars の値をすべて定義します。データベースやキューのリソースはありません。QUEUE_LABEL は公開表示用のラベルにすぎません。

cat > wrangler.jsonc <<CONFIG
{
  "name": "$WORKER_NAME",
  "main": "src/index.js",
  "compatibility_date": "2026-09-14",
  "workers_dev": true,
  "preview_urls": false,
  "env": {
    "preview": {"vars": {"ENVIRONMENT": "preview", "QUEUE_LABEL": "sandbox"}},
    "live": {"vars": {"ENVIRONMENT": "live", "QUEUE_LABEL": "primary"}}
  }
}
CONFIG

両方のローカルランタイムを起動します。> は出力をリダイレクトし、2>&1 はエラーも含め、& はプロセスをバックグラウンドで実行します。HTTP ポートとインスペクターポートを分けて、競合を避けます。

npx wrangler dev --env preview --port 8080 > preview.log 2>&1 &
npx wrangler dev --env live --port 8081 --inspector-port 9230 > live.log 2>&1 &
cat preview.log
cat live.log

両方のログに準備完了のメッセージが表示されるまで待ちます。必要であれば、対応する cat コマンドをもう一度実行してください。その後、レスポンスを比較します。

curl -i http://127.0.0.1:8080/health
curl -i http://127.0.0.1:8081/health

どちらも 200 を返します。preview は {"status":"ok","environment":"preview","queue":"sandbox"} を返し、live は {"status":"ok","environment":"live","queue":"primary"} を返します。curl -i はステータスとヘッダーも表示します。両方のサーバーを起動したまま、検証ボタンを使用してください。

環境のドキュメントでは、環境の継承と、デプロイ時に使用されるデフォルトの <name>-<environment> 形式の名前について説明しています。

ローカルシークレットでメンテナンスルートを保護する

このステップでは、環境ごとに異なるトークンを使って、合成メンテナンス操作を保護します。シークレットは env から利用できる非公開の設定です。公開用の vars、返却する JSON、アプリケーションログに含めてはいけません。この小さな Bearer トークンの例では、サーバー側の境界を学びます。完全なユーザー認証システムを実装するものではありません。

シークレットファイルを追加する前に、2 つのローカルジョブを停止します。実際のジョブ番号を確認してください。以下の例では、preview が 1、live が 2 であると仮定しています。

jobs
kill %1 %2

表示せずに、テスト専用のランダムなトークンを 2 つ生成します。umask 077 により、新しく作成するファイルを VM のユーザーだけが読み取れるようにします。printf は、各環境用のファイルに dotenv 形式の代入を 1 行ずつ書き込みます。ここでは実際のアカウント API トークンを絶対に使用しないでください。

umask 077
PREVIEW_TOKEN=$(openssl rand -hex 24)
LIVE_TOKEN=$(openssl rand -hex 24)
printf 'MAINTENANCE_TOKEN=%s\n' "$PREVIEW_TOKEN" > .dev.vars.preview
printf 'MAINTENANCE_TOKEN=%s\n' "$LIVE_TOKEN" > .dev.vars.live
cat .gitignore

.dev.vars*.env* が除外されていることを確認します。シークレットファイルを表示したり、コミットしたりしないでください。Wrangler は --env preview に対して .dev.vars.preview を読み込み、--env live に対して別の live 用ファイルを読み込みます。環境固有の .dev.vars ファイルがある場合、汎用のファイルが置き換えられます。これらのファイルがシークレットを自動的に Cloudflare へアップロードすることはありません。ローカルシークレットとデプロイ済みシークレットを参照してください。

ハンドラーを置き換えます。引用符で囲んだ heredoc により、JavaScript をそのまま保持できます。設定されたシークレットがない場合は 503 を返し、リクエストの認証情報がない場合または正しくない場合は 401 を返します。成功を返す前に、サーバーで Authorization ヘッダーを比較します。ログに記録するのは、固定のイベント名、公開環境名、数値のステータスだけです。受け付ける操作はドライランであり、保存される副作用はありません。

cat > src/index.js <<'JS'
export default {
  async fetch(request, env) {
    const path = new URL(request.url).pathname;
    if (path === '/health' && request.method === 'GET') {
      return Response.json({status: 'ok', environment: env.ENVIRONMENT, queue: env.QUEUE_LABEL});
    }
    if (path !== '/maintenance') return Response.json({error: 'not_found'}, {status: 404});
    if (request.method !== 'POST') {
      return Response.json({error: 'method_not_allowed'}, {status: 405, headers: {Allow: 'POST'}});
    }
    // Fail closed if this environment has no configured secret.
    if (!env.MAINTENANCE_TOKEN) {
      return Response.json({error: 'maintenance_unconfigured'}, {status: 503});
    }
    const authorized = request.headers.get('Authorization') === `Bearer ${env.MAINTENANCE_TOKEN}`;
    const status = authorized ? 200 : 401;
    console.log(JSON.stringify({event: 'maintenance', environment: env.ENVIRONMENT, status}));
    if (!authorized) return Response.json({error: 'unauthorized'}, {status});
    return Response.json({operation: 'dry-run', environment: env.ENVIRONMENT});
  }
};
JS
npx wrangler dev --env preview --port 8080 > preview.log 2>&1 &
npx wrangler dev --env live --port 8081 --inspector-port 9230 > live.log 2>&1 &
cat preview.log
cat live.log

両方のサーバーに準備完了のメッセージが表示されたら、認証の境界を確認します。-X POST はメソッドを指定し、-H は Bearer ヘッダーを指定します。実際の認証情報を使う場合は、curl の詳細出力を使用しないでください。

curl -i -X POST http://127.0.0.1:8080/maintenance
curl -i -X POST http://127.0.0.1:8080/maintenance -H "Authorization: Bearer incorrect-token"
curl -i -X POST http://127.0.0.1:8080/maintenance -H "Authorization: Bearer $LIVE_TOKEN"
curl -i -X POST http://127.0.0.1:8080/maintenance -H "Authorization: Bearer $PREVIEW_TOKEN"
curl -i -X POST http://127.0.0.1:8081/maintenance -H "Authorization: Bearer $LIVE_TOKEN"
curl -i http://127.0.0.1:8080/health
curl -i http://127.0.0.1:8081/health

最初の 3 つのリクエストは、他の環境では有効なトークンを使用した場合も含め、401 unauthorized を返します。続く 2 つのリクエストは、operation: dry-run と、それぞれ自身の環境を含む 200 を返します。ヘルスチェックは引き続き公開されています。検証を実行して、トークンの分離、メソッド、公開設定、ローカルログにトークン値が含まれていないことを、両方向について確認してください。

各環境をデプロイし、対応するシークレットをアップロードする

このステップでは、新しい VM を認証し、名前付き環境をそれぞれデプロイして、シークレットを明示的にアップロードします。最初にローカルジョブを停止してください。jobs で実際のジョブ番号を確認します。

jobs
kill %1 %2
npx wrangler login --device --browser=false --scopes account:read user:read workers_scripts:write workers_tail:read

表示されたリンクを開き、サインイン済みのブラウザーで現在のコードを入力します。Wrangler が要求する権限と Background Access を確認し、接続の実験で学んだ手順に従って、自分の学習用アカウントだけを選択して認証します。ターミナルの処理が完了するまで待ちます。

npx wrangler whoami --json

loggedIn: true と、アカウント名および ID が表示されることを確認します。以下の YOUR_ACCOUNT_ID を実際の ID に置き換えてください。元のリソース名はそのまま保持します。

cat > wrangler.jsonc <<CONFIG
{
  "name": "$WORKER_NAME",
  "main": "src/index.js",
  "compatibility_date": "2026-09-14",
  "account_id": "YOUR_ACCOUNT_ID",
  "workers_dev": true,
  "preview_urls": false,
  "env": {
    "preview": {"vars": {"ENVIRONMENT": "preview", "QUEUE_LABEL": "sandbox"}},
    "live": {"vars": {"ENVIRONMENT": "live", "QUEUE_LABEL": "primary"}}
  }
}
CONFIG

このプロジェクトでは、常に --env を指定してください。指定しない場合、Wrangler は名前のないトップレベル環境を対象にします。この環境は、今回の実験のデプロイ計画には含まれていません。

npx wrangler deploy --env preview
npx wrangler deploy --env live

デプロイ出力に表示された workers.dev アドレスを、それぞれ正確にコピーします。学習用アカウントにすでにあるサブドメインを再利用してください。初回利用時は、既存のサブドメインを変更せず、Wrangler が表示する利用可能なサブドメインのプロンプトに従います。

PREVIEW_URL="https://YOUR_BASE-preview.YOUR_SUBDOMAIN.workers.dev"
LIVE_URL="https://YOUR_BASE-live.YOUR_SUBDOMAIN.workers.dev"
curl -i -X POST "$PREVIEW_URL/maintenance"
curl -i -X POST "$LIVE_URL/maintenance"

どちらも 503 maintenance_unconfigured を返します。通常のデプロイでは、ローカルのシークレットファイルはアップロードされないためです。ヘルスチェックはメンテナンス認証とは独立しています。

標準の一括コマンドを使って、対応する環境に dotenv ファイルをアップロードします。シークレットが 1 つだけの場合も、このファイルベースの操作を使用できます。出力にはシークレット名が表示されますが、値は表示されません。シークレットを更新すると、バージョンが直ちに作成され、デプロイされます。

npx wrangler secret bulk .dev.vars.preview --env preview
npx wrangler secret bulk .dev.vars.live --env live
npx wrangler secret list --env preview
npx wrangler secret list --env live

それぞれの一覧に、種類 secret_textMAINTENANCE_TOKEN が含まれていることを確認します。公開値と認証動作を比較します。

curl -i "$PREVIEW_URL/health"
curl -i "$LIVE_URL/health"
curl -i -X POST "$PREVIEW_URL/maintenance"
curl -i -X POST "$PREVIEW_URL/maintenance" -H "Authorization: Bearer $LIVE_TOKEN"
curl -i -X POST "$PREVIEW_URL/maintenance" -H "Authorization: Bearer $PREVIEW_TOKEN"
curl -i -X POST "$LIVE_URL/maintenance" -H "Authorization: Bearer $LIVE_TOKEN"

ヘルスチェックでは、preview/sandbox と live/primary が維持されます。認証情報がない場合と別環境の認証情報を使った場合は 401 を返し、対応するトークンを使った場合は 200 を返します。接続エラーが発生した場合は、ホスト名の初回反映が完了するまで待ってから再試行してください。同じ Dashboard アカウントで、Compute → Workers & Pages を開きます。-preview-live で終わる 2 つの Worker を見つけ、完全な名前と URL をデプロイ出力と比較します。この例では、名前付き Wrangler 環境ごとに独自のデプロイ済み Worker が作成されています。Dashboard で別のアプリケーションを作成しないでください。

Workers and Pages に表示された分離された preview と live の Worker

-preview Worker を開き、Settings を選択します。Runtime variables and secretsVariables and secrets セクション)で、TypeNameValue の各列を比較します。ENVIRONMENTpreviewQUEUE_LABELsandbox になっているはずです。MAINTENANCE_TOKEN の種類は Secret で、Value encrypted と表示され、読み取り可能な値は表示されません。

sandbox の変数と暗号化されたメンテナンスシークレットが表示された preview 環境

Workers & Pages に戻り、-live Worker を開いて同じセクションを確認します。公開値は liveprimary になっているはずです。独立してアップロードしたシークレットも、同じバインディング名を使用します。表を比較する前に、上部のパンくずリストで Worker 名を確認してください。

primary の変数と独自の暗号化されたメンテナンスシークレットが表示された live 環境

画像に表示されているランダムな名前のサフィックスとサブドメインは例です。暗号化された表示から確認できるのは、シークレットバインディングの存在と種類です。2 つの環境でシークレット値が異なることを示すものではありません。前述の、同じ環境のトークンと別環境のトークンを使った HTTP チェックによって、その動作を確認します。この確認では読み取りだけを行ってください。Dashboard で変数を編集したり、認証情報を表示、置換、コピーしたりしないでください。検証を実行すると、両方の環境について、実際の所有権、デプロイ済みバインディングの種類、公開動作が確認されます。

シークレットを公開せずにアプリケーションログを確認する

このステップでは、デプロイ済みの preview 環境で、拒否されたリクエストと受け付けられたリクエストを 1 つずつ確認します。アプリケーションログには、認証情報やリクエストヘッダーをコピーせずに、結果が分かる情報だけを記録します。

これまでに学んだ tail コマンドでログストリームを開始します。pretty 形式ではアプリケーションメッセージが見やすく表示されます。ストリームを停止した後で限定されたテスト結果を確認できるよう、ログを保存します。

npx wrangler tail --env preview --format pretty > preview-tail.log 2>&1 &
cat preview-tail.log

ストリームが接続されたことを示すメッセージが表示されるまで待ちます。接続中は cat を繰り返し実行してください。その後、新しい合成リクエストを送信します。

curl -i -X POST "$PREVIEW_URL/maintenance" -H "Authorization: Bearer incorrect-token"
curl -i -X POST "$PREVIEW_URL/maintenance" -H "Authorization: Bearer $PREVIEW_TOKEN"

grep を使って、固定のアプリケーションイベント名を含む行だけを表示します。

grep 'maintenance' preview-tail.log

ステータス 401 と 200 のイベントが表示されるまで待ちます。どちらも公開環境は preview です。どちらのメッセージにもトークン値が含まれてはいけません。イベントの配信は HTTP レスポンスより遅れる場合があります。最大 1 分間、grep を再試行してください。イベントが見つからない場合は、ソース内の対応する console.log を確認します。

jobs
kill %1

両方のイベントが表示されたら、実際の tail ジョブを停止します。以下の例ではジョブ 1 であると仮定しています。検証を実行して、保存したログを確認し、リモートの認証契約を個別に再確認します。ここで扱うのは合成リクエストだけであり、将来の任意のログ変更に対する安全性を保証するものではありません。

両方の環境のデプロイメントを削除する

このステップでは、まだ認証済みの状態で、破棄可能な 2 つの環境 Worker を削除します。設定内のベース名と学習用アカウントを確認します。

cat wrangler.jsonc

この実験の preview と live のデプロイメントだけを削除します。各プロンプトで正確な <base>-preview または <base>-live の名前を確認し、単一のキー y を押します。

npx wrangler delete --env preview
npx wrangler delete --env live

これらの Worker を削除すると、関連付けられたシークレットバインディングも削除されます。その後、Wrangler 4.131.1 が、以前から報告されているレガシー Workers Sites KV 認証エラーを表示する場合があります。権限を広げたり、そのエラーを削除完了の証拠として解釈したりしないでください。Workers & Pages を更新し、検証を実行します。認証済みのインベントリで、両方の名前が存在しないことを確認してください。認証エラーやネットワークエラーだけでは判断できません。関係のない Worker、学習用アカウント、その既存のサブドメインは保持してください。

ローカルシークレットを削除して接続を解除する

このステップでは、クラウドのクリーンアップを確認した後で、この実験用のローカルシークレットのコピーを削除し、VM の接続を解除します。rm は以下に指定した 2 つのファイルだけを削除し、unset は一時的なシェル変数 2 つを削除します。

rm .dev.vars.preview .dev.vars.live
unset PREVIEW_TOKEN LIVE_TOKEN
npx wrangler logout
npx wrangler whoami --json

明示的に "loggedIn": false と表示されることを確認します。この構造化された結果が表示される場合、未認証のコマンドがゼロ以外の終了コードを返すのは想定どおりです。検証を実行してから、VM を終了します。ブラウザーのログイン状態は別に管理されるため、次の実験のために残しておいて構いません。ログアウトや VM の終了は、先にクラウドリソースを削除する代わりにはなりません。

まとめ

Wrangler の環境ごとに公開設定を分離し、環境固有のローカルシークレットを読み込み、暗号化されたシークレットバインディングをアップロードしました。また、一致する認証情報、認証情報がない場合、別環境の認証情報を使った場合の動作を確認しました。公開ヘルスルートでは環境の識別情報を維持しながら、サーバー側でドライランのメンテナンスルートを保護しました。トークンを表示せずに限定されたアプリケーションログを確認し、ローカル認証情報を削除してログアウトする前に、削除が完了したことを検証しました。

同じ設定管理の考え方は、このコースの後半で preview 設定のずれを診断するときにも役立ちます。