From nothing to a protected site, in the order that will not break it. This page is the path through the other ten: install an agent, add a site, watch before blocking, read what you see, then turn protection on.
The whole route takes about an hour of work and a week of waiting — and the waiting is the part that matters. A WAF switched straight to blocking on an application nobody has observed is how a site loses customers on a Monday morning.
https://<address>:8082.The agent is the decision engine that sits next to nginx.
Production Agent 1, not agent2.

Full detail: Agents.
Edge → Tenants → Add Tenant: pick the group it belongs to, give it a name and its domain. Then go back to the agent and tick the new site, so the agent knows to protect it.


A site inherits everything from its group, which inherits from the global settings. You have not configured anything yet, and that is correct: the defaults are a working policy.
This is the step people skip, and the one that decides whether the rest goes well.
Global Settings → General → WAF Operating Mode → Learning (detect only, no blocking) — or set it on the site alone, if the rest of the estate is already in blocking mode.
In learning mode EdgeGuard inspects everything and blocks nothing. Every decision it would have made is recorded, with its score and the rules that fired.

Leave it here for at least a few days of ordinary traffic — including whatever runs at the weekend, and the batch jobs nobody remembers. You are not waiting for the product; you are waiting for your application to show you its habits.
After a few days, four pages answer four questions:
| Question | Page |
|---|---|
| What has been happening? | Monitoring → Daily summary — one page per day, exportable |
| What exactly was decided, and why? | Monitoring → Security Events — open any row for the rules and what they matched on |
| Which rules are costing me false positives? | Monitoring → Analytics → Performance & quality, the False Positive Rate Estimate table |
| Is anything already being suppressed for me? | WAF → False Positives, lower table |
Work through the events that would have been blocked. For each one, decide: was it an attack, or was it your application?
These cost nothing to get right and stop a great deal of noise:
When the events for a normal week contain nothing you would be sorry to refuse:
Global Settings → General → WAF Operating Mode → Blocking, or on the one site.
Then watch the same four pages for a day. The first hours of blocking are when a missed false positive shows itself, and undoing one is a minute's work: the event that was refused carries Mark false positive and Create rule from event in its detail panel.
A WAF that refuses everything is not passing a test, it is failing it the other
way round. So the check is a pair of questions, always: is the attack refused,
and does ordinary traffic still arrive.
The appliance ships the run:
./tools/waf-selftest.sh https://your-site.example
Ten cases against a site you are responsible for. Six attacks that must be
refused, and four that answer the other half of the question:
| SQLi in a query parameter | refused — the shape sqlmap sends |
| Error-based SQLi | refused |
| Command injection in a urlencoded body | refused |
| Command injection in a multipart body | refused — over 400 characters, to exercise the evidence store |
| Path traversal | refused |
| A clean request | arrives |
The PHP_SESSION_UPLOAD_PROGRESS field |
refused — see PHP2Shell |
| That field's name as a value | arrives |
| English prose containing "update … where" | arrives |
| Real SQL injection in that same field | refused |
The last four are two pairs, and the pairing is the point.
The field, and its name. A rule that refused any request mentioning
PHP_SESSION_UPLOAD_PROGRESS would refuse the ticket quoting it, the advisory
describing it and the engineer pasting it into a search box. If the first of
that pair is refused and the second is too, the rule has regressed from reading
parameter names to reading the request body — and the first case on its own
looks identical either way.
The prose, and the payload. In October 2026 a real support ticket was
refused as SQL injection because its text contained "update … where". The rule
responsible was called SQL Injection Attack Detected via libinjection and was
in fact a keyword pair — (select|insert|update|…).*(from|into|set|where|…) —
which half of ordinary correspondence matches. It is a genuine semantic
detector now. The guard against its return is the prose case; but prose passes
just as well against a body the engine never reads at all, so the fourth case
sends real injection in the same field. Together they say the field is
inspected and ordinary writing survives it. Separately, neither says
anything.
A refusal carries an EdgeGuard ID; open it in Monitoring → Security
Events and check three things on the multipart case:
payload, and not the multipart envelope(value withheld: sensitive parameter) instead. The decision is on the
If every case fails, including the clean request, the requests are being
stopped before any payload is looked at. Check the event's rule: it will be
Bad Bot, a firewall rule or geo-blocking rather than an injection rule. The
script sends a browser's headers for exactly this reason — curl/8.x announces
itself and bot detection refuses it on that alone, at which point every case
comes back 403 for a reason that has nothing to do with what it was carrying.
Once it is quiet, three habits keep it that way:
After a fortnight of steady traffic, WAF → Learned Rules begins proposing rules built from your own application's habits — "user_id is always a whole number of 1 to 6 digits". Accepting one only measures it; it blocks nothing until you have the evidence and say so.
Full detail: Learned Rules.
Worth knowing once, because it explains most surprises:
An earlier step ends the request. So an allowlisted address is never inspected, a firewall Allow skips every detection that follows it, and a rule you expected to fire may simply never have been reached.
| The console, screen by screen | Dashboard Guide |
| Your own block/allow/challenge rules | Firewall Rules |
| The detection rules and how scoring works | Rules & Rulesets |
| Recording a rule that was wrong | False Positives |
| Rules learned from your traffic | Learned Rules |
| Addresses, limits, bots, paths, pages | IP Lists · Rate Limits · Bot Management · Path Rules · Response Pages |
| The fleet | Agents · Threat Intelligence |