Scoring and integrity tests

Scores

combinedBlockingScore sums the blocking contributions of participating rulesets; combinedDetectionScore sums the rest. A retained finding’s configured score is not necessarily a contribution to either sum: a Challenge finding contributes zero. A reported threshold-exceeded result can describe a Detection-mode ruleset’s hypothetical result and is not itself proof that a response was blocked.

See WAF scoring and paranoia levels for blocking and detection scores, scoring modes, thresholds and paranoia levels. Event exports filter on the actual combined blocking score, so a positive minimum excludes events whose findings are all detection-only or Challenge actions.

Other inspection stages

Each WebSocket message has its own transaction and request-style scoring threshold. An inspected response retains its request method, path and origin for request-dependent comparisons and conditional exclusions. See Inspected traffic for response scoring and stream limitations.

Challenge actions

action: "Challenge" adds no score. A retained matching Challenge rule can trigger a challenge only when it is within the blocking paranoia level, its ruleset is effectively in Prevention, and the route’s challenge policy is enabled and eligible. It does not override an ordinary WAF block. Responses and WebSocket messages do not serve challenge pages. In Combined mode, a configured suspicious-score threshold can also trigger a challenge from scoring matches. See Bot challenges for HTTPS, request eligibility, clearance and fallback behavior.

Integrity test vectors

An integrityTests entry declares a unique id, profileId, optional inspectionStage (default RequestMetadata), optional paranoiaLevel (default 4), fields and expectedMatchedRuleIds. Each field supplies target, value, and optional name and group. Tests compare the exact set of retained matched rule IDs; they do not merely check that one expected rule appeared. Budget exhaustion or truncated findings fails the vector.

Use method, path and origin: { "scheme": "https", "host": "example.com" } when behavior depends on the original request. Omitted method/path are GET and /; ordinary request test metadata uses HTTPS and a reserved integrity-test host by default. For response and WebSocket origin comparisons, supply the origin explicitly. For RequestBody vectors, optional metadataFields supplies the original request’s metadata alongside body fields. The runner inspects metadata first and compares cumulative request matches after the body stage. These are field vectors, not raw HTTP parser tests; the custom-rule tester preserves this context when generating vectors from parsed inputs.

A release may contain at most 1,024 vectors, 64 fields per vector and 16,384 fields total, counting metadataFields together with fields. Include an expecting vector for every scoring rule before distributing a release. Gateways run embedded integrity tests before accepting a release; a failing release is not activated. Local publication also runs its vectors.

For an Exclusion ruleset, rulesetId selects the other ruleset under test. method and path supply the exclusion’s request scope. expectedMatchedRuleIds describes matches with the exclusion enabled, and expectedSuppressedRuleIds is the exact difference from running without it. Vectors targeting an inactive ruleset are skipped until that target is active. An embedded exclusion vector must expect a retained match or a suppressed rule. This allows boundary vectors to prove that a request outside the exclusion still matches. Cloud publication requires positive suppression coverage for every exclusion; boundary vectors alone do not satisfy that gate. The WordPress example verifies the selected path; include outside-path and method-boundary controls as well.