API keys and backup
Everything except /health needs the X-Api-Key header.
Twenty wrong keys from one address in five minutes and that address is answered 429 for the
rest of the window, whatever key it sends - the right one included, or the refusal itself would say
which guess was right. Only wrong or empty keys count: a caller with a working key never meets the
limit, and each container on the host reaches the API from an address of its own.
Two kinds of key
Configured keys come from the container's environment (Api__Keys__<name>). At least one is
required, they are read once at start-up, and they cannot be revoked or deleted through the
API, which makes them the way back in after revoking the wrong thing.
They are listed by GET /apikeys and marked as coming from the environment, beside the issued ones,
so the list shows every key that can reach the service.
Issued keys are minted through the console or POST /apikeys with a description, an optional
expiry and an optional read-only flag. They are stored as SHA-256 digests plus an eight-character
prefix, so the file on the volume is a list of descriptions rather than a set of working
credentials.
On the API keys page, a live issued key has a Revoke button (DELETE /apikeys/{id}). A
revoked key is refused from the next request on and stays in the list, marked revoked. A revoked or
expired key has a Delete button instead (POST /apikeys/{id}/delete), which removes it from
the list for good. A live key cannot be deleted: revoke it first. Both are confirmed in the row, and
the Audit log names the key by its description and prefix, so an entry still reads after the key
is gone.
From the call that issued it. Nothing readable is stored, so it cannot be read back: lose it and you revoke it, mint another, and delete the revoked one.
A read-only key may only issue GET requests: it is refused a POST, PUT or DELETE before a route is chosen.
It can read the status, the jails, the bans and the logs, and it can neither ban or unban an address, change a jail or a setting, take a backup, nor issue itself another key.
Backup and restore
The console's Backup page (POST /backup) downloads one JSON document holding everything this
service is configured with: the jails and their filters, the options with the whitelist and the
blacklist, the mail settings, the GeoIP settings, the keys issued here, the accounts and the
license. Only an administrator can take or restore one, in the console; a configured or issued
key that is not read-only can too, because the Odoo Host Manager takes its backups that way.
Every backup and restore is in the Audit log, and one made with a key alone is recorded under
that key's name.
- It holds the secrets: the relay password, the GeoIP key, the issued keys' digests, the
accounts' password hashes and the license files. A backup without them would restore a service
that looks configured and sends nothing. Keep it where you keep your other credentials. A
read-only key cannot take one: the backup is a
POSTfor exactly that reason. - It does not hold the authenticator apps. An app's secret is stored as it is, so in a file it would be a working second factor for whoever held the file. Passwords travel as hashes and passkeys as public keys, which are of no use to a thief, so those do come.
- It does not hold the bans. Those expire on their own, and restoring a week-old set onto a running host would re-block addresses whose ban was lifted on purpose. The blacklist does come, because that is a list somebody wrote.
- Restoring goes section by section, with a report for each, and the sections behave in two
ways:
- The jails and the accounts are added to what is here. Every jail in the backup is applied; a jail that is here now and not in the backup is left alone, so a restore never takes protection away.
- The global options (with the whitelist and the blacklist), the mail settings, the GeoIP settings and the issued keys are replaced by the backup's, when it carries them. A restore resets the API keys to the backup's, on purpose: a key issued since the backup was taken stops working, so issue it again afterwards and update the caller that uses it.
- Accounts are merged by user name. Every account in the backup comes back with its password,
passkeys and preferences; an account made since the backup stays. An account that used an
authenticator app signs in with its password and sets the app up again on My account >
Security; the restore report names each one. The built-in administrator keeps the password it
has, which belongs to
FAIL2BAN_SEED_ADMIN_PASS, so an old backup cannot lock you out, and an authenticator app required byFAIL2BAN_SEED_ADMIN_TOTPis kept by a restore. Everyone restored signs in again. The audit log is not in a backup. - A backup taken before 0.6.15 still holds the authenticator secrets, and restoring it puts them back. Take a new backup, and keep or destroy the old file as you would a password.
- Licenses are installed as they are restored, with no restart, and blocking follows within 30 seconds; see Managing the license. A license bound to another machine is refused, and the report says so.