On this page0
Unfamiliar word? See Glossary: words used in these docs. Looking for the tasks in order? Begin at Start Here.
Reference
Geo & IP Access Control
Restrict who can reach your instance by country and by IP address. Every rule is checked on your own instance against an offline country database that ships with the product; no outside lookup service is called.
What It Does
Configure everything from Security & Compliance → Threat Defense → Configure. Pick a country policy, choose countries from the picker, and add specific IPs or ranges. Set the page to Dry-run first to watch what would be blocked before you switch to Enforce. Saving a change to the rules asks you to confirm your identity first, with your password or a passkey.
Blocklist vs Allowlist
IP Allowlist Wins
Dry Run
Block Unknown Geo
Two safeguards stop a bad rule from locking you out. Country rules never apply to the sign-in, MFA and single sign-on paths or to the access-control settings themselves, so an admin in a blocked country can still sign in and fix the rule. And an allowlist with no countries in it is treated as a mistake and blocks nobody. IP blocks are stricter: they do cover the sign-in page, and are lifted only for an already signed-in admin reaching the settings, re-authentication and session-refresh paths needed to undo them.
Auto-Block Engine
The auto-block engine bans addresses that behave like an attack. It has its own switch on the Configure tab, separate from the Off / Dry-run / Enforce banner, and it is off and in dry-run by default: it cannot block anyone until you turn it on and set its mode to Enforce. A ban is written into the IP blocklist marked AUTO with the time left, and lifts on its own when the ban time runs out (6 hours by default). Addresses on the Exclude list are never banned. Switching the engine off, or back to dry-run, stops existing bans from being enforced.
It has five detectors: credential stuffing, auth-endpoint flood, sensitive-path scan, unknown-geo probe, distributed attack. Each detector can be switched off and its threshold and window changed under Detection patterns. All five are on by default once the engine is on. The same list shows an SSH brute-force row; that one is enforced on the server itself, not by this engine.
If something here is not working as you expect, start with When something goes wrong.
The plain explanation is above. This part is for IT and developers: the exact settings, permission names, API addresses and data fields behind it. Closed: select the heading above to open it. While it is closed, your browser’s find-on-page (Ctrl+F or Cmd+F) does not search this part.
The screen is at /dashboard/threat-defense.
// Stored in SecuritySetting → key "accessControl"
{
"enabled": true,
"mode": "blocklist", // or "allowlist"
"countries": ["RU", "KP", "IR"],
"blockedIps": [
{ "value": "198.51.100.0/24" },
{ "value": "192.0.2.44", "source": "auto", "expiresAt": 1767225600000 } // auto-block ban
],
"allowedIps": [{ "value": "203.0.113.7" }], // always pass
"blockUnknownGeo": false,
"dryRun": true, // log, don't block
"autoBlock": { "enabled": false, "dryRun": true, "threshold": 6, "windowSec": 600, "banSec": 21600, "patterns": { ... }, "tuning": { ... } },
"storeIp": "...", // Zonitix licensing address, always allowed
"sshAllowlist": [] // server access, held by Zonitix
}
Evaluation Order & Safety
The gateway middleware evaluates rules in a fixed precedence and caches them for 60 seconds. The address a rule is matched against is the one the network edge reports, falling back to the peer on the connection; the exact order is under How The Client Address Is Determined. Private/internal IPs are always exempt. If the offline country database fails to load, country and unknown-location rules stop being enforced, and the Threat Defense page says so with a “Country blocking is inert” banner. The IP blocklist, the Exclude list and auto-block do not depend on that database and keep working. Separately, an unexpected error inside the filter lets the request through rather than taking the gateway down.
The rules are read with GET /api/v1/auth/settings/security/access-control (manage_security) and written with POST to the same path, which needs manage_security and a fresh step-up. A missing or expired step-up is refused with "error": "SUDO_REQUIRED" in the response body. The status beside it is 400 on most routes, because the gateway turns a 401 from a service behind it into 400. It stays 401 on the routes the gateway passes through unchanged: removing a passkey, the diagnostics bundle, and in Security Lab starting an aggressive scan, changing a scan scope and archiving findings. Key on the error string, not the status. On this route the status is 400. A personal API token cannot perform a step-up, so it cannot change these rules.
// Rule precedence (first match wins):
1. Private / internal IP (RFC1918, loopback) → PASS
2. IP on the Exclude list (allowedIps) → PASS
3. Store IP (Zonitix licensing address) → PASS
4. Unexpired auto-block ban, engine on and enforcing → BLOCK (403)
// applies even when the main switch is off
5. IP on the manual blocklist, main switch on → BLOCK (403)
// 4 and 5 are skipped on the signed-in undo paths
6. Sign-in / MFA / SSO / access-control settings path → PASS
7. Main switch off, or country database not loaded → PASS
8. Unknown geo + blockUnknownGeo → BLOCK
9. Allowlist mode with no countries → PASS (misconfiguration guard)
10. Country {in blocklist | not in allowlist} → BLOCK
11. Everything else → PASS
// In dry-run, steps 5, 8 and 10 log ACCESS_BLOCKED_DRYRUN and pass.
// Blocked attempts are written to the audit log:
ACCESS_BLOCKED { ipAddress, country, reason: "country_blocklist" }
// reason: country_blocklist | country_allowlist | ip_blocklist | unknown_geo | auto_block
Auto-Block Detectors And Defaults
| Detector | Trips on | Default |
|---|---|---|
| Credential stuffing | Sign-in attempts on many different accounts from one address | 6 accounts in 10 min |
| Auth-endpoint flood | 401 / 403 responses to one address | 40 in 5 min |
| Sensitive-path scan | Requests for scanner paths such as /.env, /wp-login, /.git | 3 paths in 10 min |
| Unknown-geo probe | Errors from an address whose country cannot be resolved | 20 in 10 min |
| Distributed attack | One account failing from many addresses | 8 addresses in 15 min |