Policy & sites
Configuration live
Policy is the JSON contract the control plane writes and the data plane reads. It decides, per site, what is enabled, how strict the thresholds are, who is allowed in, and how the edge behaves. Zero-valued fields are back-filled to safe defaults at load time, so a minimal policy is valid.
The policy object
| Field | Meaning |
|---|---|
version |
Monotonic counter — anti-rollback anchor for hot-reload |
enforce |
false = monitor/shadow (never blocks), true = enforce |
thresholds |
Decision cutoffs per tier (below) |
engines |
map[string]bool per-engine enable; an absent key means enabled |
access |
Allow/deny + rate controls |
custom_rules |
Operator-defined detection rules |
edge |
Edge behavior (forwarded headers, challenge, response hardening) |
Engine keys: sql, xss, ssrf, cmdi, traversal, header, protocol, api, rate, auth,
ssi, upload, overflow, ssti, deserialize, nosql.
Thresholds
The decision tiers, Allow < Monitor < Throttle < Challenge < Block < Drop, with
defaults:
| Tier | Default score |
|---|---|
monitor |
150 |
throttle |
400 |
challenge |
700 |
block |
1200 |
drop |
2500 |
decisive |
700 |
decisive is not a tier but an escalation: when one finding's weighted
contribution clears it, the action is floored at Block without waiting for the
sum. Omit it for the default; set it to 0 to switch escalation off.
Lower a site's thresholds to make it stricter. See Risk & decision for how the score is built.
Access control
Runs before detection; an allowlist entry can bypass the WAF, a denial short-circuits to a block.
| Field | Meaning |
|---|---|
allow_ips / block_ips |
IP and CIDR lists |
allow_cc / block_cc |
ISO-2 country lists |
rate |
{ per_sec, burst } per-client rate limit |
auto_ban |
{ trips, window_sec, ban_sec } adaptive auto-ban |
Edge behavior
| Field | Meaning |
|---|---|
set_forwarded / forwarded_proto |
Inject Forwarded / X-Forwarded-* toward origin |
response_headers |
Hardening: hsts, content_type_options, frame_options, referrer_policy, csp, csp_report_only, permissions_policy |
security_txt |
Served at /.well-known/security.txt |
challenge_difficulty |
Site-wide PoW leading-zero bits; 0 = engine default |
challenge_all |
Proof-of-work wall on every first request (Anubis-style) |
challenge_routes |
[{ prefix, difficulty }] — force PoW on path prefixes regardless of score. Matched against the resolved path: /%61dmin, /./admin, //admin, /x/../admin and /admin;jsessionid= all match /admin, because the origin's router resolves them there too |
Custom rules
Extend detection without writing Go. Each rule adds its score to the request when
it matches.
| Field | Meaning |
|---|---|
id |
Rule id |
name |
Human label |
target |
any / path / query / param / header / body |
match |
contains / equals / prefix / regex (RE2) |
pattern |
The pattern (1–4096 chars) |
field |
Narrowing name for param / header targets |
score |
Risk weight added on a hit |
nocase / enabled |
Case-insensitive · on/off |
Multiple sites
A sites file routes by Host header to a per-site origin and policy, so one
engine protects many sites:
SiteDef—{ id, name, domains[], origin, policy }default_origin/default_policy— fallback for unmatched hostsglobal— install-widemax_rps+burst(L7 overload shed / anti-DDoS)feed— a curated signed-feed layer (rules + reputation) merged on top of every site's policy; it is managed only by the feed tooling and the GUI can never drop a feed rule.
Example
{
"version": 12,
"enforce": true,
"thresholds": { "challenge": 600, "block": 1000 },
"engines": { "rate": true, "auth": true },
"access": {
"block_cc": ["KP"],
"rate": { "per_sec": 50, "burst": 100 },
"auto_ban": { "trips": 5, "window_sec": 60, "ban_sec": 900 }
},
"edge": {
"challenge_routes": [{ "prefix": "/login", "difficulty": 18 }],
"response_headers": { "hsts": true, "frame_options": "DENY" },
"security_txt": "Contact: mailto:security@example.com"
},
"custom_rules": [
{ "id": 5001, "name": "block admin probe", "target": "path",
"match": "prefix", "pattern": "/wp-admin", "score": 800, "enabled": true }
]
}
This site enforces, challenges /login hard, rate-limits and auto-bans abusive
clients, hardens responses, and adds one custom rule — all hot-reloaded without a
restart.