Cloudflareで安全なベータ待機リストを構築する方法
Tech
Cloudflare Workers
Beta Waitlist
Double Opt-In
Turnstile

Cloudflareで安全なベータ待機リストを構築する方法

double opt-in、Turnstile、ハッシュ化トークン、SMTP、管理者向け制御、リリースゲートを備えた、本番対応のCloudflareベータ待機リストを構築する実践的な方法。

Uygar DuzgunUUygar Duzgun
Jul 26, 2026
更新日 2026年8月20日
9 min read

Cloudflareで安全なベータ待機リストを構築する方法

ベータ待機リストがビジネス資産になるのは、登録されたアドレスが実在する場合だけです。

多くのチームは、メールアドレス入力欄と送信ボタンから始めます。ランディングページの実験なら、それで十分です。しかし、リストがローンチ計画、招待の段階的な送信、投資家向けの更新、プロダクトに関する意思決定を左右し始めると、それだけでは不十分です。誰でも他人のアドレスを登録できたり、botが一晩でデータベースを埋め尽くしたりすると、チームが得るのは使えるシグナルではなく、ノイズの多い需要情報です。

私がCloudflare上で本番対応のベータ待機リストを構築する際に使っている方法は、double opt-in、サーバーサイドのbotチェック、有効期間の短い確認リンク、ハッシュ化トークン、既存のメールホスティングを利用したSMTP配信、verifiedとlegacyの行を分ける管理者向けデフォルト設定、そして設定済みのインフラがすでに稼働しているかのように扱わないリリースゲートを組み合わせるものです。

最近のベータ待機リスト実装では、完全なアカウントシステムを必要とせず、実際の配信環境でこの方法の有効性を確認できました。重要なのは作業の形です。つまり、同意、不正利用、配信、データ品質、デプロイの境界を明確にした、小さな登録画面です。

安全な待機リストが解決するビジネス上の課題

待機リストには2つの役割があります。

需要を集めること、そしてチームがその需要に対応できるようにすることです。弱いフォームが機能しなくなるのは、後者の部分です。

リストを信頼できなければ、あらゆるフォローアップが遅くなります。何行がbotによるものなのか分からず、招待メールを送る前にためらいます。データをエクスポートして手作業で整理しても、そのアドレスを本当に管理している人なのかは分かりません。リストはリリースのためのツールではなく、大まかな虚栄指標になってしまいます。

安全なベータ待機リストがあれば、よりクリーンな入力を得られます。

botやスクリプトによる偽の登録が減る
同意なしに送信されたアドレスが減る
その人が受信トレイを管理していることをより確実に確認できる
ローンチやアウトリーチに使う管理者向けエクスポートが明確になる
ベータ招待を送る前の手作業による整理が減る
公開トラフィックが到達する前に、より安全なデプロイ経路を確保できる

目的は、単純なフォームを複雑にすることではありません。ビジネスがフォームの意味だと考えているものを、実際にその意味どおりにすることです。

Cloudflareのアーキテクチャ

コアとなるスタックは意図的に小さくしています。

Cloudflare Workersがリクエストを処理します。Cloudflare Turnstileが登録が人間によるものらしいかを確認します。D1が待機リストの行と確認待ちのレコードを保存します。既存のSMTP/メールホスティングがTLS経由で確認メールを送信します。スケジュールされたWorkerのクリーンアップジョブが、有効期限切れの確認待ちレコードを削除します。

このスタックは、多くのアーリーステージのチームにとって十分です。責任あるベータリストを集めるだけなら、完全なユーザーアカウントシステムを追加する必要はありません。

フローは次のとおりです。

訪問者が待機リストのフォームからメールアドレスを送信する。
Workerがorigin、本文サイズ、honeypot、レート制限、Turnstileを検証する。
Workerが24時間の有効期限付きで確認待ちを作成する。
生のトークンはメールリンクに含めるが、D1にはキー付きハッシュのみを保存する。
ユーザーがリンクを開き、同一originのPOSTを通じて確認する。
Workerが一度限りのトークンを消費し、verifiedの待機リスト行を書き込む。
管理者画面とCSVエクスポートでは、デフォルトでverifiedのアドレスを表示する。

