Cloudflare Gateway の Forward アクション: 社内の HTTP 通信に自分の Worker を挟む(DLP の検出も Worker で検証できる)
Gateway の HTTP ポリシーに「Forward」アクションが追加され(2026-10-15 公開ベータ、全 Zero Trust プラン)、条件に合った通信で自分の Worker を呼べるようになった。プロキシを別に立てずに、ヘッダー書き換え・注意喚起ページ・Slack 通知・R2 への記録などができる。
どんなときに使う?
- 特定の社内 SaaS へのアクセスだけ、リクエストやレスポンスに手を入れたいとき(ヘッダー追加、コーチングページの表示など)
- 「誰が・どの端末で」アクセスしたかを見て、アプリ固有のルールで止めたいとき(ID と端末ポスチャを Worker から読める)
- アクセスをきっかけに裏で処理を走らせたいとき(Slack 通知、R2 に証跡を保存)
仕組み
- Gateway は HTTP リクエストポリシー → Forward ポリシー → ボディのポリシーと検査 の順に評価し、最初に一致した Forward ポリシーの Worker を呼ぶ。Block に当たった通信では Worker は呼ばれない
- Worker 側は
fetch()ハンドラーではなく、名前付きエントリポイントGatewayMiddlewareのhandle(request, context, next)が Workers RPC で呼ばれる(クラス名は変えない) next(request)で元の宛先へ送り、上流のレスポンスを受け取る。呼ばずに独自レスポンスを返してもよい。next()は 1 回までで、宛先 URL やホストは変えられないcontextには送信元 IP、SNI、ホスト、正規化した URL、ポリシー ID などが入る。await context.identity()でメール・グループ、await context.devicePosture()で通過したポスチャチェックの UUID 一覧が取れる
やり方
- Worker を作る。公開 URL から呼ばれないよう、設定で
workers_dev: falseとpreview_urls: falseにする(Gateway からは公開ルートなしで呼べる) - 型だけ欲しければ
npm i -D @cloudflare/zt-types(2026.10.1以降)を入れ、import typeで使う - 最小の例。通過したことが分かるようにレスポンスヘッダーを足すだけ:
ts
import { WorkerEntrypoint } from "cloudflare:workers"; import type { GatewayMiddlewareContext, GatewayMiddlewareNext } from "@cloudflare/zt-types"; export class GatewayMiddleware extends WorkerEntrypoint { async handle(req: Request, ctx: GatewayMiddlewareContext, next: GatewayMiddlewareNext) { const res = await next(req); const headers = new Headers(res.headers); headers.set("x-gateway-worker", "gateway-worker"); return new Response(res.body, { status: res.status, statusText: res.statusText, headers }); } } wrangler deployで Gateway と同じアカウントにデプロイする- Cloudflare One の HTTP ファイアウォールポリシーで、テスト用のホストとユーザー(または端末グループ)に絞ったポリシーを作り、アクションに Forward と上の Worker を選ぶ
- テスト端末からそのホストを開き、
x-gateway-workerヘッダーが付いていれば成功
API で作るときは Gateway rule を action: "forward"、rule_settings.forward.worker_id に Worker の ID(32 桁の 16 進。名前や URL ではない)で作成する。
注意点
- HTTPS は TLS 復号が前提。Do Not Inspect に当たる通信、WebSocket、
CONNECTトンネル、プロトコルアップグレードでは Worker は呼ばれない(素通りする) - 検査は「元のリクエスト」と「最終レスポンス」だけ。Worker が書き換えたリクエストは再検査されないので、Worker で DLP をすり抜けることはできないが、Worker が足したデータにも DLP はかからない
- Worker 内の普通の
fetch()は別のサブリクエストで、ユーザーの Gateway ポリシーや送信元 IP を通らない。ユーザーの通信を続けるならnext()を使う identity()/devicePosture()は取得に失敗すると例外を投げ、捕まえないと HTTP500になる。「ID なし(null)」と「取得失敗」を分けて扱う(例: 失敗は503、ID なしや必要なポスチャ不足は403)- Worker を消してもポリシーは残り、一致した通信は
500で落ちる。消す前に Forward ポリシーを付け替えるか削除する - Workers VPC 経由で Cloudflare の基盤から出た HTTP 通信が Forward に一致すると落とされる。Forward ポリシーから除外する
- Workers の利用料金は通常どおりかかる。ベータ中なので仕様が変わる可能性がある
同じ仕組み: DLP の検出結果を Worker で検証する
同じ 2026-10-15 に、DLP のカスタムパターンにも Worker を付けられるようになった。正規表現だけでは誤検知が多い社員番号・顧客 ID などを、自社のルールで確かめてから判定できる。
@cloudflare/zt-typesのDlpValidationを継承したDlpValidationEntrypointクラスを export し、validate(input)を実装する。inputにはエントリ ID、一致位置、リクエストのメソッドと URL、前後を含む抜粋(base64)が入る- 戻り値は
{ score: -1〜1 }(正で確信度を上げ、負で下げる、0は変えない)か、{ score: "veto" }(一致を却下) - Cloudflare One の Data loss prevention → Detection entries → Pattern でエントリを開き、Validators → Custom functions から Worker を選ぶ。Worker のエラーやタイムアウト時の既定動作(No fallback / Veto / Score)も選べる
- そのエントリをカスタム DLP プロファイルに入れて初めてスキャンに使われる
出典
- @CFchangelog · 2026-10-17
- @CFchangelog · 2026-10-17
- Changelog: developers.cloudflare.com
- ドキュメント(Forward traffic): developers.cloudflare.com
- ドキュメント(Available context): developers.cloudflare.com
- ドキュメント(DLP の Worker 検証): developers.cloudflare.com