Firewall and threat protection
Two pages under Security in the console decide who reaches the service at all, before an API key, an account or a route is even looked at. Both are offered to Administrators, who change them, and read-only administrators, who see them.
Firewall
The service has three doors, each with its own rules and its own tab on Security > Firewall:
| Door | What it guards | Who calls it |
|---|---|---|
| Console | The console's pages, from the sign-in page on | People, in a browser |
| Management API | Every route of the API except the checks: entries, lists, jobs, keys, settings, the license, backup | The console, and your management scripts |
| Checks | POST /api/v1/check and POST /api/v1/check/batch | Your forms and the servers behind them |
/health is on no door: it stays reachable whatever the rules say, so an orchestrator's health probe
keeps working.
With no rules, every door is open, as it is on a new installation.
Rules
A rule admits or refuses callers by address (an IP or a range), host name (resolved and kept current, for a line behind dynamic DNS), country or continent. Each door reads its rules from the top, and the last rule a caller matches decides.
- A refused caller gets an empty answer, as if the page did not exist, never a page saying it was refused.
- Loopback and private addresses always pass. The console reaches the API across the Docker network, and a rule listing only your office's addresses must not cut the console off from its own API.
- Saving rules that would refuse your own address is warned about on the page, with your address named: you save them only after accepting that you may lock yourself out. The deployment's locked entries (below) are then the way back in.
- Saving a door's rules is a job, like every change. The rules are
GET /api/v1/security/rulesandPUT /api/v1/security/rules/{application}/{surface}.
Country and continent rules
A rule by country or continent needs a GeoLite2 country database file, named with
AccessControl__GeoDatabasePath on the container whose door it guards - the API for the management
API and the checks, the console for the console. Without one, or with one that cannot be read,
location rules are switched off rather than refusing anybody.
Entries from the deployment
Addresses, host names, countries and continents admitted in the container's environment are shown locked on their door's tab. Nothing on the page removes them, so they are the way back in after a mistake:
| Door | Set on | Variables |
|---|---|---|
| Console | The console container | AccessControl__Surfaces__admin__AllowedIps__0, ...__AllowedHostnames__0, ...__AllowedCountries__0, ...__AllowedContinents__0 |
| Management API | The API container | The same, under AccessControl__Surfaces__admin__ |
| Checks | The API container | The same, under AccessControl__Surfaces__checks__ |
The log
The Log tab holds every decision a door with rules took: who asked, from where, for what, and
which rule refused them. It can be filtered, and exported as CSV (GET /api/v1/security/log/export).
Threat protection
Threat protection counts failed attempts against the address they came from and bans an address that fails too often:
- a wrong password, or a refused Cloudflare Turnstile check, on the console's sign-in;
- a call to the API with a wrong API key.
A banned address is refused the console and the management API until the ban lapses or is lifted. The checks keep answering it: a form that checks addresses never loses its answers because somebody on the same address mistyped a password or a key.
Your own network is never banned: loopback and private addresses never are, and neither is any address on the whitelist. Put your office's public address on it.
The page
Security > Threat protection has three tabs:
| Tab | What it shows |
|---|---|
| Bans | The bans in force, automatic and by hand. An administrator can ban an address by hand, for a number of minutes or until it is lifted, and lift any ban |
| Failures | The latest failed attempts threat protection counted |
| Settings | The thresholds, the whitelist and the mail. What is saved here is laid over the deployment's settings; resetting hands them back |
Bans by hand, lifts and saved settings are jobs, like every change. Through the API they are
/api/v1/security/threat/settings, /api/v1/security/threat/bans and
/api/v1/security/threat/failures; see the reference.
The settings
The deployment's values are environment variables on the API container. The Settings tab shows them and can lay its own over them.
| Variable | Default | What it is |
|---|---|---|
threatProtection__Enabled | true | Whether failed attempts are counted and addresses banned at all |
threatProtection__MaxFailures | 5 | Failed attempts inside the window that ban an address |
threatProtection__WindowSeconds | 600 | How far back failed attempts are counted |
threatProtection__BanSeconds | 3600 | How long an automatic ban lasts |
threatProtection__CountFailedChecks | true | Whether a refused Turnstile check on the sign-in counts as a failed attempt |
threatProtection__EscalateRepeatOffenders | true | An address banned again within 30 days of its last automatic ban ending gets twice that ban, up to the longest ban below; once a ban has reached it, the next one lasts until it is lifted. A ban an administrator lifted is not counted |
threatProtection__LongestBanSeconds | 2592000 (30 days) | Where doubling stops |
threatProtection__WhitelistIps__<n> | - | Addresses and ranges that are never banned |
threatProtection__NotifyEachBan | true | One message per automatic ban |
threatProtection__DailyDigest | true | A summary of every ban since the last one, automatic or by hand, sent with the first ban after a day has passed, so a day without bans sends nothing |
threatProtection__NotifyAdministrators | true | Whether administrators with an e-mail address on their account receive the mail |
threatProtection__NotificationRecipients__<n> | - | Further addresses that receive the mail. Environment only |
threatProtection__FailureRetentionDays | 7 | How many days failed attempts are kept for the Failures tab, 1 to 365. Environment only |
Ban mail goes to the recipients on the SMTP page, to the addresses in
threatProtection__NotificationRecipients__0 and on, and to the administrators while that setting is
on. It needs Send mail on the SMTP page; see Mail.