テック技報最新号へ →
インフラ

Cloudflare Gateway の Forward アクション: 社内の HTTP 通信に自分の Worker を挟む(DLP の検出も Worker で検証できる)

Gateway の HTTP ポリシーに「Forward」アクションが追加され(2026-10-15 公開ベータ、全 Zero Trust プラン)、条件に合った通信で自分の Worker を呼べるようになった。プロキシを別に立てずに、ヘッダー書き換え・注意喚起ページ・Slack 通知・R2 への記録などができる。

@CFchangelog · 投稿 2026-10-15
#infra#cloudflare#zerotrust#gateway#workers#dlp#proxy

どんなときに使う?

  • 特定の社内 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 一覧が取れる

やり方

  1. Worker を作る。公開 URL から呼ばれないよう、設定で workers_dev: false と preview_urls: false にする(Gateway からは公開ルートなしで呼べる)
  2. 型だけ欲しければ npm i -D @cloudflare/zt-types(2026.10.1 以降)を入れ、import type で使う
  3. 最小の例。通過したことが分かるようにレスポンスヘッダーを足すだけ:
    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 });
      }
    }
  4. wrangler deploy で Gateway と同じアカウントにデプロイする
  5. Cloudflare One の HTTP ファイアウォールポリシーで、テスト用のホストとユーザー(または端末グループ)に絞ったポリシーを作り、アクションに Forward と上の Worker を選ぶ
  6. テスト端末からそのホストを開き、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() は取得に失敗すると例外を投げ、捕まえないと HTTP 500 になる。「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 プロファイルに入れて初めてスキャンに使われる

出典

X の元の投稿を開く