- 著者
- app-hacks
- 公開日
- 更新日
- 確認日
Cloudflare Pages / Security / Environment Variables
Cloudflare Pages Functionsの環境変数とSecretを分ける判断基準
問い合わせFunctionを題材に、ブラウザへ渡せる値とSecretで管理すべき値を分ける基準を整理する。
環境変数という名前だけでは、値を安全に保管できるとは限らない。Astroでクライアント側へ参照させる値は生成HTMLやJavaScriptから取得できる。一方、Pages Functionだけで使う値はブラウザへ渡さない設計にできる。問い合わせフォームでは、この公開範囲の差で変数を分けている。
公開値と秘密値を用途から分ける
PUBLIC_TURNSTILE_SITE_KEYはウィジェットを表示するブラウザが使う値であり、公開変数として渡す。一方、APIトークン、受信先、Turnstile secretはFunctionのenvだけで使う。設定済みの変数名は次のとおりで、値はどこにも載せない。
CLOUDFLARE_ACCOUNT_ID
CLOUDFLARE_EMAIL_API_TOKEN
CONTACT_RECIPIENT_EMAIL
CONTACT_FROM_EMAIL
PUBLIC_TURNSTILE_SITE_KEY
TURNSTILE_SECRET_KEY
functions/api/contact.tsのEnv型は、値をコードへ固定せず実行環境から受け取るための境界である。環境変数が未設定なら503で止め、空の認証情報で外部APIを呼ばない。PUBLICという接頭辞は秘密化の仕組みではなく、ブラウザへ渡すことを意図した値だけに使う判断である。
秘密値を出さない運用
Secretの実値をGit、Markdown、ブラウザJavaScript、ビルド出力、エラーメッセージ、チャットへ書かない。調査時にconsole.log(env)のような包括的なログを追加すると、問題解決中に値を漏らすため避ける。必要なら設定の有無だけを確認し、値そのものを表示しない。
送信基盤のトークンやTurnstile secretを更新する必要がある場合も、Pages側で差し替え、古い値を履歴へ残さない。ローカル用のテスト設定と本番Secretを混ぜず、docs/contact-form-setup.mdにあるように公開環境の設定とは分ける。
失敗しやすい点と確認方法
クライアントから参照するコードへ秘密値を追加していないか、生成HTMLや配信JavaScriptを確認する。Functionの失敗応答に認証情報やメールアドレスを含めないことも確認する。値の種類ではなく、誰が実行時に読む必要があるかで公開範囲を決めるのが今回の判断理由である。
設定画面に登録されているだけでは、利用側が安全とは限らない。たとえば公開変数をFunctionで使うこと自体は可能でも、その値がブラウザから見える必要がなければ公開変数にする理由はない。逆に、ウィジェット初期化に必要な値をSecretに置くだけではブラウザが参照できず、実装が動かない。必要な実行場所から逆算して、最も狭い公開範囲を選ぶ。
問い合わせの不具合を調べるときは、変数名、設定の有無、HTTPステータス、再現手順を記録し、値をコピーしない。これなら設定漏れと認証失敗を切り分けつつ、調査記録そのものを秘密情報にしない。
記事のコード例でも、変数名だけを示して値の形式や一部を例示しない。この扱いを一貫させる。
公式資料と関連記事
- Cloudflare公式: Environment variables — Pages Functionsの環境変数を確認できる。
- Cloudflare Pages FunctionsからEmail Service REST APIで問い合わせを送信する — Secretを使う送信処理を扱う。
- お問い合わせフォームでCloudflare Turnstileをサーバー側検証する —公開値とSecretの役割を扱う。