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 hosts
  • global — install-wide max_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.