Rules & Rulesets is the detection itself: the OWASP Core Rule Set, EdgeGuard's own rules, and any you write. Unlike a firewall rule, these do not decide alone — each match adds a score, and the request is refused when the total crosses the site's threshold.
A request that survives the earlier steps — path rules, IP lists, threat intelligence, geo, firewall rules, bots, rate limits — reaches the rulesets. Then:
So a rule scoring 5 blocks on its own at the default threshold, and two rules scoring 3 block together. This is why raising the threshold is a blunt instrument: it does not make one noisy rule quieter, it makes every combination harder to reach.
Static assets skip this step. A plain file fetch has no injection surface, and the regex work is the most expensive thing the engine does, so the fast path leaves it out.
Paranoia levels. Every rule carries one. PL1 rules always run; a rule at PL2 or above runs only if the site's CRS Paranoia Level is at least as high. PL1 is the default and is what you should stay on until you have time to tune: PL2 and above trade false positives for coverage, deliberately.
Category switches win. Turning a category off in Global Settings → Attack Detection silences both EdgeGuard's own matchers and the CRS rules of that category — including when a path rule turns it off for one path. Without that, disabling "RCE detection" would silence the built-in detector while CRS 932xxx kept scoring, and the request would stay blocked for a reason the setting appeared to cover. Categories with no switch — protocol, Log4Shell, custom — always evaluate.
There is a time budget. A crafted input can make many rules backtrack; the engine stops evaluating early, keeps what it found, and records that it did, rather than spending a core on one request.

One card per ruleset. Each shows the source (owasp-crs), its category tag (sqli, rce, lfi, protocol, data_leakage…), the CRS version it came from, how many rules it holds, how many times it has matched, and whether it is enabled.
The filter buttons above narrow the list by category: All, SQLi, XSS, CMDi, RCE, LFI, SSRF, XXE, SSTI, NoSQLi, Open Redirect, Header Inj., Deserialization, Log4Shell, Protocol, Custom.
The hits figure is the one worth reading. Twenty-nine rulesets are loaded and they overlap heavily; the count is what tells you which earn their place and which have never matched anything on your traffic.
Expand a card to see its rules:

| Column | Meaning |
|---|---|
| ID | the CRS rule number — 942100, 942140… This is the number that appears in an event and in an exclusion |
| NAME | what it detects, e.g. SQL Injection Attack Detected via libinjection |
| PATTERN | the regular expression, or @detectSQLi for the libinjection detector |
| TARGETS | which part of the request it reads: uri, query, args, body, or all |
| ACTION | what it contributes — most are block, meaning "add score toward a block" |
| SEVERITY | critical, error, warning, notice — which is what the score derives from |
| ENABLED | a single rule can be switched off without touching the rest of its ruleset |
Switching off one rule is almost always better than switching off its category, and writing an exclusion for it is better still — see False Positives.

The same protection read the other way round: A01 through A10, and what covers each. This is the view to bring to an auditor, and the quickest way to notice that a category you switched off has left a gap in the Top 10.

The engine fetches updated rule definitions on a schedule; the Artica EdgeGuard feed is always included.
The current feed version is shown on each ruleset card, so you can tell at a glance whether an agent is running rules from last month.

Click Create Ruleset.
Test every pattern against something that should not match. A regular expression that matches everything looks identical to protection until the first complaint. The Test box exists for exactly this, and it costs ten seconds.
Cost. Your pattern runs on every request that is not a static asset. Avoid nested quantifiers ((a+)+), prefer anchored and specific expressions, and keep the target as narrow as the attack allows — a rule that only makes sense in a body should not read the URI.
1. Does the rule match what you meant? Use Test in the builder before saving.
2. Does it fire on real traffic?
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/?id=1%20UNION%20SELECT%20password%20FROM%20users"
3. What did EdgeGuard think? Open the newest row in Security Events. The detail panel names every rule that matched, what it matched on, the accumulated score and the threshold it was compared against. If the request was allowed, the score will tell you how close it came.
4. Is the ruleset doing work over time? The hits figure on its card, and the Rule Coverage table on Analytics, which lists rules that are firing and rules that are silent in this window.
The False Positive Rate Estimate table on Analytics is the evidence for which of these you need: it shows, per rule, how many events it produced and how many a person marked as false positives.
Learning mode (Global Settings → General → WAF Operating Mode) is the safe way to introduce a stricter setting: everything is detected and logged, nothing is refused, and the Analytics tables then tell you what would have happened.