これにより、プロダクトチームは明確に分けて扱えます。確認待ちの関心と、verifiedの需要は同じものではありません。

Double opt-inはプロダクト上の意思決定

double opt-inは、メールの衛生管理として説明されることが多いものです。私はこれをプロダクトの衛生管理だと考えています。

ベータリストによって誰が最初にアクセスできるかを決めるのであれば、各アドレスが確認した本人のものであることをチームは把握すべきです。24時間の確認期間は、通常の登録には十分であり、古い確認待ちの行が長期間残らない程度に短い期間です。

確認リンク自体が状態を変更してはいけません。リンクスキャナー、メールのプレビュー、意図しないGETリクエストは存在します。より安全なパターンは、リンクによって確認ページを表示し、その後ユーザーがボタンを押して同一originのPOSTを送信することです。

この追加のクリックは小さなものです。しかし、その境界には意味があります。

サポートもより簡単になります。登録した覚えがないと言われた場合でも、受信トレイへのアクセスと明示的な確認操作が必要なフローを経てから、そのアドレスがverifiedリストに入る仕組みだと説明できます。

敵対的に感じさせないbot対策

優れた待機リストは、セキュリティ試験のように感じられるべきではありません。

対策の大部分はフォームの背後に置くべきです。この構成では、Workerが管理対象のCloudflare Turnstileウィジェットをサーバーサイドで検証します。検証では、トークン、期待されるaction、期待されるhostnameを確認します。サーバー検証のないブラウザウィジェットは飾りにすぎません。Workerが検証しなければなりません。

Turnstileは1つのレイヤーにすぎません。フォームでは、簡易的なbot検出のためのhoneypotフィールド、サイズの大きいペイロードがWorkerの処理時間を浪費しないように制限したリクエスト本文、キー付きのIPレート制限、アドレスごとの試行回数制限も使用します。

アドレスごとの制限は重要です。メール確認が迷惑行為の手段になる可能性があるからです。同じ受信トレイに対して、誰かが確認メールを何度も送信させる状況は避けたいものです。

公開レスポンスは汎用的な内容にします。アドレスがすでに存在するのか、確認待ちなのか、抑制対象なのか、制限に達したのかを明らかにしてはいけません。これにより、登録エンドポイントがメールアドレス列挙ツールになるのを防げます。

トークンの保存:送信するものをハッシュ化する

確認リンクは、受信トレイへのアクセスを証明するため機密性が高いものです。

実装では、メールリンクにランダムなトークンを含めて送信しますが、D1にはそのトークンのキー付きハッシュだけを保存します。確認時にWorkerが送信されたトークンをハッシュ化し、保存されたハッシュと比較します。生のトークンがデータベースに保存されることはありません。

この設計により、システムをシンプルに保ちながら、被害の範囲を抑えられます。確認待ちテーブルが漏洩しても、攻撃者がそのまま使える確認リンクを入手することはできません。

トークンは一度しか使えません。確認に成功すると、Workerが確認待ちレコードを削除します。有効期限切れの確認待ち行は、通常の待機リスト処理中に機会的に削除され、スケジュールされた毎日のCloudflare Cronによっても削除されます。

このクリーンアップ経路により、手作業でデータベースを整理しなくてもテーブルを小さく保てます。

既存のメールホスティングを利用したメール配信

多くのチームはすでにメールホスティングを利用しています。ベータ待機リストのためだけに、新しいトランザクションメールベンダーが必要とは限りません。

私が検証した実装では、既存のメールホスティング上に専用の送信者アドレスを作成し、WorkerがTLS経由のSMTPで送信します。メールの内容は簡潔です。ベータ登録を確認すること、リンクの有効期間は24時間であること、依頼していない場合は無視することを伝えます。

この用途にはそれで十分です。

価値があるのは、凝ったメールデザインではありません。既知の送信者、明確な目的、そしてローンチ前にスモークテストできる配信経路です。スタートアップにとっては、プロダクトにまだユーザーがいない段階で別のベンダーを追加するよりも、こちらの方が適していることがよくあります。

管理者画面はチームを誤った前提から守るべき

セキュリティは公開エンドポイントだけの問題ではありません。

