Skip to Content
PaywallMonetizationOS (MOS)Cloudflare Worker Integration

Cloudflare Worker Integration

Sophi Paywall with MonetizationOS (MOS) is deployed via the officially maintained Cloudflare Proxy Worker  — an open-source reference implementation of the MonetizationOS proxy , built on Cloudflare Workers . It is a ready-to-deploy Worker, not a library you build a Worker around — integration is configuration, not custom code.

View the Cloudflare Proxy Worker on GitHub  — that page also has a “Deploy to Cloudflare” button for a one-click deploy.

This page is the client-facing setup and rollout guide. For the authoritative implementation reference — the full environment variable list, request pipeline, HTML transformation, and error handling — see the MonetizationOS docs linked throughout; this page links to the relevant section rather than duplicating it.


1. How it works

The Worker sits on the site’s hostname, fetches from the origin, and calls the MonetizationOS Surface Decision API for every HTML response. See the request pipeline  for the full stage-by-stage flow (custom endpoint routing → origin fetch → link rewriting → identity resolution → Surface Decision API call → surface behavior → component behaviors).

Any failure after the origin fetch is caught and the Worker fails open — the visitor still gets the origin response. See Error handling .


2. Prerequisites

ItemWho provides it
Cloudflare account with Workers enabled, on the zone that serves the siteClient
Wrangler CLI (npm i -D wrangler)Client
MONETIZATION_OS_SECRET_KEY (secret key from the MonetizationOS dashboard)MonetizationOS
SURFACE_SLUG for each surface (e.g. web)MonetizationOS
Origin hostname the Worker should proxy to (ORIGIN_URL)Client
Cookie names used for sessions — authenticated JWT and anonymous sessionClient
Decision: which paths skip Surface Decisions (SURFACE_DECISIONS_IGNORE_PATHS)Client + MonetizationOS

3. Worker configuration

All settings are Cloudflare Worker bindings , set in wrangler.jsonc for deployed environments or a .dev.vars.local file for local development. The full variable reference — including optional variables and their defaults — lives in Environment variables . The variables every integration must set:

VariableDescription
MONETIZATION_OS_SECRET_KEYSecret key from the MonetizationOS dashboard. Also derives the environment prefix for custom endpoint routing .
ORIGIN_URLBase URL of the client origin. All non-endpoint requests are proxied here.
SURFACE_SLUGThe MonetizationOS surface to evaluate for every HTML request.
AUTHENTICATED_USER_JWT_COOKIE_NAMECookie name containing the authenticated user’s JWT.
ANONYMOUS_SESSION_COOKIE_NAMECookie name for anonymous session identifiers.

Example wrangler.jsonc for a production deployment:

{ "name": "mos-proxy", "main": "src/index.ts", "compatibility_date": "2026-08-01", "routes": [ { "pattern": "www.client.com/*", "zone_name": "client.com" } ], "vars": { "ORIGIN_URL": "https://origin.client.com", "SURFACE_SLUG": "web", "AUTHENTICATED_USER_JWT_COOKIE_NAME": "__session", "ANONYMOUS_SESSION_COOKIE_NAME": "anon-session-id" } }

MONETIZATION_OS_SECRET_KEY is a secret, not a plain var — set it per environment with:

npx wrangler secret put MONETIZATION_OS_SECRET_KEY

For local development, put the equivalent values in a git-ignored .dev.vars.local:

MONETIZATION_OS_SECRET_KEY=sk_test_... ORIGIN_URL=https://origin.client.com SURFACE_SLUG=web AUTHENTICATED_USER_JWT_COOKIE_NAME=__session ANONYMOUS_SESSION_COOKIE_NAME=anon-session-id

A few optional variables worth deciding on up front:

VariableDefaultPurpose
MONETIZATION_OS_HOSThttps://api.monetizationos.comOverride the MonetizationOS API host.
MONETIZATION_OS_ENDPOINTS_PREFIX/mos-endpoints/URL prefix routed directly to MOS as Endpoint Workflow  requests.
INJECT_SCRIPT_URLunsetIf set, injects <script src="{INJECT_SCRIPT_URL}" async defer></script> into <head> on every HTML response.
SURFACE_DECISIONS_IGNORE_PATHSunsetComma-separated regex patterns for paths that should skip Surface Decisions entirely (e.g. /api/, static assets).

