Firewall policies and the kill switch
A policy is an ordered list of rules (up to 100 per site). RevokeGPT signs the list into a bundle; every firewall integration fetches it, verifies the signature offline and enforces it identically. It is part of the Business plan.
When to use it
Section titled “When to use it”Use a policy when you want to protect paths without changing your application code: a login path that needs a token, an admin area that needs a challenge page, a scraper-prone API that should be blocked below a score. For one form in your own code, siteverify is simpler.
How it works
Section titled “How it works”- You write rules in the dashboard (Firewall). RevokeGPT validates and signs them into a bundle.
- An integration (Cloudflare Worker, Fastly, Lambda@Edge, OpenResty, a Node, Python, Go, PHP or Java middleware) fetches
GET /v1/policies/{siteKey}about every 60 seconds, with anETag(a matchingIf-None-Matchgets 304). - It verifies the Ed25519 signature against keys pinned in the integration, never trusting the transport.
- For each request it runs the rules from top to bottom. The first terminal action that matches wins.
An unknown site and a site with no published policy are the same 404 not-found. If you mark the bundle private, the fetch needs Authorization: Bearer rgsk_....
Step by step
Section titled “Step by step”- Add the hostnames of your site, then open Firewall in the dashboard.
- Add a rule: a name, hosts, a path glob, methods, optional conditions and one terminal action. Start with a rule that only sets a score header, to watch before you block.
- Save and publish. Install an integration in front of your origin.
- Check the
X-RG-Verdict,X-RG-ScoreandX-RG-Ruleheaders your origin receives.
A rule has a name, enabled, a match (hosts, a path glob and methods), optional when conditions (scoreBelow, sessionLevelBelow, noSession), up to 8 actions and an onError of allow or block.
- Terminal actions (at most one per rule):
allow;block(status 403, 404 or 429);requireToken(anactionand athreshold);challengePage(minLevel1 or 2);redirect(302, 307 or 308, to a path or an https URL on your own hostnames). - Non-terminal actions:
scoreHeader;setHeader. - Hosts are exact hostnames or
*.example.com(never the bare apex). Methods are upper case names or*;*does not matchOPTIONS. - Path globs use literal characters,
*(within one segment) and**(whole segments). Matching is case-sensitive; query and fragment are never matched. - Saving a list is refused if a blocking rule would match
POSTor*on/__rg/returnor/__rg/session.
Example of a rule, as saved. It checks the fields the policy schema requires (id is 8 base62 characters, onError is mandatory, a requireToken threshold is a multiple of 0.1 from 0.1 to 1):
{ "id": "Login001", "name": "Protect login", "enabled": true, "match": { "hosts": ["shop.example"], "path": "/login", "methods": ["POST"] }, "actions": [ { "type": "scoreHeader" }, { "type": "requireToken", "action": "login", "threshold": 0.5 } ], "onError": "block"}The dashboard writes the rule ids for you. Every host in a rule must be covered by the hostnames you added to the site.
The kill switch
Section titled “The kill switch”To stop the firewall for a whole site without deleting anything, open Firewall, Settings, “Emergency switch” in the dashboard, tick Turn the firewall off for this site and save. Within a few minutes every integration lets all requests through unscored and unblocked. Untick and save to resume. This needs an integration version that supports it (older ones ignore it and keep enforcing), and it does not apply while the integration cannot load any policy.
Every rule has an enabled flag: switch a rule off without deleting it, and the next bundle (integrations refresh about every 60 seconds) stops enforcing it.
Fail modes and errors
Section titled “Fail modes and errors”onError decides what a rule does when it cannot be evaluated, for example a requireToken rule with no secret key configured or a failed verification call.
Each integration also has an initial fail mode for the time before it has ever verified a bundle: open (the default: requests pass with X-RG-Verdict: none) or closed (503). Once a bundle was verified, the integration keeps enforcing it while the API is unreachable. A bundle past its expiry plus 6 hours applies the bundle’s failMode.
| What you see | Meaning | What to do |
|---|---|---|
| 400 from the integration | The method, host or path of the request is not valid or canonical. | Fix the client; this is not a policy decision. |
403 with X-RG-Action: challenge |
A non-browser request hit a challengePage rule. |
Use a token (requireToken) for API calls. |
| 503 | closed fail mode, and no verified bundle yet. |
Check the integration’s network and pinned keys. |
404 not-found on bundle fetch |
No published policy, or a wrong site key. | Publish a policy. |
401 unauthorized on bundle fetch |
A private bundle without the matching secret. | Give the integration the secret. |
Security notes
Section titled “Security notes”The firewall is not the only gate. A request that reaches your origin another way (a direct IP, another hostname, a path the integration was not installed on) is never evaluated. Lock the origin so only the integration can reach it. The X-RG-* headers it sets are advisory unless you turn on X-RG-Sig (set sigHeader: true in the bundle settings and a sigSecret in the integration), and the integration deletes any x-rg-* header the client sent. Verify tokens yourself on endpoints that matter. Never cache a response that depends on X-RG-Score or X-RG-Verdict.
Limits
Section titled “Limits”100 rules per site, 8 actions per rule, 16 hosts and 8 methods per rule, path globs up to 200 characters with up to 8 wildcards, a bundle of at most 64 KiB, and up to 1,000 revoked entries. Private path forms (%2F, ;, double encoding) are refused rather than guessed.