第3章 グローバルDNS・エッジネットワーク(上級:Route 53・Cloudflare)
学習目標
- DNSの階層構造とRoute 53の主要レコード(
A、AAAA、CNAME、Alias、TXT、CAA)を区別し、ルートドメイン(Zone Apex)にCNAMEを使えない理由とAliasレコードによる解決策を説明する。 - Route 53のルーティングポリシー(シンプル、加重、レイテンシ、フェイルオーバー)とヘルスチェックを組み合わせ、カナリアデプロイと自動フェイルオーバーを設計する。
- 無停止でのドメイン・サーバー移行のために、切り替え時点よりも最低でも既存のTTL時間以上前にTTLをあらかじめ短くしておかなければならない原理を説明する。
- CloudflareのDNSのみ(灰色の雲)とプロキシ(オレンジ色の雲)モードの違いを理解し、SSL/TLSモードのうち
Flexibleがリダイレクトループや平文露出を招く理由と、Full (Strict)+ Origin CAの構成を説明する。 - WAF・Rate Limiting・Bot制御ルールを設計する際に、正常な決済・認証Webhookが遮断されないよう例外と署名検証を構成する。
- CDNキャッシュルールにおいて、パーソナライズされたAPI応答(
/api/*、Authorization、Set-Cookie)とLLMストリーミング(text/event-stream)のキャッシュ汚染およびバッファリング事故を予防する。 - Cloudflare Workers、Queues、そしてAI Gateway(可観測性、キャッシング、レート制限、マルチプロバイダーフォールバック)を結合し、回復力のあるAIエッジアーキテクチャを設計する。
はじめに
コードも完璧でデータベースも堅牢なのに、ユーザーの画面にはERR_TOO_MANY_REDIRECTS(リダイレクト回数の超過)が表示されたり、サーバーを新しいクラウドへ移したら半分のユーザーが6時間にわたってすでに終了した古いサーバーへ接続し続けたり、さらに恐ろしいことに、自分がログインしたのに他人のアカウントのプロフィールと会話履歴が自分の画面にそのまま見えてしまったりする事故が起きます。アプリケーションのコードをいくら調べてもバグはありません。犯人はコードの外側、すなわち**DNSとエッジネットワーク(CDN・リバースプロキシ)**の設定にいるからです。
ユーザーがアドレスバーにhttps://aidan.agentcat.appを入力した瞬間から、私たちのアプリケーションサーバーが最初の1バイトを返すまでに、リクエストはまず**権威DNS(Amazon Route 53、Cloudflare DNS)**でIPアドレスを調べ、**グローバルエッジプロキシ(Cloudflare)**でTLSハンドシェイク・WAF検査・キャッシュ照会・ワーカー実行を経たあと、ようやくオリジンサーバー(Origin)へと到達します。AIサービスではここにもう1つ経路が加わります。私たちのサーバーから再び外部のLLMプロバイダー(OpenAI、Anthropic、Google)へと出ていくトラフィックが、AI Gatewayを通って流れていくのです。
この章では、インターネットの電話帳であるRoute 53から、世界300以上の都市の玄関口で盾と加速器の役割を果たすCloudflareのプロキシ・セキュリティ・キャッシュ・サーバーレス・AIゲートウェイまで、上級エンジニアが必ず熟知しておくべき9つの重要な設計原理を扱います。
重要な概念
DNSの名前解決経路と主要レコード:なぜルートドメインにはCNAMEを使えないのか
ドメインネームシステム(DNS)は、人間にとって読みやすいドメイン(aidan.agentcat.app)を、コンピュータが通信できるIPアドレス(192.0.2.1または2001:db8::1)へと変換してくれる階層型の分散データベースです。ユーザーの端末(Stub Resolver)が通信事業者やパブリック再帰リゾルバ(Recursive Resolver、例:1.1.1.1、8.8.8.8)に尋ねると、再帰リゾルバはルート(.)ネームサーバー → トップレベルドメイン(.app)ネームサーバー → 権威ネームサーバー(Authoritative Nameserver、例:Route 53やCloudflare)の順にたどって最終的なレコードを受け取り、その結果を**TTL(Time To Live、秒単位の有効期間)**の間だけキャッシュに保存して再利用します。
最も頻繁に扱うDNSレコードの種類と用途は次のとおりです。
| レコード種別 | 格納する値 | 主な用途 | 設計時の注意点 |
|---|---|---|---|
A |
IPv4アドレス (203.0.113.10) |
ドメインを固定IPv4サーバーへ直接接続 | 対象サーバーのIPが変わったら手動で書き換える必要がある |
AAAA |
IPv6アドレス (2001:db8::10) |
ドメインをIPv6エンドポイントへ接続 | 現代のモバイル・クラウド網のためにAと併せて構成することを推奨 |
CNAME |
別のドメイン名 (cname.vercel-dns.com) |
サブドメイン(www.example.com)を別のドメインへエイリアス接続 |
ルートドメイン(Zone Apex、example.com)には標準規格上使用不可! |
Alias (Route 53) / CNAME Flattening (Cloudflare) |
AWSリソース(ALB、CloudFront、S3)または対象ドメイン | ルートドメインを動的IPエンドポイントへ接続 | クエリ時にネームサーバーが最終的なA/AAAA IPに展開して応答するため、ルートドメインにも使用可能 |
TXT |
任意のテキスト文字列 | ドメイン所有権の検証、メール送信認証(SPF、DKIM、DMARC) |
引用符・長さ制限と既存レコードの上書きに注意 |
CAA |
証明書の発行を許可する機関(letsencrypt.orgなど) |
承認されていない認証局(CA)が自ドメインのTLS証明書を誤発行するのを防止 | サブドメインが上位ドメインのCAAを継承するため、使用するすべてのCA(Vercel、Cloudflareなど)を登録しないと更新失敗が起きる |
ここで試験の定番として出題される最も重要なルールが、まさに**ルートドメイン(Zone Apex、例:example.com)におけるCNAME禁止ルール(RFC 1034 / RFC 2181)**です。
DNSの標準規格によれば、ある名前にCNAMEレコードが存在する場合、その名前には**他のいかなるレコードも同時に存在することはできません。ところがルートドメイン(example.com)には、そのドメインゾーン全体を定義する必須レコードであるSOA(Start of Authority)レコードとNS(Name Server)レコードが無条件に存在しなければなりません。**したがって、標準DNSにおいてはwww.example.com(サブドメイン)にはCNAMEを自由に使うことができますが、example.com(ルートドメイン)にCNAMEを入れた瞬間にゾーン(Zone)の規則が壊れてしまいます。
クラウドのロードバランサー(ALB)やCDN(CloudFront、Vercel)は固定IPの代わりにドメイン名しか提供してくれませんが、ルートドメインにCNAMEが使えないとしたら、どうやって接続すればよいのでしょうか。
- Amazon Route 53の
Aliasレコード:Route 53固有の拡張機能です。管理者は対象のALBやCloudFront、S3、あるいは同じホストゾーン内のレコードを指すようにAliasを設定しますが、外部のDNSリゾルバがexample.comのAレコードを尋ねてくると、**Route 53が内部で対象の現在のIPアドレスを引き当て、標準のA/AAAA応答として返します。**そのためDNS標準に一切違反することなくルートドメインに使用でき、さらにAWSリソースを指すAliasクエリにはRoute 53のクエリ料金も課金されません。 - CloudflareのCNAME Flattening(フラット化):ルートドメインに
CNAMEを入力すると、Cloudflareのネームサーバーがバックグラウンドで対象ドメインを最後まで追跡し、最終的なIP(A/AAAA)にフラット化して応答してくれます。
Route 53のルーティングポリシーとヘルスチェックによる無停止トラフィック制御
Route 53は単にドメインを1つのIPへ結びつけるだけでなく、トラフィックの比率・レイテンシ・サーバーの生存有無に応じて異なるエンドポイントへ応答を振り分ける**ルーティングポリシー(Routing Policy)**を提供しています。
| ルーティングポリシー | 動作方式 | 代表的な実務活用ケース |
|---|---|---|
| シンプル (Simple) | 1つのレコードに1つ以上のIPを入れ、ランダムに応答 | 単一環境のサービス、別途トラフィック制御が不要な場合(ヘルスチェックの直接連携は不可) |
| 加重 (Weighted) | 各レコードに重み(例:90対10)を付与し、比率どおりにトラフィックを分配 | カナリア(Canary)デプロイ、ブルーグリーン(Blue-Green)の段階的インフラ移行 |
| レイテンシ (Latency) | ユーザーの位置からネットワーク往復遅延(Latency)が最も低いAWSリージョンで応答 | ソウル(ap-northeast-2)とバージニア(us-east-1)にそれぞれアクティブサーバーを置いたグローバルサービス |
| フェイルオーバー (Failover) | 平常時はプライマリ(Primary)にのみ送り、ヘルスチェック失敗時にセカンダリ(Secondary)へ自動切り替え | アクティブ・パッシブ(Active-Passive)の災害復旧(DR)、メンテナンス案内ページへの自動切り替え |
| 位置情報 (Geolocation) | リクエスト送信者の国・大陸に応じて指定されたエンドポイントへ固定ルーティング | 国別のデータ主権・法規制の分離、地域専用の決済/コンテンツ提供 |
ここでの核心は、ルーティングポリシー自体は対象サーバーが生きているか死んでいるかを自動的には把握できないという点です。加重ルーティングやフェイルオーバールーティングが死んだサーバーへトラフィックを送らないようにするには、必ず**Route 53ヘルスチェック(Health Check)**を作成してレコードに紐づけ(Evaluate Target HealthまたはヘルスチェックIDの指定)なければなりません。
このとき、ヘルスチェック対象のエンドポイント(/api/health)をどのように実装するかも重要です。もし/api/healthがデータベースや外部APIを一切確認せず、無条件に200 OKという文字列だけを返す見せかけの検査(Shallow Check)だったとしたら、データベース接続が切れてすべての実リクエストが500エラーを吐き出していても、Route 53はサーバーが正常だと思い込んでトラフィックを送り続けてしまいます。反対に、ヘルスチェックのたびに重いLLM呼び出しを実行してしまうと、世界中のヘルスチェッカーが数秒おきに送ってくるリクエストのせいでコストが爆発します。したがってヘルスチェックは、ローカルプロセスの状態と中核の依存先(例:DBコネクションプールのSELECT 1)を軽く確認し、異常時には503 Service Unavailableを返すように設計しなければなりません。
無停止でのドメイン・サーバー移行とTTL(Time To Live)事前短縮の法則
サーバーやプラットフォームを移行するときに最も多く犯しがちなミスを見てみましょう。
あるチームが、既存サーバー(IP 198.51.100.10)のDNS AレコードのTTLを普段どおり**86,400秒(24時間)**にしたまま運用していました。日曜日の午前2時に新サーバー(IP 203.0.113.50)へ切り替えることにし、午前2時ちょうどにDNSコンソールへ入ってTTLを60秒に変えると同時にIPアドレスを新サーバーへ書き換え、午前2時10分に旧サーバーの電源を落としました。
結果はどうなったでしょうか。日曜日を通じて顧客の半数以上から「サイトにアクセスできない」という苦情が殺到しました。なぜ午前2時にTTLを60秒へ縮めたのに効果がなかったのでしょうか。
**すでに午前1時50分にクエリを終えていた世界中の通信事業者のDNSリゾルバ群は、旧サーバーのIP(198.51.100.10)を「これから24時間(86,400秒)の間は再度尋ねずにキャッシュから取り出して使え」という古いTTLと一緒に保存していたからです!**リゾルバは自分のキャッシュ有効期間が終わるまでは権威ネームサーバーを再訪することすらないため、私たちが午前2時にネームサーバー上で変更した新しいIPと60秒の新しいTTLは、リゾルバに伝わる機会すらありません。
したがって、無停止でのDNS切り替えの定石タイムラインは、必ず次の5段階の順序を守らなければなりません。
- 事前準備(切り替えの最低24〜48時間前、すなわち「既存のTTL」時間よりはるかに前):既存レコードのIPはそのままにした状態で、TTLだけを先に短い値(例:60秒〜300秒)へ引き下げます。
- 既存キャッシュの期限切れ待機:既存のTTLが24時間に設定されていたなら、最低でも24時間以上待ちます。この時間が経過すれば世界中のすべてのリゾルバの古いキャッシュが期限切れとなり、すべてのリゾルバが60〜300秒ごとに私たちのネームサーバーへ新しく尋ねてくる状態になります。
- 新規環境の準備および並行稼働:新サーバーを立ち上げ、旧サーバーと新サーバーの両方が正常にリクエストを処理できるように(同一DBを参照するなど)、2つの環境を同時に開いておきます。
- レコードの切り替え(Cutover):DNSレコードの値を新サーバーのIP(または新しい対象)に変更します。すでにTTLが60〜300秒に縮まっているため、最大でも1〜5分以内に世界中のトラフィックが新サーバーへと移ってきます。
- 観測後の旧サーバー終了およびTTLの復元:旧サーバーのアクセスログにこれ以上トラフィックが入ってきていないことを確認したあとに旧サーバーを停止し、DNSクエリ費用と遅延を減らすためにTTLを再び平常時の値(例:3,600秒)へと戻します。
Cloudflareプロキシ(オレンジ色の雲)対DNSのみ(灰色の雲)とオリジンIPの隠蔽
Cloudflareにドメインを登録すると、各DNSレコードの横に雲の形のスイッチがあります。このスイッチ1つがネットワーク経路全体を変えます。
| モード | 表示 | DNSクエリへの応答値 | トラフィック経路 | 動作する機能 |
|---|---|---|---|---|
| DNSのみ (DNS Only) | 灰色の雲 | オリジンサーバーの実際のIPアドレスまたは元のCNAME対象をそのまま応答 | ユーザー → オリジンサーバーへ直接接続 | 純粋なDNS名前解決のみを実行(WAF、CDNキャッシュ、Workers、DDoS L7防御は不作動) |
| プロキシ (Proxied) | オレンジ色の雲 | Cloudflareエニーキャスト(Anycast)エッジIPアドレスに置換して応答 | ユーザー → Cloudflareエッジ → オリジンサーバー | WAF、Rate Limiting、CDNキャッシング、SSL/TLS終端、Workers、AI Gateway、オリジンIP隠蔽がすべて動作 |
オレンジ色の雲(Proxied)を有効にする際に必ず知っておくべき実務上の落とし穴が2つあります。
- **外部サービスのCNAME検証や非HTTPポートは、灰色の雲(DNS Only)にしておかなければならない場合があります。**たとえば外部のメール配信サービス(DKIMのCNAME)や他プラットフォーム(Vercel、AWS ACM証明書検証のCNAMEなど)が「自分たちの方へCNAMEが正確に向けられているか」をDNSクエリで検証する際、オレンジ色の雲を有効にしていると、CloudflareがCNAMEを隠してCloudflareのIP(
A/AAAA)で応答してしまうため、相手側のプラットフォームが「CNAME設定が見つからない」として検証に失敗します。また、Cloudflareの基本プロキシは標準のHTTP/HTTPSポート(80、443など)のトラフィックしか中継しないため、通常のSSH(22)やDB(5432)ポートへオレンジ色の雲のドメインで直接接続しようとしてもつながりません(この場合は第4章のCloudflare TunnelやSpectrumを使います)。 - オレンジ色の雲を有効にしたからといって、オリジンサーバーのファイアウォールを全世界(
0.0.0.0/0)に開けたままにしておくと、WAFが無用の長物になります!攻撃者が過去のDNS履歴照会サイト(SecurityTrailsなど)や誤って露出したサブドメイン(direct.example.com)、あるいは全IPv4帯域スキャンによってオリジンサーバーの本当のIPアドレスを突き止めたあと、Cloudflareを経由せずにHost: app.example.comヘッダーを付けてオリジンIPへ直接リクエストを撃ち込めば、CloudflareのWAFやRate Limitingを100%バイパスできてしまいます。これを防ぐには、オリジンサーバーのファイアウォールでCloudflareの公開エッジIP帯域のみを許可するか、Authenticated Origin Pulls(mTLSクライアント証明書検証)またはCloudflare Tunnelでオリジンをロックしなければなりません。
SSL/TLS暗号化モード:なぜFlexibleは絶対に使ってはならず、Full (Strict)が標準なのか
Cloudflareプロキシ(オレンジ色の雲)を使うと、暗号化の区間が2つに分かれます。 第1の区間は**[ユーザーのブラウザ ↔ Cloudflareエッジ]であり、第2の区間は[Cloudflareエッジ ↔ 私たちのオリジンサーバー(Origin)]です。CloudflareのSSL/TLSモードは、まさにこの第2の区間(エッジ ↔ オリジンサーバー)**をどのように接続するかを決定します。
| SSL/TLSモード | ブラウザ ↔ Cloudflare | Cloudflare ↔ オリジンサーバー | 致命的な問題点または特徴 |
|---|---|---|---|
| Off | 平文HTTP | 平文HTTP | 全区間で暗号化なし(使用禁止) |
| Flexible | HTTPS暗号化 | 平文HTTP(ポート80) | 1) エッジ〜オリジン区間が平文のため盗聴に露出<br>2) オリジンサーバーでHTTPSリダイレクトが有効になっていると無限リダイレクトループ(ERR_TOO_MANY_REDIRECTS)が発生! |
| Full | HTTPS暗号化 | HTTPS暗号化(証明書は未検証) | オリジン証明書が期限切れや偽の自己署名(Self-signed)であっても無条件に信用するため、中間者攻撃(MITM)に脆弱 |
| Full (Strict) | HTTPS暗号化 | HTTPS + 有効なCAまたはCloudflare Origin CA証明書を厳格に検証 | **唯一の本番環境推奨標準。**全区間の暗号化およびオリジンサーバーの身元検証を保証 |
ここで実務でも試験でも最も有名な障害シナリオが、**Flexibleモードが引き起こす無限リダイレクトループ(ERR_TOO_MANY_REDIRECTS)**です。
なぜこのようなことが起きるのでしょうか。
- ユーザーがブラウザから
https://app.example.comへアクセスします。 - Cloudflareは
Flexibleモードであるため、オリジンサーバー(Vercel、Nginx、ALBなど)には**平文のhttp://app.example.com(ポート80、X-Forwarded-Proto: http)**に変換してリクエストを送ります。 - ところが現代的なオリジンサーバーやWebフレームワークはセキュリティのため、「おや、平文のHTTPでリクエストが入ってきたぞ。
https://app.example.comへアクセスし直してくれ!」として**301/308 Redirect to https://app.example.com**という応答を返します。 - ブラウザは言われたとおり再び
https://app.example.comをリクエストし、Cloudflareはまたオリジンへhttp://で送り、オリジンはまたhttps://へリダイレクトさせるという無限の堂々巡りが続いたあげく、ブラウザがERR_TOO_MANY_REDIRECTSエラーを出して停止してしまうのです!
したがって解決策は明確です。Flexibleモードは絶対に使わず、必ずFull (Strict)モードを使用しなければなりません。オリジンサーバーで公的証明書(Let's Encryptなど)を自動更新するのが手間である場合は、Cloudflareが無料で発行してくれるCloudflare Origin CA証明書(最大15年間有効、Cloudflareエッジとオリジンサーバーの区間専用)をオリジンサーバーやALBにインストールしてFull (Strict)を有効にすれば、一度で解決します。
WAF・Rate Limiting・Bot制御と正常なWebhookの保護
Cloudflareエッジでは、リクエストがオリジンサーバーへ届く前に悪性トラフィックをふるい落とす3重の防護壁を運用します。
- WAFマネージドルール(Managed Rules):SQLインジェクション、XSS、Log4Shell、最新フレームワークのCVE攻撃パターンを自動的に遮断します。
- レート制限(Rate Limiting Rules):特定のIP、ユーザーセッション、またはAPIキーが短時間のうちに異常に多くのリクエスト(例:ログイン総当たり攻撃で
/api/auth/loginが毎分10回超過、高コストなAI生成API/api/chatが毎分20回超過)を送ってきた場合、429 Too Many Requestsで遮断します。このときNAT環境(社内オフィス、大学、通信事業者ゲートウェイ)では数百人の正常なユーザーが同じグローバルIPを共有しているため、機密性の高いAPIのレート制限は単純なIP単独基準よりも、セッションCookie・認証トークン・複合キーをあわせて考慮し、誤遮断を減らします。 - Bot制御(Bot Fight Mode / Super Bot Fight Mode):自動化されたスクレイパーやクローラーに対してJSチャレンジやTurnstile CAPTCHAを提示します。
ここで頻繁に起きる実務事故は、Bot Fight Modeや過度なWAFルールが、外部の決済事業者(Toss、Stripe、Lemon Squeezy)やGitHub、Slackから送られてくる正常なサーバー間Webhookリクエストまで「ボット」と判定してJSチャレンジ(HTML画面)を返してしまい、決済処理が欠落する事故です!外部のWebhookサーバーはブラウザではないため、JavaScriptチャレンジやCAPTCHAを解くことができません。
したがって、Webhookエンドポイント(例:/api/payments/webhook)を保護するときは次のように設計します。
/api/payments/webhookパスにはブラウザ向けのインタラクティブチャレンジ(JS Challenge / Managed Challenge)がかからないようWAFのカスタムルールを構成しつつ、セキュリティ検査全体をむやみにすべてオフにはしません。- その代わりに、アプリケーション(またはエッジワーカー)のコード内で、Webhook送信元が送ってきた暗号化HMAC署名ヘッダー(例:
X-Signature、Stripe-Signature)とタイムスタンプを秘密鍵で厳格に検証し、偽造されたリクエストを拒否します。
CDNキャッシュルールと動的API・ストリーミングのキャッシュ汚染防止
CDNキャッシングは、静的アセット(/static/*、フォント、公開画像)の応答速度を高め、オリジンサーバーの負荷を減らしてくれる最大の功労者です。しかし、キャッシュルール(Cache Rules)を誤って触り、動的な応答をキャッシュしてしまった瞬間、インフラ史上最も恐ろしい個人情報流出事故である「キャッシュ汚染(Cache Poisoning / Web Cache Deception)」が発生します。
もし管理者がオリジンサーバーの負担を減らそうとして、CloudflareのCache RuleでURI Path starts with /api/またはサイト全体(*)に対して**Cache Everything(すべてをキャッシュ)およびIgnore Cache-Control(オリジンヘッダーの無視)**を有効にしたと想像してみましょう。
- 最初に顧客A(ホン・ギルドン)がログインした状態で
/api/me(またはサーバーサイドレンダリングされた/dashboard)を呼び出します。 - オリジンサーバーは、顧客Aの名前、メールアドレス、直近のAI相談履歴、さらには応答ヘッダーの
Set-Cookie: session=hong_secretまで詰めて応答します。 - Cloudflareのエッジノードが、この応答を
/api/meというキャッシュキー(Cache Key)にそのまま保存してしまいます! - 1秒後、赤の他人である顧客B(キム・チョルス、さらには未ログインのユーザー)が
/api/meにアクセスすると、Cloudflareはオリジンサーバーへ尋ねることすらなく、キャッシュに入っていた顧客Aの個人情報と顧客AのセッションCookieを顧客Bへそのまま返してしまうのです!
したがって、AI・Webサービスのキャッシュ設計においては、次の4つの鉄則を命がけで守らなければなりません。
| 対象トラフィック | 正しいキャッシュ設計 (Cloudflare + Origin) | 誤って設定したときの結果 |
|---|---|---|
ユーザー別パーソナライズAPI(/api/*)、認証確認、カート、マイページ情報 |
Cloudflare Cache Rule:Bypass Cache(キャッシュバイパス) + オリジン応答ヘッダー:Cache-Control: private, no-store |
他人に自分のアカウント情報とセッションCookieが露出する |
AuthorizationヘッダーやセッションCookieによって変わるページ |
キャッシュをバイパス(Bypass)するか、やむを得ずキャッシュする場合はキャッシュキーの分離およびVaryヘッダーを厳格に適用(Set-Cookieを含む応答は共有キャッシュ絶対禁止) |
最初の訪問者の画面が後続のすべての訪問者に複製される |
LLMリアルタイムストリーミング応答(Content-Type: text/event-stream、SSE) |
Bypass Cache + 応答バッファリング無効化(Cache-Control: no-cache, no-transform、X-Accel-Buffering: no) |
エッジがストリーム終了まで30秒間チャンクを溜め込んでから一括で返すため、リアルタイムのタイピング効果が壊れてタイムアウトが発生する |
ハッシュが付いた不変の静的バンドル(/_next/static/*、/assets/*.a1b2c3.js) |
Cache-Control: public, max-age=31536000, immutableによってエッジとブラウザに長期キャッシュ |
毎回オリジンサーバーからバンドルを再ダウンロードして速度低下および帯域幅の浪費を招く |
Cloudflare WorkersとQueues:エッジコンピューティングと非同期ジョブの分離
Cloudflareは、世界中のエッジノードで軽量なV8 Isolateベースで即座に実行されるサーバーレスランタイムであるCloudflare Workersと、非同期メッセージブローカーであるCloudflare Queuesを提供しています。
- Cloudflare Workers:重い仮想マシンやコンテナを立ち上げる代わりに、V8エンジンの隔離空間(Isolate)だけを数ミリ秒で生成するため、**コールドスタートが事実上0msに近くなります。**ユーザーに最も近いエッジでJWT署名を一次検証して無効なリクエストをオリジンサーバー到達前に弾いたり、国コードヘッダー(
CF-IPCountry)に応じて決済通貨・言語をルーティングしたり、静的な応答ヘッダー(セキュリティヘッダーStrict-Transport-Security、Content-Security-Policy)を注入したりといった軽量なゲートウェイ処理に理想的です。ただし、WorkersはCPU演算時間の制限が厳しく、単一の中央データベースが遠く離れている場合(第1章で見たRTT問題)は、重い多重DBトランザクションよりもエッジルーティング・検証・キャッシュの組み合わせやSmart Placementに合わせて使うべきです。 - Cloudflare Queues:AIサービスでは、ユーザーがリクエストを送ったときにその場で1秒以内に答えを返せない重い後処理ジョブが数多く存在します(例:100ページのPDFの埋め込み生成、大量の通知メール送信、外部Webhook受信後の複雑な精算処理)。これをユーザーのHTTPリクエストの中で同期的に処理すると、タイムアウトが起きたり、外部APIの障害がそのままユーザーのエラーにつながったりします。このとき、リクエストを受け取ったフロントのWorker(Producer)はQueuesにジョブメッセージだけを入れて即座に
202 Acceptedを返し、背後のConsumer Workerがバッチ(Batch)単位でメッセージを取り出して処理するように分離すれば、トラフィックの急増を緩衝(Buffering)できます。一時的な失敗時には自動リトライ(Retry with backoff)を実行し、最後まで失敗したメッセージは**デッドレターキュー(Dead Letter Queue, DLQ)**へ別途集めて、消失させることなく原因を分析して再処理することができます。
Cloudflare AI Gateway:LLMトラフィックの観測・キャッシング・レート制限・フォールバック
私たちのアプリケーションがOpenAI、Anthropic、Google Geminiといった外部のLLM APIを直接呼び出すとき、運用上の最大の悩みは何でしょうか。
- 複数のサービスやエージェントが銘々にAPIを呼び出すため、どの機能でトークンとコストがどれだけ消費されているのか、遅延時間(TTFT)とエラー率がどれくらいなのかをひと目で把握できません。
- まったく同じシステムプロンプトとまったく同じ質問が何百回も繰り返されているのに、毎回LLM料金を払って何秒も待たされます。
- 特定のLLMベンダー(例:OpenAI)に一時的な障害(
502/503)やレート制限(429)が発生すると、私たちのサービス全体がそのまま止まってしまいます。
Cloudflare AI Gatewayは、アプリケーションコードとLLMプロバイダーAPIの間に位置するLLM専用のプロキシゲートウェイです。既存のSDKでAPIのベースURL(baseURL)をAI Gatewayのアドレスに変えるだけで、コードをほとんど書き換えることなく5つの強力なインフラ統制を手に入れることができます。
| AI Gatewayの主要機能 | 動作原理と運用効果 |
|---|---|
| 統合可観測性 (Analytics & Logging) | プロバイダーが異なっていても、リクエスト数、入出力トークン数、推定コスト、遅延時間、エラーコード(429/5xx)を単一のダッシュボードで追跡 |
| セマンティック・完全一致キャッシング (Caching) | 同一のプロンプト・パラメータのリクエストが再び入ってきたら、LLMを呼び出さずにエッジキャッシュから即座に応答を返す(コスト0円、遅延数十ms)。ただしユーザー別の機密データが混ざったリクエストはキャッシュ除外設定が必須 |
| レート制限と予算統制 (Rate Limiting) | エージェントループの暴走や異常トラフィックが時間あたりの所定リクエスト数を超えた場合、LLMプロバイダーに届く前にゲートウェイで遮断 |
| 自動リトライとモデル・ベンダーフォールバック (Universal Endpoint / Fallbacks) | プライマリモデル(例:Anthropic Claude)が5xx障害やタイムアウトを出したら、設定されたポリシーに従って自動リトライするか、予備モデル(例:OpenAI GPTまたはGoogle Gemini)へ即座に迂回(Fallback)してサービスの継続性を維持 |
| キー管理および中央認証 (BYOK / Authenticated Gateway) | ゲートウェイへのアクセス自体に認証トークン(cf-aig-authorization)を強制し、承認されたバックエンドだけがゲートウェイを通過できるよう保護 |
さらに深く
無停止ブルーグリーンインフラ移行におけるDNS加重ルーティングとエッジルーティングの違い
大規模なアーキテクチャ改編によって、トラフィックの5%だけをまず新インフラ(Green)へ送り、95%は既存インフラ(Blue)に残すカナリア移行を行うとき、**Route 53の加重ルーティング(DNSレイヤー)とCloudflare Workers / Load Balancing(HTTPエッジレイヤー)**のどちらを使うべきでしょうか。2つの方式には、切り替え速度とロールバック(Rollback)時間において決定的な違いがあります。
| 比較基準 | Route 53加重ルーティング(DNSレイヤー) | Cloudflareエッジルーティング(HTTPプロキシレイヤー) |
|---|---|---|
| 分配単位 | DNSリゾルバのキャッシュクエリ単位(1つの通信事業者リゾルバ配下の数万人が一斉に同じIPを受け取る可能性がある) | 個別のHTTPリクエストまたは個別のユーザーCookie/セッション単位(正確に5.0%のリクエストだけを分配可能) |
| 緊急ロールバック速度 | 重みを0に変えても、**DNS TTLおよびクライアントDNSキャッシュが期限切れになるまで(数分〜数十分)**一部のトラフィックが流入し続ける |
エッジ設定の変更直後、1〜2秒以内に世界中のすべての後続HTTPリクエストが100%既存サーバーへと切り替わる |
| セッション固定 (Stickiness) | リゾルバが再クエリした際に別のIPを受け取ると、ユーザーの接続先サーバーが変わってしまうことがある | CookieやユーザーIDハッシュを基準に、同じユーザーは常に同じ環境へ固定可能 |
| 適した状況 | 異なるクラウド・CDN事業者間のマクロな移行、非HTTPプロトコルを含む移行 | Web・APIサービスの精密なカナリアテスト、即座の1秒ロールバックが必要なデプロイ |
したがって、2つの方式を相互排他的なものとして見る必要はありません。平常時はRoute 53とCloudflareを併用しつつ、アプリケーションのバージョンやオリジンサーバープール間の細やかなカナリア分配と即座のサーキットブレーキングはHTTPヘッダーやCookieを見ることができるエッジプロキシレイヤーで実行し、リージョン全体やCDN事業者自体を移すマクロな災害復旧にはDNSルーティングポリシー(事前に低いTTLを維持)を使うのが、最も堅牢な多層構造です。
オリジンサーバー直接露出(Origin IP Leak)の経路と完全なオリジンロックダウン(Origin Lockdown)
Cloudflare WAFに毎月数十万円を投じて完璧な遮断ルールを築き上げていたとしても、攻撃者がオリジンサーバーのIPやオリジンプラットフォームのアドレス(例:my-app.vercel.app、またはAWS ALBのデフォルト*.elb.amazonaws.comアドレス)へ直接リクエストを送ることができるなら、WAFは張り子の虎にすぎません。
実務においてオリジンのアドレスが漏れ出す経路は、驚くほど多様です。
- Cloudflareを導入する前まで使っていた旧IPが、過去のDNS履歴データベースに残っている場合。
- メールサーバー(
MX、mail.example.com)や開発サーバー(dev.example.com)を同じサーバーに置き、そのレコードだけを灰色の雲(DNS Only)で開けてある場合。 - アプリケーションのパスワードリセットメール送信や画像ダウンロード機能(SSRF)が外部サーバーへ直接アウトバウンドリクエストを送り、オリジンサーバーのグローバルIPをさらけ出してしまう場合。
- Vercelのデフォルトデプロイドメイン(
aidan-mu.vercel.app)が、保護やリダイレクトなしにそのまま開いている場合。
したがって、真のエッジセキュリティは**「Cloudflare(または指定されたプロキシ)を経由していないリクエストはオリジンが最初から拒否する」というオリジンロックダウン(Origin Lockdown)**が完成して初めて完結します。
- ネットワークファイアウォールレベル:オリジンのセキュリティグループ(Security Group)のインバウンド443番ポートを、
0.0.0.0/0からCloudflareの公開IPv4/IPv6リストのみに絞るか、あるいはインバウンドポートをすべて閉じてCloudflare Tunnel(第4章)でのみ接続します。 - TLS相互認証レベル(Authenticated Origin Pulls、mTLS):攻撃者が別のCloudflare無料アカウントを作って自分のドメインのオリジンIPに私たちのサーバーIPを指定し、Cloudflare IP帯域チェックをすり抜けることまで防ぐには、ゾーン別(Per-Zone)またはカスタムクライアント証明書によるAuthenticated Origin Pullsを有効にし、「私たちのCloudflareアカウントのゾーン」が提示するTLSクライアント証明書があるときだけオリジンが応答するように作ります。
- プラットフォームドメインレベル:マネージドプラットフォーム(Vercelなど)をオリジンとして使うときは、デフォルトの
.vercel.appアドレスへ入ってきたリクエストを正式な本番ドメイン(https://aidan.agentcat.app)へ308 Permanent Redirectさせるか、デプロイ保護および署名付きカスタムヘッダー検証によって迂回侵入を遮断します。
実務の場面
ビョルムリコマース:Cloudflare導入当日に起きた無限リダイレクトとカートキャッシュ汚染
オーダーメイドのギフト推薦AIショッピングモール「ビョルムリコマース」は、ブラックフライデーのトラフィック急増と海外からのボット攻撃に備え、既存のAWS ALBの手前にCloudflareを配置することにした。担当エンジニアは金曜日の夕方にドメインのネームサーバーをCloudflareへ変更し、2つの設定を有効にした。第1に、オリジン側の設定に触るのが面倒だったため、SSL/TLSモードをFlexibleにした。第2に、サーバー負荷を劇的に減らそうと、すべてのパス(*)に対してCache Level: Cache Everythingルールを追加した。
切り替えから5分後、サイト全体が麻痺した。まず、アクセスした顧客の半数はブラウザにERR_TOO_MANY_REDIRECTSエラーが表示され、トップ画面すら開けなくなった。AWS ALBに設定されていた「HTTP(80)リクエストをHTTPS(443)へリダイレクトせよ」というルールと、CloudflareのFlexibleモード(エッジ→オリジンをHTTP 80で転送)が衝突し、無限リダイレクトループに陥ったのである。
慌ててALBのHTTPリダイレクトをオフにするとサイトは開いたが、10分後にはるかに恐ろしい第2の事故が起きた。カスタマーセンターへ「自分のカートと配送先住所録に、見ず知らずの他人の名前と電話番号、AIギフト相談の履歴が入っている!」という通報が殺到したのである。Cache Everythingルールのせいで、最初にログインした顧客が呼び出した/api/cartと/api/chat/historyのJSON応答がCloudflareエッジに丸ごとキャッシュされ、続いてアクセスした他の顧客たちへそのまま配信された典型的なキャッシュ汚染事故だった。さらに、AIギフト相談のリアルタイムストリーミング(/api/chat/stream)も1文字ずつ表示されず、20秒間止まったあげく一気に出力される状態になっていた。
緊急投入されたインフラアーキテクトは、15分のうちに次の措置を順番に実行して事態を収拾した。
- 即座のキャッシュ全削除(Purge Everything)および動的パスのバイパス:Cloudflareのキャッシュを全量パージ(Purge)し、汚染された個人情報の応答を即座に消去した。続いてCache Ruleを全面修正し、
/api/*、/auth/*、/checkout/*、およびCookieやAuthorizationヘッダーが含まれるリクエストは無条件に**Bypass Cache**となるよう最優先順位で固定した。オリジンサーバー側でもすべてのパーソナライズ応答にCache-Control: private, no-storeヘッダーを強制し、SSEストリーミング応答にはContent-Type: text/event-streamとCache-Control: no-cache, no-transformを明示した。 Full (Strict)への切り替えとオリジン保護:ALBには正常なACM証明書がすでに設定されていたため、CloudflareのSSL/TLSモードを直ちに**Full (Strict)**へ変更し、ALBのHTTPSリダイレクトを復旧させた。無限ループが消え、全区間が安全に暗号化された。- 事後措置:キャッシュ汚染が起きていた12分間のアクセスログを全件照合し、他人の配送先情報が露出した可能性のあるセッション18件を特定したうえで、セキュリティチームおよび個人情報保護責任者とともにセッションの強制失効と法的通知の手順を踏んだ。
ナレAIラボ:OpenAIの障害でも止まらなかったAI Gatewayフォールバックと事前TTL短縮移行
企業向けの議事録要約サービスを運用する「ナレAIラボ」は、2つの大きな課題を控えていた。1つは既存の他社DNSからAmazon Route 53へ権威ネームサーバーとAPIエンドポイントを無停止で移行することであり、もう1つは単一のLLMベンダーに障害が起きるたびに議事録要約全体が止まってしまう単一障害点(SPOF)をなくすことだった。
チームはまずドメイン移行のため、切り替え予定日よりも3日(72時間)前の木曜日の午前に、既存DNSのすべてのレコードのTTL(既存は36,000秒=10時間)を60秒へと引き下げておいた。十分な待機時間を経て世界中のリゾルバが60秒周期でクエリする状態になった日曜日の未明、Route 53のホストゾーンにて、ルートドメイン(narae.ai)はAliasレコードで、APIサブドメイン(api.narae.ai)はヘルスチェックが紐づいたフェイルオーバー(Failover)レコードで構成して切り替えた。事前のTTL短縮のおかげで、旧サーバーへの取りこぼしは1件もなく2分で切り替えが完了し、安定化を確認したあとにTTLを再び3,600秒へと戻した。
続いてLLMの呼び出し経路には、Cloudflare AI GatewayとQueuesを導入した。
| 区間の問題 | 既存の構造 | 改善されたエッジ・ゲートウェイ構造 |
|---|---|---|
| 音声文字起こし完了後の長い要約リクエスト | Webhook内で同期的にLLMを直接呼び出し、タイムアウトおよびリトライ消失が頻発 | 文字起こし完了WebhookはHMAC署名検証後にCloudflare Queuesへジョブ登録のみを行い(202 Accepted) → Consumerがバッチ処理し、失敗時はDLQへ保管 |
| 特定LLMプロバイダーの一時障害 (503/429) | OpenAIの障害時に要約サービス全体が失敗 | AI Gateway Universal Endpointを構成:第1優先モデルを呼び出しつつ、連続5xx/タイムアウト発生時は自動的に第2優先の代替プロバイダー(Anthropic Claude)へ即座にフォールバック |
| 繰り返される標準テンプレート分類の呼び出し | 毎回有料トークンを消費し、1.5秒の遅延が発生 | 公開テンプレート分類のように個人情報を含まない決定論的プロンプトにのみ**AI Gatewayキャッシング(TTL 1時間)**を有効化し、トークン費用を38%削減 |
2か月後、実際にプライマリLLMプロバイダーで40分間のグローバルAPI障害が発生したが、ナレAIラボの要約パイプラインはAI Gatewayが2秒で代替モデルへトラフィックを自動迂回させたおかげで、顧客からの問い合わせ0件のまま障害時間帯を乗り切った。
間違えやすいポイント
- **「ルートドメイン(
example.com)にもサブドメインと同じように標準のCNAMEレコードをそのまま入れればよい。」**DNS標準上、ルートドメイン(Zone Apex)にはSOAレコードとNSレコードが一緒に存在しなければならないため、他のレコードと共存できない標準のCNAMEは使えません。Route 53のAliasレコードやCloudflareのCNAME Flatteningを使わなければなりません。 - **「サーバー移行の当日にDNSレコードのIPを変えながらその場でTTLも60秒に縮めれば、世界中へ60秒で反映される。」**すでに以前のクエリを終えているDNSリゾルバ群は、変更前の古いTTL時間の間、旧IPをキャッシュに握ったまま再クエリを行いません。必ず切り替え時点よりも最低「既存のTTL時間」以上前にあらかじめTTLを下げて待つ必要があります。
- 「オリジンサーバーにSSL証明書をインストールするのが面倒だから、CloudflareのSSLモードを
Flexibleにしておけば安全で便利である。」FlexibleはCloudflareとオリジンサーバーの間を平文HTTP(80)で接続するだけでなく、オリジンサーバー側でHTTPS強制リダイレクトが有効になっているとERR_TOO_MANY_REDIRECTS無限ループ障害を引き起こします。必ずオリジン証明書(Origin CAなど)をインストールしてFull (Strict)を使わなければなりません。 - **「Cloudflareのオレンジ色の雲(Proxied)を有効にしたから、オリジンサーバーのセキュリティグループは
0.0.0.0/0で開けておいても誰も直接入ってこられない。」**オレンジ色の雲はDNSの応答をCloudflareのIPに変えるだけです。オリジンサーバーの実際のIPが露出していれば、攻撃者がIPへ直接リクエストを送ってWAFをバイパスできるため、オリジンファイアウォール制限・Authenticated Origin Pulls(mTLS)・Cloudflare Tunnelなどでオリジンをロックしなければなりません。 - **「サーバー負荷を減らすには、
/api/*パスにもCDNのCache Everythingを有効にするのがよい。」**ユーザーごとに応答が異なるAPIやSet-Cookie/Authorizationがやり取りされるパスを共有CDNにキャッシュすると、最初のユーザーの個人情報とセッションが他のユーザーへそのまま露出する重大なセキュリティ事故が起きます。パーソナライズAPIとSSEストリーミングは必ずキャッシュをバイパス(Bypass)しなければなりません。 - **「外部プラットフォームのドメイン所有権確認用CNAMEレコードも、セキュリティのためにオレンジ色の雲(Proxied)を有効にしておくべきである。」**オレンジ色の雲を有効にすると、CloudflareがCNAMEの代わりに自身の
A/AAAAIPで応答するため、相手側のプラットフォームがCNAMEの対象文字列を確認できず、ドメイン認証や証明書発行が失敗します。検証用のCNAMEは灰色の雲(DNS Only)にしておかなければなりません。
ひと目でわかるまとめ
| 重要テーマ | 試験と実務で覚えておくべき重要文 |
|---|---|
| Zone ApexとAlias | ルートドメイン(example.com)には標準のCNAMEを使えないため、Route 53のAliasまたはCloudflareのCNAME Flatteningを使う |
| ルーティングポリシーとヘルスチェック | 加重(カナリア)・レイテンシ・フェイルオーバー(DR)ルーティングが死んだサーバーを避けるには、必ず依存先を確認するヘルスチェックを紐づけなければならない |
| 無停止移行とTTL | 切り替え時点よりも最低でも既存のTTL時間以上前にあらかじめTTLを60〜300秒へ下げて既存キャッシュを空にしてからIPを切り替える |
| オレンジ色の雲 vs 灰色の雲 | オレンジ色の雲(Proxied)はCloudflareエッジ(WAF・CDN・Workers)を経由し、灰色の雲(DNS Only)はオリジンIP/CNAMEをそのまま露出する |
SSL/TLS Full (Strict) |
Flexibleは平文区間と無限リダイレクトループを引き起こす。必ずオリジン証明書(Origin CAなど)と**Full (Strict)**を使う |
| オリジンロックダウン (Origin Lockdown) | 攻撃者によるWAFバイパス直接接続を防ぐため、Cloudflare IP許可リスト、Authenticated Origin Pulls(mTLS)、またはTunnelを適用する |
| WebhookとWAF/Bot制御 | 決済・GitHubなどのサーバー間Webhook経路がJSチャレンジに阻まれないよう例外を設け、アプリ側でHMAC署名検証により完全性を確認する |
| キャッシュ汚染・バッファリング防止 | パーソナライズ/api/*(Authorization、Set-Cookie)はBypass Cache + private, no-store、LLMのSSE(text/event-stream)はバッファリング・キャッシュを切る |
| Workers・Queues・AI Gateway | Workersはエッジ超低遅延検証/ルーティング、Queuesは非同期緩衝とDLQ、AI GatewayはLLM観測・レート制限・マルチベンダー自動フォールバックを担う |
公式ドキュメントで確認する
- AWS Route 53 — Choosing between alias and non-alias records:ルートドメインの制約と
Alias対CNAMEの比較。 - AWS Route 53 — Choosing a routing policy & Health Checks:シンプル、加重、レイテンシ、フェイルオーバールーティングとヘルスチェックの連動。
- Cloudflare — Proxy status (Orange vs Grey Cloud):プロキシの動作方式とCNAME検証時の注意点。
- Cloudflare — SSL/TLS Encryption modes (
Full (Strict)) & Origin CA:Flexibleの危険性、リダイレクトループの原因とFull (Strict)の構成。 - Cloudflare — Cache Rules & Preventing Cache Poisoning:動的コンテンツのキャッシュバイパス(
Bypass)とキャッシュキーの設計。 - Cloudflare — AI Gateway Documentation:LLM統合ロギング、キャッシング、レート制限、Universal Endpointフォールバックルーティング。
セルフチェック
3-1. DNS標準において、サブドメイン(www.example.com)にはCNAMEレコードを使えるがルートドメイン(Zone Apex、example.com)にはCNAMEを使えない理由を説明し、Route 53でルートドメインをAWS ALBに接続するときに使う解決策を書きなさい。
3-2. 既存のTTLが86,400秒(24時間)であるドメインのサーバーIPを無停止で移行しようとするとき、なぜ移行作業の当日ではなく最低24時間以上前にあらかじめTTLを60〜300秒へ引き下げておかなければならないのか、再帰DNSリゾルバのキャッシュ動作原理から説明しなさい。
3-3. オリジンWebサーバーで「平文HTTPリクエストが来たらHTTPSへ301リダイレクトする」という設定が有効になっているとき、CloudflareのSSL/TLS暗号化モードをFlexibleに設定するとユーザーのブラウザでどのようなエラーがなぜ発生するのかを説明し、正しいSSL/TLSモードを書きなさい。
3-4. Cloudflareでドメインにオレンジ色の雲(Proxied)を有効にしてWAFルールを完璧に設定していても、攻撃者がオリジンサーバーの実際のIPアドレスを突き止めたらどのようにWAFをバイパスできるかを説明し、これをオリジンサーバー側で遮断する方法を2つ以上書きなさい。
3-5. パーソナライズされたユーザー情報を返す/api/profileエンドポイントと、LLMのリアルタイムストリーミングを返す/api/chat/stream(text/event-stream)エンドポイントに対して、CDNで無分別なキャッシングおよび応答バッファリングを有効にしたときにそれぞれどのような事故が発生するかを書き、正しいCache-Controlおよびキャッシュルールを示しなさい。
3-6. 設計課題:単一のLLM API(例:OpenAI)に依存していた顧客相談要約サービスが、プロバイダーの一時的な503障害とエージェントループによる時間あたりの呼び出し急増のせいで頻繁に停止している。Cloudflare AI Gatewayを導入してこの2つの問題をどのように解決できるか、主要な機能を3つ挙げて説明しなさい。
実習課題
実習
無停止ドメイン移行タイムラインとRoute 53・Cloudflareレコード設計表を作成する(45分)
- 現在他社DNSでTTL 43,200秒(12時間)で運用中の
service.krドメイン全体を、Route 53およびCloudflareベースの新規インフラへ日曜日の午前03:00に無停止移行する時間帯別ランブック(D-2日、D-Day 02:30、03:00、03:30、D+1日)を作成する。 - 次の5つのレコードについて、(ア)レコード種別(
A/AAAA/CNAME/Alias/TXT/CAA)、(イ)Cloudflareプロキシ状態(オレンジ色の雲 vs 灰色の雲)とその理由を表に整理する:- ルートWebドメイン
service.kr - APIドメイン
api.service.kr - 外部メール配信用のDKIM検証
s1._domainkey.service.kr(CNAME) - 証明書発行機関の制限設定
service.kr(CAA) - 社内専用SSHゲートウェイ
ssh.service.kr
- ルートWebドメイン
完了基準: TTL短縮時点が切り替え時刻より最低12時間以上前に設定されており、ルートドメインの処理と外部CNAME検証レコードを灰色の雲(DNS Only)にする理由が正確に説明されていること。
実習
エッジセキュリティ・キャッシュ・AI Gatewayアーキテクチャ点検表を作成する(50分)
- Cloudflareの背後に置かれたAI Webアプリケーションの5大パス(
/_next/static/*、/、/api/user/me、/api/payments/webhook、/api/ai/stream)を表の行として書き出す。 - 各パスについて、(ア)キャッシュポリシー(
Cache EverythingvsBypass Cache)、(イ)オリジンのCache-Controlヘッダー値、(ウ)WAF/BotチャレンジおよびRate Limitingの適用方式、(エ)追加の検証手段(セッション検証、WebhookのHMAC署名検証など)を埋める。 /api/ai/streamの内部から外部LLMを呼び出す際、Cloudflare AI GatewayのUniversal Endpointフォールバック構成を擬似コード(またはJSON配列)で記述し、第1優先モデルの失敗時に第2優先の別ベンダーモデルへ切り替わるフローを定義する。
完了基準: パーソナライズAPIとWebhook、SSEストリーミングが共有キャッシュから完全に除外(Bypass)されており、WebhookがJSチャレンジに阻まれずにHMACで保護され、AI Gatewayの異種プロバイダーフォールバックが明記されていること。