No client-written HTML rewriting, identity resolution, or Surface Decision API call code is needed — the Worker already implements all of it. See HTML transformation with HTMLRewriter  and Identity resolution  for how those stages behave.

If a client needs a provider MonetizationOS doesn’t ship a reference Worker for, see Custom Proxy Integration , which documents the underlying runtime-agnostic @monetizationos/proxy core that this Worker — and the Fastly and Akamai reference implementations — are built on.


4. Cloudflare request context

The Worker automatically forwards request.cf — Cloudflare’s incoming request properties  (geolocation, device, network, bot signals) — to the Surface Decision API on every call. No configuration is required to enable this; Surface Workflows can use it directly for targeting. See Cloudflare request context .


5. Routing traffic to the Worker

Two options — pick one with the client:

OptionHowWhen
A. Worker on the public hostname (recommended)Add a Worker route for www.client.com/* on the existing zone; DNS for www becomes a proxied (orange-cloud) record — since the route intercepts before DNS resolution.The site is already on Cloudflare (or can be onboarded).
B. Workers subdomain / gradualServe from *.workers.dev or a staging hostname first; cut over by changing DNS when validated.The site is not on Cloudflare yet, or a staged migration is required.

Origin protection is required once the Worker fronts the site, otherwise visitors (and scrapers) can bypass the paywall by hitting the origin directly. Options, best first:

  1. Authenticated Origin Pulls (mTLS) — Cloudflare presents a client certificate; origin rejects anything else.
  2. Secret header — the origin only accepts requests carrying a header only the Worker sends; reject everything else.
  3. IP allow-list — origin firewall allows only Cloudflare IP ranges (weakest of the three; headers are easier to verify).

Identity is resolved from cookies before the Surface Decision API is called — see Identity resolution . The client must confirm:

  • AUTHENTICATED_USER_JWT_COOKIE_NAME and ANONYMOUS_SESSION_COOKIE_NAME match what the site actually sets (e.g. Auth0/Clerk/custom auth often use __session, appSession, etc.).
  • Cookies are set on the parent domain (.client.com) if subdomains must share identity.
  • If neither cookie is present, the Worker generates a new anonymous session ID and sets it via Set-Cookie — confirm this is acceptable for the client’s cookie/consent policy.

7. Verification & rollout

  1. Local: npx wrangler dev → browse pages; expect the anonymous-session cookie to appear.
  2. Staging: point a staging hostname at the Worker (Option B above), run the paywall scenarios (anonymous metered, subscribed user, bot UA, non-HTML assets, POST forms).
  3. Observability: the Worker logs to console.error on failure — wire Workers Logpush / dashboard alerts on any error-level log.
  4. Cutover: enable the route on the production hostname; monitor origin bypass attempts, error rate, and added latency (the Surface Decision API call is the dominant added latency — once per uncached HTML page view).
  5. Rollback: remove the Worker route — traffic flows directly to the origin again.

8. Failure modes the client should know

FailureBehavior
Surface Decision API down/timeoutCaught by the Worker’s error handling; original origin response returned unmodified. Fail-open.
Non-HTML contentAlways passes through unchanged.
Origin downOrigin’s error response passes through (the Worker does not mask origin failures).

See Error handling  for the exact behavior.


9. Client questionnaire

The open questions for the client development team live on a standalone page: the readiness questionnaire. Send it before implementation starts — every answer maps to a configuration value in §3.


10. Deliverables checklist

  • Worker deployed from the Cloudflare Proxy Worker repo , configured per §3
  • Secrets configured in Cloudflare (per environment)
  • Origin bypass protection enabled
  • Staging hostname verified against the full scenario matrix
  • Log alerts wired
  • Runbook: how to disable the route (rollback) and how to rotate MONETIZATION_OS_SECRET_KEY
Last updated on