Fields
A field determines which property of the request a rule inspects: the visitor’s IP, the page they asked for, their bot score? Every condition follows the IF {field} {operator} {value} syntax. The 30 fields fall into five categories; to pick the right one, ask:
- “Who is asking?” → Network (IP, country, ASN) or Bot & Threat (bot score, VPN/Tor)
- “What are they asking for?” → HTTP Request (path, method, header, cookie)
- “What did the origin answer?” → HTTP Response (status code — for auto-banning)
The names in the tables match the labels you see in the console’s field menu exactly, and link to each field’s own reference page. The Key column is the field’s technical name — conditions appear under these names in the console’s Rule Preview section.
Network
Section titled “Network”Targets the source of the request: a single IP, an IP range, a predefined IP list, an autonomous system (ASN) or a country. These are the core tools for geo restriction, trusted-IP exemptions and filtering datacenter traffic.
| Field | Key | What it does |
|---|---|---|
| IP Address | ip.src | Targets a single IP — accepts plain IPv4/IPv6 only; use ip.prefix for CIDR |
| IP Range (CIDR) | ip.prefix | Targets CIDR blocks (like 10.0.0.0/8) — office networks, cloud provider ranges |
| IP List | ip.list | Membership in a named list you define on the IP Lists page — update the list, all rules follow automatically |
| ASN Number | ip.asnum | The autonomous system the IP belongs to — target a hosting company’s entire range with one condition |
| Country | ip.country | The IP’s country (ISO 3166-1 alpha-2: TR, DE…) — the basis of geo restriction |
Operators: == != in not_in — ip.list accepts only in / not_in; ip.asnum additionally supports numeric comparison (gt ge lt le).
# Block a single countryIF ip.country == RUTHEN block
# Allow IPs on a named listIF ip.list in "office-ips"THEN allow
# Allow an internal network blockIF ip.prefix == 10.0.0.0/8THEN allowWith these selections in the console:
- Block a single country — Field Country · Operator equals · Value
RU→ Action Block - Allow IPs on a named list — Field IP List · Operator in list · Value
office-ips→ Action Allow - Allow an internal network block — Field IP Range (CIDR) · Operator equals · Value
10.0.0.0/8→ Action Allow
HTTP Request
Section titled “HTTP Request”Targets the content of the request: which hostname, which path, which method, which headers. These are the tools for path-based protection (e.g. /admin), API checks and User-Agent filtering.
| Field | Key | What it does |
|---|---|---|
| Host (Domain) | http.host | The requested hostname — to distinguish subdomains within the same WAF zone |
| HTTP Method | http.request.method | GET, POST, PUT… — e.g. tighten write requests only |
| Path (without query) | http.request.base_uri | The full path without the query (/admin/login) — the primary field for path-based rules |
| Last URI Segment | http.request.uri.path | The last segment of the path (/admin/login → /login) — file-name targeting; use base_uri for the full path |
| Query Parameters | http.request.uri.query | The part after ? — parameter-based filtering |
| URI (with query) | http.request.uri | Path + query together |
| Full URI (host+path) | http.request.full_uri | The complete address including the host |
| HTTP Version | http.request.version | 1.0, 1.1, 2, 3 — suspicious clients on legacy protocols |
| Header | http.header | Checks any header as name=value — API key or custom header validation |
| Cookie | http.cookie | Presence/value of a specific cookie — distinguishing logged-in users |
| User Agent | http.user_agent | Browser/bot identity — blocking known bad tools by name |
| Referer | http.referer | The page the request came from — hotlink prevention |
| X-Forwarded-For IP | http.x_forwarded_for | The client IP header in a proxy chain |
| TLS Version | tls.version | The connection’s TLS version — restricting old/insecure clients |
Operators: == != in not_in contains not_contains has_prefix has_not_prefix has_suffix has_not_suffix — exceptions: http.request.method and http.request.version accept only equality + list (== != in not_in); tls.version additionally supports numeric comparison (gt ge lt le). String comparisons are case-sensitive.
# CAPTCHA for the admin panelIF http.request.base_uri has_prefix /adminTHEN captcha
# Block a known bad toolIF http.user_agent contains BadBotTHEN block
# Rate limit login POSTsIF http.request.method == POSTAND http.request.base_uri == /loginTHEN ratelimit 10/60s
# Reject requests without an API keyIF http.header not_contains X-Api-KeyAND http.request.base_uri has_prefix /apiTHEN blockWith these selections in the console:
- CAPTCHA for the admin panel — Field Path (without query) · Operator starts with · Value
/admin→ Action CAPTCHA - Block a known bad tool — Field User Agent · Operator contains · Value
BadBot→ Action Block - Rate limit login POSTs — Field HTTP Method · Operator equals · Value
POSTAND Field Path (without query) · Operator equals · Value/login→ Action Rate Limit (10 requests / 60 s) - Reject requests without an API key — Field Header · Operator does not contain · Value
X-Api-KeyAND Field Path (without query) · Operator starts with · Value/api→ Action Block
Bot & Threat
Section titled “Bot & Threat”Uses the intelligence signals HEIMWALL produces for every request: is this a bot, which bot, how suspicious, is it behind a VPN or Tor? These fields free you from relying on easily spoofed values like the User-Agent.
| Field | Key | What it does |
|---|---|---|
| Known Bot | waf.client.bot | Is the client a verified bot (on/off) — identity-confirmed bots like Googlebot |
| Bot Name | waf.client.bot_name | The verified bot’s name (googlebot… — lowercase) — targeting one specific bot |
| Bot Category | waf.client.bot_category | The bot’s function (search, SEO, AI…) — allow/block by category |
| Bot Score (0–100) | waf.bot_score | 0–100 behavioral score (0 = human, 100 = bot) — catches unverifiable automation |
| IP Infrastructure Type | waf.client.ip_type | The IP’s origin: home user or datacenter? The hosting type is a strong automation signal |
| VPN | waf.client.vpn | Known VPN exit (on/off) |
| Proxy | waf.client.proxy | Known open proxy (on/off) |
| Tor | waf.client.tor | Tor exit node (on/off) |
| Private Relay (Apple) | waf.client.relay | Apple iCloud Private Relay (on/off) — a legitimate privacy service; think before blocking |
Bot categories (17): search seo ai_crawler ai_assistant ai_search advertising social monitoring preview feed aggregator archiver security accessibility academic webhook other
IP types (6): residential mobile business hosting education government
Operators: category/type fields (bot_category, ip_type) take == != in not_in; bot_name additionally contains; on/off signals (bot, vpn, proxy, tor, relay) only == !=; waf.bot_score only numeric comparison (gt ge lt le).
# CAPTCHA for suspicious behaviorIF waf.bot_score ge 60THEN captcha
# Block verified bots outside search/SEO/monitoringIF waf.client.bot == onAND waf.client.bot_category not_in search, seo, monitoringTHEN block
# Challenge foreign VPN trafficIF waf.client.vpn == onAND ip.country not_in TRTHEN captcha
# JS challenge for API requests from datacentersIF waf.client.ip_type == hostingAND http.request.base_uri has_prefix /apiTHEN jsWith these selections in the console:
- CAPTCHA for suspicious behavior — Field Bot Score (0–100) · Operator greater or equal · Value
60→ Action CAPTCHA - Block verified bots — Field Known Bot · Operator equals · Value Yes AND Field Bot Category · Operator not in list · Value
search, seo, monitoring→ Action Block - Challenge foreign VPN traffic — Field VPN · Operator equals · Value Yes AND Field Country · Operator not in list · Value
TR→ Action CAPTCHA - JS challenge for datacenter API requests — Field IP Infrastructure Type · Operator equals · Value
hostingAND Field Path (without query) · Operator starts with · Value/api→ Action JS Challenge
HTTP Response
Section titled “HTTP Response”Targets what your origin server answered. It has a single purpose: automatically banning clients that generate errors — e.g. an IP collecting consecutive 401s is most likely guessing passwords.
| Field | Key | What it does |
|---|---|---|
| Origin Response Status | http.response.status | The HTTP code the origin returned — brute-force detection via 401/403/404 counters |
| Origin Response Header | http.response.header | A header in the origin response — catching requests your application flags |
# Count unauthorized attempts toward failbanIF http.response.status == 401THEN failban
# Count all 4xx errorsIF http.response.status ge 400AND http.response.status lt 500THEN failbanWith these selections in the console:
- Count unauthorized attempts — Field Origin Response Status · Operator equals · Value
401→ Action Auto-Block (the console locks the action automatically for these fields) - Count all 4xx errors — Field Origin Response Status · Operator greater or equal · Value
400AND Operator less than · Value500→ Action Auto-Block
Next steps
Section titled “Next steps”- Which operators are valid per field type: Operators
- What to do with a matching request: Actions
- Ready-made rule patterns: Rule Examples