Firewall Rules are your own rules: block, allow or challenge a request because of where it came from, what it asks for, or what it claims to be.
They are evaluated before any attack detection, and the first one that matches decides.
Nothing else in EdgeGuard overrides them.
This page covers what they can match on, where they sit in the decision, how to write one, and how to prove it works.
Screenshots come from a live installation.
Site names and addresses have been replaced with documentation equivalents (example.com,203.0.113.x).
A request is examined in a fixed order, and the first rule that decides ends it:
Two consequences worth holding on to. A firewall rule cannot rescue a request already refused by an IP list or by geo blocking, because those run first.
And an allow rule ends the examination completely: nothing after step 6 ever sees that request.

Four counters at the top say how many rules exist and at which scope: All Rules, Global, Group, Tenant.
| Column | What it tells you |
|---|---|
| PRIO | evaluation order. Higher is evaluated first |
| ACTION | Block, Allow, Challenge, Log Only |
| NAME | and its description underneath |
| MATCH CONDITIONS | every condition the rule carries, as tags. A rule with none matches all traffic |
| TENANT | the scope: Global, a group, or one site |
| HITS | how much work it is doing — see below |
| STATUS | Enabled, Disabled, Expired, or "until <date>" when an expiry is set |
12 189 Matched — the rule matched that many requests. Hover for when it last did.574 Skipped, in amber — an allow rule, and the number is how many requests skipped the WAF entirely because of it. Amber because that is a hole, and the number is its size.none yet — the rule has never matched. Either nothing looks like that, or the rule does not say what its author thought it said.A rule nobody can measure is a rule nobody can retire.
Before widening a rule that "isn't working", check whether it has ever matched:none yetusually means the conditions are narrower than intended, not that the traffic is absent.

Block Russia. RU,CN,IR, @EU,@AS, @eu27. ! to negate: !FR,PT is everyone except France and Portugal, !@EU everyone outside Europe. @ matters more than it looks — see Countries, continents and groups below.* for all, /admin/* for a prefix, or an exact path.["10.0.0.0/8","192.168.0.0/16"].curl or python-requests. Not a regular expression.AS64512,AS15169, with or without the AS prefix. The way to catch a whole hosting provider without listing its ranges.| Action | What happens |
|---|---|
| Block | the request is refused with your response code, and the event is recorded with the rule's name |
| Allow | the request is allowed and skips every remaining check — detection, bots, rate limits, everything |
| JS Fingerprint | a silent JavaScript challenge; a real browser passes it without noticing |
| Smart Challenge | a managed challenge, escalating by risk |
| Slider Puzzle | an interactive challenge for a human to solve |
| Log Only | nothing changes for the visitor; the match is recorded. This is how you try a rule before trusting it |
Allow is the one to be careful with.
It does not mean "this is fine" — it means "stop inspecting".
A path that is allowed is unprotected against everything, including attacks nobody has thought of yet.
Prefer a Log Only trial, a narrow exclusion on the False Positives page, or a path rule;
reach for Allow when you genuinely mean do not inspect this.
The console says so out loud: when any allow rule exists, a banner appears above the pages — "N firewall rules are letting traffic past the WAF" — with a link to the list of them.
It is deliberate, and it does not go away while the rules exist.

Each row carries four controls:

Expiry.
A rule can carry an expiry date, and the list shows it as until <date>, then as Expired.
An expired rule stops matching immediately
The engine checks the expiry again on every request, not only when it loads the rules, so a rule cannot outlive its date by a caching window.
Expiries are set by the flows that create temporary rules (the Allow IP quick action on an event, and auto-containment); the Add dialog itself creates rules without one.
Most rules should not be written from scratch.
Open the block in Security Events, and the panel offers Create rule from event, which fills the conditions in from the request that prompted it and asks which of three instruments you want:
Start at the top of that list. Come down one step only when the narrower instrument cannot express what you learned.

1. Is it live?
The list shows Enabled; give the agents 30 seconds.
2. Does it match what you meant?
Send a request that should match:
curl -o /dev/null -w '%{http_code}\n' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/140.0.0.0' \
"https://site.example.com/admin/"
A blocking rule answers 403; a challenge answers 200 with a challenge page; Log Only answers whatever the origin would.
3. Did EdgeGuard agree it was your rule?
Open Security Events and look at the newest row: the attack column reads the rule's name, and the detail panel shows firewall_rule as the reason.
Every block page also carries an EdgeGuard ID — paste it into the global search to find that exact request.
4. Is it doing work over time?
The HITS column. none yet after a day on a busy site means the conditions are not matching what you think.
A country condition accepts three kinds of token, mixed freely in the same field.
| You write | It means |
|---|---|
PT, RU, CN |
that country, by its ISO 3166-1 alpha-2 code |
@EU, @AS, @AF, @NA, @SA, @OC, @AN |
that continent, as the GeoIP database reports it |
@eu27, @gcc, @asean, @schengen, … |
a named country group, defined under Country Groups |
RU,CN,@AF,@eu27 is a single valid list. The leading ! negates the whole list, not one token: !@EU,PT reads not in Europe and not Portugal.
The @ is not decoration
Four continent codes are also real country codes:
| Code | As a country | With the @ |
|---|---|---|
AF |
Afghanistan | @AF Africa |
AS |
American Samoa | @AS Asia |
NA |
Namibia | @NA North America |
SA |
Saudi Arabia | @SA South America |
So a rule written to block North America as a bare NA blocks Namibia instead, and you find out from a customer.
Two bare letters are always a country.
A continent always carries the @.
A continent needs no configuration:
The lookup that already resolves the country resolves the continent at the same time, so @EU costs nothing and can never fall out of date.
A group is a list somebody maintains, which is why groups live in one place and expand on screen.
They are not interchangeable.
@EU is the continent Europe — Norway, Switzerland and the United Kingdom included.
@eu27 is the European Union, which excludes all three, and includes Cyprus, which the database places in Asia.
Choose by the question you are actually asking: a legal boundary is a group, a rough geographic sweep is a continent.
@nosuchgroup matches nothing — it does not fall back to being read as a country code, and it does not match everything.
The same is true the moment you delete a group a rule still refers to: the rule stops matching rather than starting to match all traffic.
That is the safe direction, but it is silent, so delete a group only after searching your rules for its name.
Continent tokens and country groups need engine 3.0.31 on the edge and central 2.4.21.
An older engine reads@EUas a country code that does not exist, and matches nothing.
Block a country, except your own offices.
Countries RU,CN, IP Ranges with your office ranges is not how to do it — conditions are AND, so that would mean "Russian and in the office".
Instead write two rules: an Allow at high priority for the office ranges, and a Block at lower priority for the countries.
Priority is what expresses "except".
Let an uptime monitor through.
IP Ranges of the monitor and a User Agent substring only it sends, action Allow, scope the one site, high priority.
Two conditions rather than one, so an attacker who guesses the address still does not match.
Slow down a scraper you do not want to block.
User Agent substring or ASN of the hosting provider, action Slider Puzzle, scope global.
A person who really wants the page can solve it; a scraper usually cannot.
Serve one continent only.
Countries !@EU, action Block, scope the one site.
One token instead of every country outside Europe, and it stays correct when the database gains one.
Try before you trust.
Write the rule with action Log Only, leave it a day, then read the HITS column and the events it produced.
If it matched what you expected and nothing else, change the action to Block.