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.
Watch the install (4 minutes): downloading the release, defender.conf, preflight, installing the Compute service, verify, allowed and blocked requests, Fastly's own stats for the service, and removing it.
At a glance
| Deployment | One Fastly Compute service in your own Fastly account, running in every POP. One command installs it; there is no capacity to provision or size. |
| Added latency | About 5-10 ms at the median. Defender decides inside the POP already serving the request, with no added network hop. |
| Cost | About $0.60 per million requests through Defender at Fastly's list prices. Nothing from Cequence for the infrastructure. |
| If something fails | No request waits on Cequence. If Cequence is unreachable, Defender keeps enforcing the last policies it received. |
| Upgrades |
defenderctl-fastly upgrade activates a new service version. Roll back by activating the previous version in Fastly. |
Deployment architecture
Defender runs as a Compute service in your Fastly account, in every POP that serves your traffic. It sits in front of your origin, or in front of a Fastly service you already have, and nothing leaves your environment but the analytics described below.
BEFORE: your Fastly service in front of your origin
client ---> Fastly POP -------------------------------> your origin
+-------------------+
| your service |
| rules, caching |
+-------------------+
AFTER: Defender added in the same POP
client ---> Fastly POP -------------------------------> your origin
+----------+ +-------------------+
| Defender | --> | your service |
| decides | | rules, caching |
+----------+ | unchanged |
| +-------------------+
|
+---> your Cequence tenant: policies in, analytics out,
after each response
What stays the same. Your service's rules, caching and origins do not
change; Defender hands it every allowed request, and the hop between the two
stays on the same machine (Fastly calls this service chaining). Defender does
not cache your origin's responses unless you set FASTLY_CACHE=yes, so your
service keeps doing the caching it does today. Not on Fastly yet? Defender can
forward straight to your origin, with no service of yours in between.
What Defender does with a request. Each POP keeps your policy set in its cache, so a decision needs no network call. A blocked request is answered by Defender in the POP and never reaches your service or your origin. An allowed request is forwarded byte for byte, and your client receives the response byte for byte: Defender inspects a copy of each body, up to your tenant's capture settings, and never changes what it forwards. When a POP's copy of your policy set is older than 30 seconds, one request -- after its response has gone -- fetches the current set, so a policy edit in your tenant reaches every POP in about 30 seconds, with no redeploy.
What is sent to Cequence. For each request: its headers and URL, the response status and headers, the client address, the decision when a policy acted, and the inspected body copies, masked first with your tenant's Sensitive Data rules inside Fastly. Until those rules have arrived, nothing is sent. Your traffic filters decide whether a request is reported at all. Analytics are sent after your client has its response.
Installation
Prerequisites
- A Fastly account that can run Compute.
- A Fastly API token with the
globalscope, created by a user who can create services (Engineer or Superuser). It is used only by you at install time; Cequence never receives it. In the Fastly control panel, go to Account -> API tokens -> Create token, name it (for exampledefender-for-fastly-install), choose Global API access and All services, set an expiry, and copy the value. Fastly shows it only once. - Your tenant's name (such as
acme.1), client ID and client secret, from Cequence. - A POSIX shell, curl, tar, base64 and Node 20 or later. No Fastly CLI.
- From the machine you install on, HTTPS to
api.fastly.com.
1. Verify the bundle and fill in the config
The download link carries no integrity guarantee of its own, so check the bundle, then copy the example config. Every command reads that one file:
sha256sum -c SHA256SUMS cp defender.conf.example defender.conf
Set three values:
| Key | What it is |
CEQUENCE_TENANT |
your tenant name, such as acme.1 -- not a URL |
CEQUENCE_CLIENT_ID |
the client ID of the credential we issued you |
FASTLY_ORIGIN |
where Defender forwards, such as https://origin.example.com, or a second domain of your existing Fastly service. An https:// origin is reached over TLS with its certificate's host name checked; an http:// origin without TLS |
CEQUENCE_NAMESPACE names everything Defender creates and defaults to prod;
set it if more than one environment shares the Fastly account. The other
optional keys are described in the Fastly section of the file. A value already
in your environment wins over defender.conf.
2. Check and install
With your two secrets in the environment (neither is read from the file):
export FASTLY_API_TOKEN=PUT_YOUR_FASTLY_TOKEN_HERE export CEQUENCE_CLIENT_SECRET=PUT_YOUR_SECRET_HERE ./bin/defenderctl-fastly preflight ./bin/defenderctl-fastly install
preflight checks your Fastly token, that your Cequence credential signs in,
and that your origin answers. install shows what it is about to create, asks
before changing anything, and ends with the address it serves on. It creates,
and touches nothing else:
- a Compute service named
defender-<namespace> - a Config Store and a Secret Store named after it
If a service of that name exists and was not created by the installer, it stops rather than change it. Defender's own connections to Cequence always use TLS.
3. Choose how traffic reaches Defender
By default Defender gets a test address,
defender-<namespace>-<id>.edgecompute.app. Then pick one of two ways in.
All at once, on your own domains. List your hostnames in FASTLY_DOMAINS,
run install again, and point each hostname at Fastly with a CNAME. If you
already run a Fastly service, point FASTLY_ORIGIN at a second domain of that
service and move your public domain to Defender, as drawn above.
Gradually, with a dial. Your Fastly service stays public and sends a share of your clients through Defender, from 0 to 100%:
client ---> your Fastly service ---+--- the share you choose ---> Defender ---> your origin
+--- everyone else ----------------------> your origin
- In
defender.conf, addFASTLY_BEHIND_CDN=yesand runinstallagain.FASTLY_ORIGINstays your origin. -
installwritesdefender-fastly-dial.vcl, listing the three things to add to your service: a backend, an Edge Dictionary nameddefender_rollout, and a VCL snippet. The installer never changes your service. - Set
percentin thedefender_rolloutdictionary: start at a few percent and raise it as you gain confidence. Dictionary edits apply in seconds, with no new service version. At 0% Defender is out of the path.
A client stays on the same side as you raise the dial. Defender then serves only
your service: it refuses anything without your service's key, including direct
requests to its own address. Keep defender-fastly-dial.vcl private -- it
holds that key. Anything your service answers from its cache never reaches
Defender; that is usually fine for APIs, and for cacheable pages only cache
misses in your chosen share are inspected.
4. Check it before you go live
- Set
CEQUENCE_DIAGNOSTICS=yesindefender.confon a test install, runinstall, allow a minute for the POPs, then run:./bin/defenderctl-fastly verify
It checks the service is active and each domain answers through Defender,
and says whether Defender is ENFORCING (your tenant's policies loaded) or
only FORWARDING (none yet).
2. Send a request that one of your policies blocks, and check it is blocked
while other paths reach your origin. Check your tenant shows the traffic.
Fastly counts the blocks as the service's own 403 responses
(compute_resp_status_403 in its real-time stats).
3. Set CEQUENCE_DIAGNOSTICS=no and run install again. While diagnostics are
on, /__end/status is readable by anyone who can reach the domain.
4. Make sure traffic cannot reach your origin by another route, which would not
be inspected: use origin shielding, mTLS or IP allowlisting.
Upgrades and rollback
With the new bundle unpacked and the same defender.conf and secrets:
./bin/defenderctl-fastly upgrade ./bin/defenderctl-fastly verify
upgrade clones the active service version, applies the new release and your
settings, validates the new version and activates it. Your settings are kept.
It refuses to create a service that is not there, and if nothing changed it
makes no new version. Requests keep being served by the active version until
the new one is activated.
To roll back, open the service in the Fastly control panel and activate the
previous version, which stays in the service's history. Settings live in the
Config Store, which is not versioned, so a rollback restores the previous
release with your current settings. Running upgrade from the previous bundle
does the same.
Performance and sizing
| Added latency, median | about 5-10 ms |
| Defender's CPU per request | about 1-2 ms |
| Building the policy engine on a fresh Fastly sandbox | about 0.5 ms for tens of policies, 11 ms for 500, 59 ms for 2,000 |
Engine build times were measured on a Fastly POP in Seattle. A sandbox builds the engine once and reuses it for later requests, and reuse grows with traffic. There is nothing to size: Defender runs in every POP that serves your traffic, and Fastly scales it.
Cost
Cequence charges nothing for the infrastructure. Defender runs in your Fastly account, and Fastly bills you for it:
- About $0.60 per million requests through Defender, at Fastly's list prices (October 2026), or up to about $2.50 per million if your Fastly contract also bills the analytics Defender sends to Cequence.
- Fastly includes 10 million requests a month free.
- With the dial, you pay only for the share sent to Defender: at 10%, about a tenth of the above.
Availability
- If Cequence is slow or unreachable, your traffic is unaffected: no request waits on Cequence. Each POP keeps enforcing the last policy set it fetched, and carries it forward for as long as the outage lasts while the POP has traffic. A POP that has served no traffic for more than a day has no copy left; it forwards every request without policy checks until it reaches your tenant again. Analytics for requests made during an outage are not sent later.
-
If Defender itself stops on a request, Fastly answers that request with
a bare
Internal Server Error. Fastly's log for the service shows why; see "If something is wrong". -
If you need Defender off the path at once: with the dial, set
percentto 0 -- it applies in seconds. Otherwise, move your public domain back to your own service or origin. - A fresh install blocks nothing until your tenant's first policy publish arrives; until a POP has fetched your policy set, it forwards all traffic.
Known limits
-
blockandadd-headerpolicies are enforced.challenge,rate-limitandredirectpolicies are reported but not applied: the request is forwarded. Response bodies are never enforced on. - Large policy sets on a fresh sandbox: about 180 ms to build for 6,000 policies. Fastly documents a 50 ms CPU limit per request; check your account's limits if your tenant's set is large.
- Fastly Compute refuses a
GETorHEADthat carries a body, with400 request cannot have request body, before Defender runs. Send the body withPOST, or keep that path off Defender. - With the dial, the client's original header order is lost across the hop, which weakens policies keyed on it.
- Analytics are sent per request rather than in batches.
If something is wrong
The bundle's README.md has the full troubleshooting reference.
./bin/defenderctl-fastly status shows the service and its active version.
| Symptom | What to do |
install stops: a service of that name exists |
Choose another CEQUENCE_NAMESPACE. |
| Nothing is enforced | Before your tenant's first policy publish, this is expected. Otherwise run preflight: a refused credential means a wrong client ID or secret. The install plan's tenant: line shows which client was used. |
status says /__end/status not served
|
Diagnostics are off, the default. Turn them on as in "Check it before you go live", check, then turn them off. |
Internal Server Error from Defender |
Defender stopped on that request. fastly log-tail --service-id <id> (Fastly CLI) shows why. Send that output, the time and the domain to Cequence support. |
| Every client has the same address | Something in front of Fastly terminates the connection. Set client_ip_header in Defender's Config Store to the header it adds. |
| Your origin sees fewer requests than your clients send |
FASTLY_CACHE=yes is caching its responses. |
With the dial, requests to Defender get 403 forbidden
|
Your service is not sending the key: check the snippet from defender-fastly-dial.vcl is in place. |
If you contact support, include the installer's output and, with diagnostics
on, /__end/status. Neither contains a secret.
Removing it
Point your own domains back first, or set the dial to 0, then:
./bin/defenderctl-fastly uninstall
This removes the Defender service and the two stores it created. Your origin and any other Fastly service are untouched.