WAF Rule Pipeline
248 production rules across 30 threat classes — evaluated in two phases with a single canonical 403 exit. Deferred rules see what the body-phase pass can't.
Evaluation Pipeline — Body Phase · Deferred Phase · Verdict
STAGE 01
Index Candidates
RuleIndex narrows 248 rules to the candidate subset for this request via cached keys & regex groups.
PREFILTER
STAGE 02
Body-Phase Pass
Evaluates all rules except those whose match kinds need data not yet available (dlp_violation).
MAIN PASS
STAGE 03
DLP Scanner
Async body scan produces dlp_violation findings. Gates the deferred pass.
ENRICH
STAGE 04
Deferred Pass
Re-evaluates only deferred_rule_indices — the rules skipped in stage 02 — now with DLP data in scope.
POST-DLP
STAGE 05
Verdict → 403
Any blocking match exits through the single canonical WAF block response. Non-blocking matches add risk.
EMIT
Why two phases?
Some rules (dlp_violation match kind) need scanner output that isn't available during the synchronous body pass. Rather than blocking the pipeline, those rule indices are tracked in deferred_rule_indices, skipped via an O(1) HashSet in the body pass, and re-evaluated once DLP completes — so the main pipeline stays fast.
Top Threat Classifications — 248 Rules Across 30 Classes
How Rules Match — Match Kind Distribution
dlp_violation · deferred
7
Blocking vs Observational Rules
62
Blocking Rules · 25%
Trigger an immediate canonical 403. Reserved for high-confidence signatures: known exploits, confirmed toolkits, active injection patterns.
186
Observational Rules · 75%
Contribute to the actor risk score without blocking directly. Feeds the risk lifecycle — repeated low-confidence hits accumulate into challenge or block decisions.
Canonical Block Response — One Exit Point
RESPONSE BODY (STABLE)
{"error": "access_denied"}
GUARANTEE
Byte-identical output from every block site — body-phase, deferred, or future additions — via send_waf_block_response. Clients that parse the shape depend on it; treated as an API contract.
RESPONSE HEADERS
:status403
content-typeapplication/json
content-length22
x-request-id<echoed>
strict-transport-security<https only>
+ security headersX-Frame, CSP, …