Akamai EdgeWorkers Proxy
The Akamai EdgeWorkers Proxy is an open source reference implementation of the MonetizationOS proxy built on the Akamai EdgeWorkers runtime.
Environment variables
Configure values in Akamai Property Manager using the Set Variable behavior with the PMUSER_ prefix. Each PMUSER_ variable maps to an internal configuration key used by the shared @monetizationos/proxy core.
| PMUSER variable | Internal key | Required | Description |
|---|---|---|---|
PMUSER_MOS_SECRET_KEY | MONETIZATION_OS_SECRET_KEY | Yes | Your MonetizationOS secret key. Used to authenticate Surface Decision API requests and to derive the environment prefix for custom endpoint routing. |
PMUSER_ORIGIN_URL | ORIGIN_URL | Yes | The base URL of your origin server. All non-endpoint requests are proxied here. |
PMUSER_SURFACE_SLUG | SURFACE_SLUG | Yes | The MonetizationOS surface to evaluate for every HTML request. |
PMUSER_AUTH_JWT_COOKIE | AUTHENTICATED_USER_JWT_COOKIE_NAME | Yes | Cookie name containing the authenticated user's JWT. |
PMUSER_ANON_COOKIE | ANONYMOUS_SESSION_COOKIE_NAME | Yes | Cookie name for anonymous session identifiers. |
PMUSER_MOS_HOST | MONETIZATION_OS_HOST | No | Override the MonetizationOS API host. Defaults to https://api.monetizationos.com. |
PMUSER_MOS_ENDPOINTS_PREFIX | MONETIZATION_OS_ENDPOINTS_PREFIX | No | URL prefix for custom MOS endpoint routing. Defaults to /mos-endpoints/. |
PMUSER_MOS_API_PREFIX | MONETIZATION_OS_API_PATH_PREFIX | No | Internal Property Manager path prefix for worker httpRequest() sub-calls to the MonetizationOS API. Defaults to /mos-webscale-api. Requires a matching Property Manager rule. Do not use /mos-api — that path is reserved for client-facing authenticated routes such as /mos-api/offer-redemptions. |
PMUSER_INJECT_SCRIPT_URL | INJECT_SCRIPT_URL | No | If set, a <script> tag pointing to this URL is appended to <head> on every HTML response after component transforms. |
PMUSER_SURFACE_DECISIONS_IGNORE_PATHS | SURFACE_DECISIONS_IGNORE_PATHS | No | Comma-separated regex patterns for paths that should skip surface decisions. |
PMUSER_ORIGIN_REQUEST_HEADERS | ORIGIN_REQUEST_HEADERS | No | JSON object mapping header names to values, added or overridden on every upstream httpRequest() to the origin. |
Internal API routing via /mos-webscale-api
Unlike Cloudflare and Fastly, Akamai's httpRequest() only reaches hostnames served through your property. The worker cannot call api.monetizationos.com directly.
Instead, the shared proxy builds API URLs on MONETIZATION_OS_HOST, and the Akamai adapter rewrites them to relative paths under PMUSER_MOS_API_PREFIX (default /mos-webscale-api):
https://api.monetizationos.com/api/v1/surface-decisions
→ /mos-webscale-api/api/v1/surface-decisionsYour property must include a rule matching /mos-webscale-api/* that strips the prefix and forwards to api.monetizationos.com. See the Akamai quickstart for Property Manager configuration.
This internal prefix is separate from client-facing routes such as /mos-api/offer-redemptions, which @monetizationos/proxy handles on incoming browser requests. Using /mos-api for both would conflict in Property Manager.
Custom endpoint routing
Requests whose path begins with PMUSER_MOS_ENDPOINTS_PREFIX (default /mos-endpoints/) are forwarded to the MonetizationOS API as Endpoint Workflow requests. The remaining pipeline stages are skipped.
The environment prefix is extracted from PMUSER_MOS_SECRET_KEY to target the correct environment:
/mos-endpoints/my-route → /mos-webscale-api/api/v1/envs/{env}/endpoints/my-routeAkamai request context
When calling the Surface Decision API, the worker sends an akamai object with the property hostname used for sub-requests:
{
"akamai": {
"host": "https://your-property-hostname.example.com"
}
}Web Platform polyfills
Akamai EdgeWorkers do not provide standard Web Platform globals that @monetizationos/proxy expects (URL, Headers, Request, Response, ReadableStream, TransformStream, TextEncoder, TextDecoder). The worker installs minimal polyfills at startup via installAkamaiGlobals.ts before the shared core runs.
Avoid top-level use of those globals in worker code — Akamai static validation evaluates the bundle at upload time.
HTML transformation with HtmlRewritingStream
Component behaviors use Akamai's streaming HtmlRewritingStream (lol-html, the same family as Cloudflare HTMLRewriter and Fastly HTMLRewritingStream) to apply CSS-selector-targeted mutations without buffering the full response body in memory.
Each component behavior from the Surface Decision response is registered with onElement(selector, …) on a shared HtmlRewritingStream before the response body stream is piped through the transformer.
CSS selector limitations
- Selectors using
:last-childare logged and skipped. replaceRangerequiresonEndTag; Akamai's rewriter does not expose it, so range replacement is skipped (same as Fastly).- Inserted text nodes are escaped in the adapter when the core requests non-HTML content.
- All other standard CSS selectors supported by
HtmlRewritingStreamwork as expected.
Script injection
If PMUSER_INJECT_SCRIPT_URL is set, the worker appends the following to <head> after all component transforms:
<script src="{PMUSER_INJECT_SCRIPT_URL}" async defer></script>Caching behavior
The worker sets Cache-Control: no-store on all HTML responses during the link-rewriting stage. This prevents CDN or browser caching of personalized, per-user responses. Non-HTML responses passed through unmodified retain whatever cache headers the origin returned.
Error handling
All processing after the initial origin fetch is wrapped in a try/catch inside the shared proxy core. On any unhandled error, the worker logs the error and returns the original origin response unmodified.
In Property Manager, enable Continue on error on the EdgeWorkers behavior so requests can still reach the origin if the worker fails at the platform level. This ensures your site stays available if the MonetizationOS API is unreachable or a workflow errors.