Concepts
authbase is an authentication service you run yourself. Your products keep their own databases and business logic; authbase owns their users’ credentials and issues the tokens they use.
end-user ──▶ your backend ──(API key)──▶ authbase ──▶ PostgreSQL │ │ └── verifies tokens ◀── JWKS (public keys, cached)Who is who
Section titled “Who is who”| What | Authenticates with | |
|---|---|---|
| Instance | One authbase deployment: one binary, one PostgreSQL, one master key. Run by an operator. | — |
| Account | A developer who uses the dashboard. Owns apps. | email + password → dashboard session cookie |
| App | One of your products (e.g. Cashmate). Has its own users, keys and settings; nothing is shared between apps. | — |
| API key | Your backend’s credential for one app: sk_live_…, server-side only. |
Authorization: Bearer sk_live_… |
| End-user | A user of your product, stored in an app. | email or username + password, through your backend |
An app is identified by an immutable slug; its issuer is
{PUBLIC_URL}/apps/{slug}, and its app id (a UUID) is the audience of
its tokens. Both are on the app’s overview page in the dashboard.
Tokens
Section titled “Tokens”A successful login returns two tokens:
| Access token | Refresh token | |
|---|---|---|
| Form | JWT (RFC 9068), signed with Ed25519 (alg: EdDSA, typ: at+jwt) |
opaque rt_…, stored only as a hash |
| Lifetime | 15 minutes by default (5–60, per app) | 30 days by default (1 hour–1 year, per app), renewed on every refresh |
| Who checks it | your backend, locally, with the app’s public keys | authbase, when you call /v1/auth/refresh |
| Revocable | no: it expires. Keep it short. | yes: logout, “sign out everywhere”, password change |
The access token carries sub (the user id), email,
email_verified, username, roles, sid (the login it came from) and
client_id/aud (the app id). User metadata is not in it: fetch the
user when you need it.
Every refresh returns a new refresh token and makes the old one
unusable. Presenting a used one again is treated as theft: the whole chain
from that login (the family) is revoked and every holder must log in
again (refresh_token_reused).
Consequences worth knowing:
- Disabling or deleting a user, or signing them out everywhere, stops new tokens at once; access tokens already issued stay valid until they expire (at most the access-token lifetime).
- Roles changed in authbase appear in the next token (login or refresh).
Signing keys and the JWKS
Section titled “Signing keys and the JWKS”Each app has one active Ed25519 signing key. Its public half is
published, with any retiring key, at
{issuer}/.well-known/jwks.json (cacheable for 5 minutes); the private
half is stored encrypted under the instance’s master key and never
leaves authbase.
Rotating a signing key (dashboard or API) makes a new active key; the
old one keeps being published until every token it signed has expired,
then disappears. Verifiers that refetch the JWKS on an unknown kid (the
SDKs do, at most once a second) need no restart.
API keys
Section titled “API keys”An app can have several API keys at once. Rotate creates a new key and gives every other key a grace period (24 hours by default) in which both work, so you can deploy the new one without downtime; revoke stops a key immediately. Keys are shown once and stored only as hashes.
With SMTP configured, authbase sends password-reset and verification
links (single-use, 30 minutes and 24 hours) and security notices when a
password or email changes. Links go to authbase’s hosted pages, which
work without JavaScript, or to your own pages (password_reset_url,
email_verification_url in the app’s settings). Per app,
email_verification is off, optional (sent, never blocks) or
required (login waits for confirmation).
Protection that is always on
Section titled “Protection that is always on”- Rate limits per client IP on login, sign-up and email requests, and
per API key; lockout of an identifier after repeated failed logins
(1 minute, doubling to 1 hour). Answers are
429withRetry-After. - Passwords: 12–128 characters, checked against the 100,000 most common leaked passwords, hashed with Argon2id.
- Audit log per app: logins, failures, token reuse, user and key changes, with actor, IP and time; filterable in the dashboard.
Errors
Section titled “Errors”Every error is application/problem+json (RFC 9457) with a stable code
to branch on (invalid_credentials, account_locked, token_expired, …),
a detail for people and a request_id to quote when reporting a
problem. The SDKs raise them as AuthbaseError / AuthbaseException.
The full list is in the API reference.
Where to go next
Section titled “Where to go next”- Quick start: run it and integrate an example.
- Integration guide: the API calls and token checks in detail, with code for Node, Go and Python.
- Self-hosting: production deployment and runbooks.
- Security model: what is protected, how, and what is left to you.
For agents: this page as markdown · llms.txt