CHALLENGE SUSPICIOUS TRAFFIC WITH A CLOUDFLARE FIREWALL RULE
This guide shows you how to add a Cloudflare firewall rule that sends matching requests to a managed challenge, confirm the rule exists, and pause it later without deleting it.
Prerequisites
- A Cloudflare API token with Firewall read and write permission for the zone,
stored in a vault named
cloudflareunder the keyCLOUDFLARE_API_TOKEN(see Storing Secrets) - The zone's ID, from the zone's overview page in the Cloudflare dashboard
Pull the extension
swamp extension pull @webframp/cloudflareThe output looks like:
INF extension·pull: Pulling "@webframp/cloudflare"@"2026.10.14.1"
INF extension·pull: Identity verified: "@webframp/cloudflare"@"2026.10.14.1"
INF extension·pull: Pulled "@webframp/cloudflare"@"2026.10.14.1"
INF extension·pull: Extracted 14 files:Define the WAF behavior
Create a @webframp/cloudflare/waf behavior named cf-waf (see
Create and Run a Behavior)
with these global arguments:
globalArguments:
apiToken: "${{ vault.get('cloudflare', 'CLOUDFLARE_API_TOKEN') }}"
zoneId: "023e105f4ecef8ad9ca31a8372d0c353"Create the rule
Pass the match condition as a Cloudflare rules expression. This example challenges requests for a login page:
swamp behavior run cf-waf create_rule \
--input 'expression=http.request.uri.path contains "/wp-login.php"' \
--input action=managed_challenge \
--input 'description=Challenge login page requests'This creates the rule on the zone and writes it to the rule resource.
To stop matching requests instead of challenging them, use action=block. To
record matches without acting on them, use action=log. The optional priority
input is a number, and paused is a boolean. Pass both with the :json=
suffix, for example --input 'paused:json=true' to create the rule paused.
Confirm the rule and find its ID
swamp behavior run cf-waf list_rulesThis fetches every firewall rule on the zone and writes the list to the rules
resource. Copy the new rule's ID from it.
Pause the rule
Pause the rule when you want it to stop acting but want to keep its definition.
Replace the ID with the one from list_rules:
swamp behavior run cf-waf toggle_rule \
--input ruleId=372e67954025e0ba6aaa6d586b9e0b59 \
--input 'paused:json=true'This sets the rule to paused on Cloudflare and writes the updated rule to the
rule resource. To turn the rule back on, run the same command with
'paused:json=false'. To remove the rule entirely, run delete_rule with the
same ruleId.
Review the challenges issued
swamp behavior run cf-waf get_security_events \
--input 'limit:json=20'This fetches the 20 most recent security events for the zone, including blocks
and challenges, and writes them to the events resource.
To put an approval step in front of rule changes, see Gate a Workflow with Manual Approval.