@d3-inc/d3-edge-cloudflare-adapter
v0.2.0
Published
Cloudflare Worker adapter for D3 Edge bot-auth enforcement, deployed in front of the protected site: extract → policy decision → enforce, fail-open.
Keywords
Readme
@d3-inc/d3-edge-cloudflare-adapter
Cloudflare Worker adapter for D3 Edge bot-auth enforcement. In front of your site, it extracts the signature headers, user agent, and IP from each request, asks your D3 Edge policy endpoint for a decision, enforces it, and forwards allowed traffic to your origin — failing open if the policy call errors or times out, so an outage never takes down your site.
Install
npm i @d3-inc/d3-edge-cloudflare-adapterUsage — your site is already a Worker
Wrap your existing handler. One line, no second worker, no route changes:
// src/index.ts
import { withD3Edge } from '@d3-inc/d3-edge-cloudflare-adapter';
export default withD3Edge({
async fetch(request, env, ctx) {
// your existing worker, unchanged
},
});Blocked requests get a 403 before your fetch runs; everything else
reaches it as before. Non-fetch handlers (scheduled, queue, …) pass
through untouched. Add the config to your existing wrangler.toml —
ORIGIN/ORIGIN_URL are not needed, the wrapped handler is the origin:
[vars]
POLICY_WORKER_URL = "https://edge-api.d3.com/v1/decision"Usage — external origin
Origin not on Workers (nginx, a VPS, another cloud)? The Deploy to Cloudflare button sets this shape up from the browser, no code. By hand, deploy the adapter as a standalone worker on a zone route:
// src/index.ts
import worker from '@d3-inc/d3-edge-cloudflare-adapter';
export default worker;# wrangler.toml
name = "my-site-d3-edge"
main = "src/index.ts"
compatibility_date = "2025-06-01"
# Zone route: your DNS record stays as-is; pass-traffic flows to your origin.
routes = [{ pattern = "www.example.com/*", zone_name = "example.com" }]
[vars]
POLICY_WORKER_URL = "https://edge-api.d3.com/v1/decision"
POLICY_TIMEOUT_MS = "500"
FAIL_MODE = "open"Origin a Worker you can't edit, or a Pages project? Attach the standalone
worker with custom_domain = true and an ORIGIN service binding instead —
a custom domain replaces the hostname's DNS record, so it always needs
ORIGIN (or ORIGIN_URL) to reach the origin. The
docs cover every shape.
With either shape, set your org's adapter key (from your D3 Edge dashboard's install page) as a secret:
npx wrangler secret put POLICY_ADAPTER_KEYLeave POLICY_WORKER_URL unset for pure passthrough (no enforcement, no
reporting) — useful for staging the rollout. The exported Env type documents
every variable.
Docs
Full documentation, including origin binding options and the decision model: ai.d3.com/docs.
License
Apache-2.0
