Security model
What authbase protects, how, and what stays your responsibility.
Each release is reviewed requirement by requirement against OWASP ASVS 4.0.3, level 2.
Trust boundaries
Section titled “Trust boundaries”| Party | Trusted with | Never gets |
|---|---|---|
| Operator | the host, the database, the master key | end-users’ passwords (only hashes exist) |
| Account (developer) | its apps: users, keys, settings, audit log | other accounts’ apps (every app route checks ownership; another account’s app is a 404) |
| API key | one app’s end-user API | the management API, other apps |
| End-user | their own tokens | anything but what your backend exposes |
| Your backend | an API key, end-users’ tokens in transit | signing keys (tokens are verified with public keys) |
Secrets and how they are stored
Section titled “Secrets and how they are stored”| Secret | At rest |
|---|---|
| End-user and account passwords | Argon2id (19 MiB, t=2), NFKC-normalized first; never logged or emailed |
API keys (sk_live_, 256 bits) |
SHA-256; shown once |
Refresh tokens (rt_, 256 bits) |
SHA-256 |
| Dashboard sessions (256 bits) | SHA-256; the cookie is HttpOnly, Secure, SameSite=Lax, __Host- on https |
| Reset and verification links | SHA-256; single use, 30 minutes / 24 hours, voided by a newer link or a password or email change |
| Apps’ Ed25519 signing keys | AES-256-GCM under the master key, bound to their app and key id |
| Queued email (it carries live links) | AES-256-GCM under the master key; deleted once sent |
| The master key | only in the environment; never in the image, the database or logs |
A stolen database therefore yields no usable credential; a stolen master key alone yields nothing. Both together allow forging tokens, which is why the runbook for that case rotates every signing key (after a leak).
Tokens
Section titled “Tokens”- Access tokens are EdDSA-signed JWTs with
typ: at+jwt(RFC 9068), an issuer per app and the app id as audience, so a token for one app is worthless to another, and other JWTs signed by the same key are not access tokens. Verifiers must accept onlyEdDSAand take keys only from the configured JWKS URL, never from the token (the SDKs do). - They cannot be revoked; their lifetime (15 minutes by default, at most 60) bounds how long a disabled or signed-out user keeps access.
- Refresh tokens rotate on every use. Re-use of a spent one revokes the
whole family, which ends a stolen token’s life at the next legitimate
refresh (
token.reuse_detectedin the audit log). - A password change or reset revokes every refresh token of the user.
Abuse controls
Section titled “Abuse controls”- Per-IP rate limits on login, sign-up, reset and verification requests
and dashboard sign-in; per-API-key limits. Behind a proxy they depend on
AUTHBASE_TRUSTED_PROXIESbeing right. - Per-identifier lockout after 5 failures in 15 minutes (1 minute, doubling to 1 hour), shared by every instance through the database.
- At most max(2, CPUs) password hashes run at once; beyond that requests wait up to 2 seconds, then get 429, so a login flood cannot exhaust memory.
- Login answers the same for an unknown identifier and a wrong password; reset and verification requests answer 202 for any address.
Web surfaces
Section titled “Web surfaces”- The dashboard is served by authbase itself: one origin, no CORS, a
Content-Security-Policy of
'self'with nothing inline, and CSRF protection (Sec-Fetch-Site/Origin) on every state-changing request. - The hosted reset and verification pages run no code beyond one same-origin script (a “Show passwords” checkbox), are never cached, and act only on a POST, so link-scanning mail filters cannot use them.
- Every response carries
X-Content-Type-Options,Referrer-Policyand, on https, HSTS.
Accountability
Section titled “Accountability”Every change to apps, keys and users, and every login, failure, lockout and token reuse, is written to the app’s audit log in the same transaction as the change, with the actor (account, API key, user or the operator’s CLI), the client IP and the time. Master key rotations are recorded as instance events.
What is yours to do
Section titled “What is yours to do”As an integrator:
- Keep the API key server-side, in the environment. Never ship it to a browser or a mobile app.
- Verify every access token (the SDK middleware, or the rules in integration guide).
- Keep refresh tokens out of reach of scripts: an
HttpOnlycookie or your server’s session, notlocalStorage. - Pass the end-user’s IP (
client_ip) on login and refresh, so rate limits and the audit log mean something. - Keep access tokens short-lived if you rely on disabling users.
As an operator:
- Serve it over HTTPS only, behind a proxy you list in
AUTHBASE_TRUSTED_PROXIES. - Keep the master key in a secret store, apart from database backups.
- Close sign-up (
AUTHBASE_ALLOW_SIGNUP=false) once your developers have accounts. - Keep
/metricsoff the internet (it is on its own listener for that).
Known limits
Section titled “Known limits”- No multi-factor authentication yet, for end-users or the dashboard (planned).
- No social login or hosted login page yet (planned).
- Per-IP rate limits are counted per instance; lockout is shared.
- Access tokens cannot be revoked before they expire (by design, above).
For agents: this page as markdown · llms.txt