Write custom WAF rules
Use Firewall → Custom rules to write your own rulesets. Drafts, testing and publishing work with Cloud integration off and need no Cloud account.
Before you start
You need WafRulesets.Read to open and test the draft, WafRulesets.Write to save changes, and WafRulesets.Manage to publish. Choose a route on which you can check both normal traffic and the behavior you want to detect.
The first draft is a template with the required standard and management profiles, default work limits, one example rule and two integrity tests. Saving keeps your text even when it has validation issues. A saved draft does not change Edge's active rules.
Several rulesets
Custom rules are not limited to one ruleset. The Rulesets selector on the page lists every draft you have, and each one publishes, activates and rolls back independently, so a change to rules for one application cannot disturb another.
Identifiers are reserved: a draft is either the original local or starts with local-, such as local-wordpress. Clearplane refuses any other identifier, because that prefix is what tells the gateway a ruleset is yours and may arrive unsigned. A signed Cloud ruleset can never take an identifier in that range, and an unsigned one can never take an identifier outside it.
Deleting a draft removes only the draft. A release you already published from it keeps running until you deactivate it on the Rulesets page.
Copy a rule as a starting point
Rather than write a rule from nothing, copy one from an installed ruleset into a draft and edit it. The copy is appended with a fresh rule identifier and added to the draft's profiles, and it keeps the source rule's provenance and licence.
Attribution follows the rule, not the ruleset it arrived in. A rule adapted from an upstream project keeps its upstream reference, so copying it through Clearplane does not obscure where the logic came from; a Clearplane-authored rule records the ruleset and version you copied it from. When a copy brings in material under a different licence, the draft's own licence is restated to name it, in the same form the shipped rulesets use — for example Proprietary; includes Apache-2.0 material from OWASP CRS. Publishing a draft therefore publishes an accurate licence for what it actually contains.
Copying requires WafRulesets.Manage. It is the one way rule patterns become visible to an operator: browsing rulesets with WafRulesets.Read still never exposes rule patterns, signed envelopes or signatures. Treat a draft holding copied rules as carrying whatever licence the source rule carried, which may not be the same as the rest of the draft.
Write a rule
The template scores requests containing a __debug query parameter. Its rule targets QueryName, lowercases it, and compares it with __debug:
"conditions": [
{
"targets": [{ "target": "QueryName" }],
"transformations": ["Lowercase"],
"operator": { "kind": "Equal", "value": "__debug" }
}
]
Keep this condition inside the template's rule object. Rule 1 uses RequestMetadata, paranoia level 1 and score 5, and both profiles include its ID. With the draft published, its ruleset and the route's WAF policy in Prevention, and a blocking threshold of 5, /?__debug=1 reaches the threshold. In Detection, it records a match while allowing the request.
Change the rule's message and conditions for your application. Include each rule ID in the profiles that should run it. Save the draft to see compiler issue codes and locations.
Test the draft
Choose Request, WebSocket message or Response, then set the input, profile and paranoia levels. Scheme, host, method and path describe the originating request; a request input's Host header takes precedence over the host field. Response inputs also take a status code and response headers. Use base64 for byte-exact bodies or binary WebSocket messages.
Run the template against /?__debug=1, then against /?q=hello. Review the parsed fields, matched rule IDs, reasons, fingerprints, blocking score and detection score. Rules above the blocking paranoia level can contribute to the detection score without raising the blocking score.
Token view previews a detector defined in your draft, including its tokens, grammar classes, assigned classes and fingerprints. Run integrity tests reports every stored test's expected and actual rule IDs.
Save as test inserts the tested fields and expected matches into the editor. Save the draft again to store them. The action is available only when the input can be replayed faithfully within integrity-test limits. Work-budget exhaustion, truncated findings, oversized fields or input that cannot be represented suppress the generated test and report an issue. Changing the editor after a run requires another run before inserting its results.
The raw request tester does not support framed gRPC or gRPC-Web inputs; these return unsupported-grpc-test-input. Test those protocols against an isolated protected application. The tester evaluates the draft; route policy, other active rulesets, transport streaming and deployment behavior still need an application-level check.
Testing, token preview and publishing first save any changed editor text. A failed save keeps the text and stops the action. If another operator changed the draft, reload and reconcile your changes before saving again.
Publish
Every integrity test must pass, and at least one must exist. Select Publish, review the draft revision and choose Detection or Prevention. Publication checks both the reviewed draft revision and the activation generation, so a stale dialog cannot silently publish newer draft text or overwrite an unseen activation.
Follow the activation on Firewall → Rulesets, then verify normal and matching requests on the chosen application. Promotion, rollback and deactivation are available there. Update strategies never apply to local. See WAF rulesets and scoring and paranoia levels.
Limits
Local rules use the same validated language and bounded engine as signed rulesets.
Editing through a protected Core route
Drafts and tester inputs can contain attack examples. If WAF inspection is enabled on Clearplane's own Core route, those inputs pass through it and may be scored or blocked before reaching the editor API. Keep that route's WAF policy in Detection while editing, or apply a narrowly scoped exclusion for the affected Core API input. Keep normal management access controls in place.
Read unsigned local rules for the Core-to-Edge trust boundary.
Use the WAF rule language reference for the document format, field scope, operators and tested examples.