管理者画面は、データ契約を反映する必要があります。verifiedのアドレスはデフォルトで表示すべきです。古いunverifiedまたはlegacyの行を利用できるようにしても構いませんが、明示的なフィルターを必要とするようにします。CSVエクスポートも同じルールに従うべきです。

これにより、よくあるローンチ時のミスを防げます。つまり、過去のすべての行をエクスポートし、それを確認済みの需要として扱ってしまうことです。

最近の実装では、新しい確認モデルを導入する前から、本番リストにlegacyのアドレスが存在していました。移行計画では、これらのアドレスをlegacyエントリとして保持します。新しいシステムにverifiedという状態があるからといって、古い行を暗黙的にverifiedとして扱うことはありません。

これは移行と履歴の書き換えの違いです。

設定済みであることと稼働中であることは別

この境界は、別のチームに提供するサービスの一部だと考えています。

メールボックスが存在していても、Turnstileウィジェットが存在していても、Workerのシークレット名が設定されていても、テストに合格していても、それだけで公開サイトが新しい待機リストを実行していることにはなりません。

現在のリファレンス実装では、double opt-inフローは実装され、ローカルで検証済みです。保留中のD1マイグレーション、新しいWorkerバージョン、スケジュールされたクリーンアップCronには、まだリリース承認とデプロイが必要です。それが完了するまで、公開サイトでは古い待機リストフォームが動作します。

この区別はビジネスを守ります。D1マイグレーションは本番データの形を変更します。Workerのデプロイは登録の動作を変更します。Cronはバックグラウンドでの変更処理を追加します。それぞれの手順に、明示的なリリース時間枠、検証、ロールバックの検討が必要です。

「secure」という言葉が付いているからといって、安全な待機リストを軽率にリリースしてはいけません。

検証で確認すること

本番対応の待機リストを提供するなら、ローンチ前に証拠が必要です。

リファレンス実装では150件のテストに合格しました。Astro checkではエラーが0件でした。本番ビルドも成功しました。作業範囲はwebのみだったため、既存のネイティブアプリの変更には手を加えていません。

それでも、その後のリリースチェックリストは重要です。

additiveなD1マイグレーションを意図的に適用する
リリース対象として決めた正確なWorkerバージョンをデプロイする
本番ドメインでTurnstileウィジェットが表示されることを確認する
管理下にあるメールアドレスを1件、本番フォームから送信する
専用送信者からSMTP配信されることを確認する
同一originのPOSTで確認する
同じトークンを2回目に使用し、失敗することを確認する
有効期限切れの確認待ちレコードが削除されることを確認する
管理者画面のデフォルト設定とCSVエクスポートで、verifiedの行が先に表示されることを確認する

これが「コードがコンパイルできる」と「登録ファネルがトラフィックを受け入れる準備ができている」の違いです。

スタートアップで役立つ場面

このパターンは、ベータが近いものの、完全なアカウントシステムを導入する準備はまだできていないチームに適しています。

モバイルアプリ、SaaSツール、非公開alpha、ゲート付きのAI機能、ハードウェアの予約リストをローンチしようとしているかもしれません。需要を取り込みたい一方で、招待を送り始める前にクリーンなデータと同意も必要です。

安全なCloudflare待機リストなら、大規模なバックエンドを追加せずにそれを実現できます。

リクエスト境界にWorkers
サーバー検証されたbot対策にTurnstile
verifiedの行と確認待ちを保存するD1
配信用の既存SMTP
不正利用を制御するレート制限とhoneypotチェック
データ契約に合った管理者向けフィルターとエクスポート
設定済みのインフラと本番での稼働動作を分けるリリースゲート

迅速にリリースできるほど小規模でありながら、信頼できるほど厳格です。

あなたのプロダクトに必要ですか?

このような登録フローを、プロダクトチーム向けに設計、セキュリティ強化、実装する支援ができます。

価値のある作業は、フォームにCAPTCHAを追加することではありません。登録が何を意味するのか、同意をどのように証明するのか、トークンをどこに保存するのか、メールをどのように配信するのか、管理者がデフォルトで何を見るのか、そして公開トラフィックが到達する前にリリースをどのように検証するのかを決めることです。

ベータリストがローンチ計画の一部になろうとしているなら、それを使って意思決定を行う前に、リストを信頼できるものにしておく価値があります。