This is a preview release. Do not use it in production environments.
Download the release bundle from Download Edge-Native Defender (Preview). New to Edge-Native Defender? Start with Edge-Native Defender overview.
At a glance
| Deployment | A Cloudflare Worker on a route of the zone already serving your traffic, installed by one command. No DNS, origin or routing changes. |
| Added latency | About 10 ms on average. No extra network hop: the request was already passing through Cloudflare. |
| Cost | Billed by Cloudflare to your account: the $5 Workers Paid plan, plus an estimated $26 a month at 10 million requests. Nothing from Cequence for the infrastructure. |
| If something fails | Your site stays up. If Cequence is unreachable, Defender keeps enforcing its last policies; one command takes Defender off the path in seconds. |
| Upgrades | One command moves traffic to the new version in steps and rolls back by itself if errors rise. |
Deployment architecture
Defender runs in your Cloudflare account as a Worker, in every Cloudflare location that already serves your zone, on a route you already have. There is no capacity to provision; a traffic spike is absorbed by the same network that absorbs it today.
BEFORE
client ---> proxied DNS ---> Cloudflare edge ------------> your origin
AFTER
client ---> proxied DNS ---> Cloudflare edge ------------> your origin
|
| Worker route (the paths you choose)
v
Defender (Cloudflare Worker)
|
+---> your Cequence tenant: policies in,
analytics out, in the background
What stays the same. Your DNS records, your origin, and every hostname and path you do not route to Defender. Defender forwards through your proxied DNS record, so it does not need to be told your origin.
What Defender does with a request. A blocked request is answered at the edge and never reaches your origin. An allowed request is forwarded byte for byte, and your client receives your origin's response byte for byte: Defender inspects a copy of each body, up to your tenant's capture settings, and never changes what it forwards.
What is sent to Cequence. For each request: its headers and URL, the response status and headers, and the inspected body copies, masked first with your tenant's Sensitive Data rules before they leave your account. Your traffic filters decide whether a request is reported at all.
No request waits on Cequence. Policies are already at the edge before a request arrives, and analytics are sent after your client has its response. The installer creates a Workers KV namespace and two Cloudflare Queues beside the Worker for this, all in your account and off the request path. Learned policies, such as IP and fingerprint policies, take effect within about 25 seconds; a policy you publish takes effect without a redeploy.
Installation
Prerequisites
- A Cloudflare account with the zone, on the Workers Paid plan. The free plan's 10 ms CPU cap is not enough for policy evaluation, and it has no Queues. Any zone plan, including Free, is enough.
-
A proxied DNS record (orange cloud) for every hostname you route to
Defender. If the hostname already serves traffic through Cloudflare, it
exists. Without one, requests never reach Defender;
preflightchecks this. - A Cloudflare API token for the account that owns the zone (step 1). It is used only by you at install time; Cequence never receives it.
- Node 20 or later and wrangler v4 or later where you install from (Terraform 1.5 or later for the Terraform path).
-
Your tenant name (such as
acme.1), client ID and client secret, from Cequence.
1. Create the Cloudflare API token
In the Cloudflare dashboard: My Profile -> API Tokens -> Create Token -> Create Custom Token, with these permissions:
Account -- Workers Scripts: Edit Account -- Workers KV Storage: Edit Account -- Queues: Edit Account -- Account Analytics: Read Zone -- Workers Routes: Edit Zone -- Zone: Read Zone -- DNS: Read
DNS: Read (optional) lets preflight confirm your record is proxied;
Account Analytics: Read is needed only for staged upgrades. Under Account
Resources include only the account that owns the zone, and under Zone
Resources only your zone. Copy the token; Cloudflare shows it once.
2. Verify the bundle and fill in the config
sha256sum -c SHA256SUMS cp defender.conf.example defender.conf
Set four values in defender.conf:
| Key | What it is |
CEQUENCE_CLOUDFLARE_INSPECTED_ROUTES |
What Defender is placed in front of, as Cloudflare route patterns. A bare hostname means the whole hostname |
CLOUDFLARE_ACCOUNT_ID |
The account that owns the zone. A route only attaches to a zone in the Worker's own account |
CEQUENCE_TENANT |
Your tenant name, such as acme.1, not a URL. Watch the trailing number: acme and acme.1 both look plausible and only one resolves |
CEQUENCE_CLIENT_ID |
Your client ID |
Optional: CEQUENCE_NAMESPACE (default prod) names the deployment's
resources; use a different one per environment. CEQUENCE_CANARY_PERCENT
inspects a share of clients while you onboard. ORIGIN is only for a backend
on a different hostname from the route. The routes key was
CEQUENCE_INSPECTED_ROUTES before 0.19.1, and that name still works. Every key
is in CONFIGURATION.md in the bundle.
Secrets never go in the file (a file that sets them is rejected). Export them:
export CLOUDFLARE_API_TOKEN=PUT_YOUR_TOKEN_HERE export CLOUDFLARE_ACCOUNT_ID=PUT_YOUR_ACCOUNT_ID_HERE export CEQUENCE_CLIENT_SECRET=PUT_YOUR_SECRET_HERE
3. Choose what Defender inspects
Routes are Cloudflare route patterns, so you can protect one hostname or one
path prefix rather than the whole zone. * is the only wildcard.
CEQUENCE_EXCLUDED_ROUTES keeps paths off Defender entirely: those requests
skip the Worker and are not billed for it.
CEQUENCE_CLOUDFLARE_INSPECTED_ROUTES="api.example.com/* www.example.com/checkout/*" CEQUENCE_EXCLUDED_ROUTES="api.example.com/health/*"
The Worker runs before Cloudflare's cache, so every request on a route is inspected, including ones the cache would have answered: a blocked client cannot be served a cached response, but static assets are inspected and billed for no return. Route Defender at your API and dynamic paths and leave static content out. (Defender for AWS is the opposite: the cache answers first.)
4. Install
./defender.conf is picked up automatically, so these take no arguments:
./bin/defenderctl-cloudflare preflight ./bin/defenderctl-cloudflare install
preflight checks your tools, the token, the zone, the DNS record and your
Cequence credentials. install creates the resources, deploys, and stages the
bypass version described under Availability. It is safe to re-run;
--dry-run prints every command it would run. For infrastructure as code, use
the bundle's terraform/ module instead.
5. Check it before you go live
- Run
./bin/defenderctl-cloudflare status(what is installed, read-only) and./bin/defenderctl-cloudflare validate(whether requests through the route are answered and reach your origin). - To check that policies arrive and analytics leave, add
CEQUENCE_DIAGNOSTICS=yestodefender.conf, run./bin/defenderctl-cloudflare upgrade, thenvalidateagain. - Send a request that one of your policies blocks, and check it is blocked.
- Remove
CEQUENCE_DIAGNOSTICSand runupgradeagain. With diagnostics on,/__end/statusand thex-end-echoheader are readable by anyone who can reach the route.
With diagnostics off, validate lists what it did not check, as expected.
Allow a couple of minutes after a fresh install for your first policies to
arrive. Before going live, make sure your origin accepts traffic only through
Cloudflare (origin shielding, mTLS or IP allowlisting).
Upgrades and rollback
Extract the new bundle and run, from it:
./bin/defenderctl-cloudflare upgrade --worker cequence-defender-prod
Replace prod with your namespace (with one deployment, --worker can be
left out). Export CLOUDFLARE_API_TOKEN and CEQUENCE_CLIENT_SECRET; your
defender.conf is not needed, as the settings are read from the deployment.
The upgrade moves traffic in steps, 1% to 10% to 50% to 100% by default, holding each step for 10 minutes. At each step it compares the new version's error rate with the old one's using Cloudflare's own counters, and rolls back by itself if the new version is worse. Your policies and queued analytics are kept, so nothing is re-fetched from scratch.
To roll back at any time:
./bin/defenderctl-cloudflare upgrade --worker cequence-defender-prod --rollback
This puts 100% of traffic back on the last good version. If a ramp is
interrupted, traffic stays split between the two versions until upgrade
--resume finishes it or --rollback undoes it; status shows where it is.
On a quiet hostname, where a step may never see enough requests to judge,
re-run install from the new bundle instead, which moves all traffic at once.
upgrade refuses to run while Defender is bypassed; turn the bypass off first.
Performance and sizing
| Added latency, average | about 10 ms |
| Sizing | none: Cloudflare runs Defender in every location serving your zone |
There is no added network hop, and a blocked request never reaches your origin, so your backend sees no load from denied traffic.
Cost
Cequence charges nothing for the infrastructure. Defender runs in your Cloudflare account and Cloudflare bills you at list price:
- Workers Paid, $5 a month per account. One subscription covers every deployment on the account.
- A fixed floor per deployment for the background policy refresh, from $6 a month in about 10 Cloudflare locations to $46 in about 100.
- $0.45 to $1.62 per million requests for Workers requests, CPU and the analytics queue. Sparse traffic costs more per request than dense traffic.
| Requests a month | Cloudflare locations | Estimated total |
| 10 million | about 25 | $26 |
| 100 million | about 50 | $96 |
| 1 billion | about 100 | $529 |
Estimates from a reference deployment, excluding the $5 subscription, not a
quote. DEPLOYMENT.md in the bundle has the full breakdown and the settings
that lower the floor.
Availability
- If Cequence is slow or unreachable, your traffic is unaffected. Defender keeps enforcing the policies it last received, and analytics wait in the queue in your account and are retried. A background refresh that stops is restarted automatically.
- If Defender hits an error on a request, Cloudflare forwards that request to your origin as if Defender were not there.
-
If you need Defender off the path at once, use the bypass lever:
./bin/defenderctl-cloudflare bypass --on ./bin/defenderctl-cloudflare bypass --off
--on sends all traffic to the staged bypass version, which forwards every
request untouched (not inspected, enforced or reported) while still keeping
policies fresh, so turning it off starts warm. --off returns traffic to
Defender, --percent N splits, and no argument reports what is serving. Each
takes seconds and changes no DNS, routes or zone settings. Cloudflare applies
it before any Defender code runs, so it works whatever Defender is doing, and
it is plain wrangler versions deploy, which you can run yourself. Cequence
holds no credential in your Cloudflare account. As a last resort, removing
the Worker route also takes Defender off the path; re-adding it restores the
deployment as it was.
- A fresh install blocks nothing until your tenant's first policy publish
arrives. Until then Defender forwards all traffic.
Known limits
- Every policy action is enforced:
block,add-header,challenge,rate-limitandredirect. Rate-limit counts are shared across all Cloudflare locations and are eventually consistent, so a client can briefly exceed its limit before it is limited. - Response bodies are captured for analytics but never enforced on; a decision applies to the request. Response signals shape decisions on later requests.
- JA3/JA4 fingerprints come only from Cloudflare Bot Management (Enterprise). Without it, a JA3/JA4-keyed policy never matches.
- Only traffic passing through Cloudflare is inspected. For a zone such as
example.co.uk, setCLOUDFLARE_ZONE.
If something is wrong
| Symptom | What to check |
| Requests never reach Defender | The hostname needs a proxied DNS record. The most common install issue |
522 on every request |
Defender is forwarding to a hostname with no reachable origin. If your backend is a different hostname, set ORIGIN
|
preflight says the tenant credential was rejected |
CEQUENCE_TENANT, CEQUENCE_CLIENT_ID and CEQUENCE_CLIENT_SECRET
|
| Nothing is blocked after install | Expected until your tenant's first policy publish |
| Analytics stop arriving | Check the queue backlog: npx wrangler queues info cequence-defender-prod-telemetry (your namespace in place of prod). A backlog that only grows means analytics are not being delivered |
| Analytics show only part of your traffic | Expected while CEQUENCE_CANARY_PERCENT is below 100 or a bypass takes a share |
./bin/defenderctl-cloudflare debug collects everything support needs into one
file, with no credentials. The full troubleshooting reference is in
DEPLOYMENT.md in the bundle.
Removing it
./bin/defenderctl-cloudflare uninstall
After you type the Worker name to confirm, it removes the Worker, its routes,
and the queues and KV namespace that the installer created, keeping any it
found already there. A Terraform install is removed with terraform destroy.
Your DNS records are untouched, and traffic goes straight to your origin again.
If you created a record only for Defender, with no origin behind it, remove or
repoint it, or the hostname will return 522.