regstack¶
Production-grade user accounts for your FastAPI app — without the vendor lock-in, the second service to run, or the homegrown auth bugs.
pip install regstack, point it at SQLite (default),
PostgreSQL, or
MongoDB, and you have register / login /
verify-email / reset-password / change-email / delete-account /
optional SMS two-factor / admin endpoints / themeable HTML pages —
all behind a small Python API and one config file.
The problem regstack solves¶
Every web application that has users eventually needs the same dozen endpoints: register, log in, log out, verify email, reset a forgotten password, change password, change email, delete account, list users for the admin panel, lock out brute-force attackers, and ideally a second factor. Every one of those endpoints has a well-known way to get subtly wrong:
Password hashing. Use Argon2id, not MD5, SHA-1, bcrypt-without-pepper, or — somehow still common — plain text.
Token revocation. A JWT is signed and self-contained: the server can’t “log it out” unless you build a revocation list. Forget this and a stolen token works until it expires.
Account enumeration. A login or password-reset endpoint that responds differently for “user exists” vs “user doesn’t” lets an attacker harvest your customer list.
Bulk session invalidation. When a user changes their password because they think they were compromised, every existing token they hold should stop working immediately. Most homegrown JWT layers don’t do this.
One-time tokens. Verification and password-reset tokens should be random, hashed at rest, single-use, and expire fast. Storing the raw token in the database is a “now your DB backup is also a credential dump” mistake.
Phone numbers. SMS codes need E.164-validated numbers, attempt limits, and an upstream provider. Wiring all of that yourself for a single feature is rarely worth it.
Doing all of these correctly, with tests, is two to four weeks of engineering for a competent team. Doing them once and embedding the result everywhere is what regstack is for.
Why not just use…?¶
There are real alternatives. Here’s why regstack might still be the right call.
Alternative |
Why you might pick it |
Why you might pick regstack instead |
|---|---|---|
Zero ops. Polished UI. Enterprise SSO out of the box. |
Cost scales per-user. Your auth lives on someone else’s servers. Your customer list is in their database. Vendor lock-in is real and migrations are painful. |
|
Keycloak / Authentik / Authelia / Ory Kratos (self-hosted IAM) |
Full identity platform. SAML, OIDC, federation. |
A separate Java/Go service to run, monitor, back up, upgrade, and reason about. Heavyweight for “let users sign up”. Schema lives outside your app. |
Same language, same framework. Good registration / login primitives. |
Doesn’t ship verification flows, anti-enumeration, bulk revoke, SMS MFA, admin endpoints, or themeable pages — you build those. regstack is the longer tail. |
|
Roll your own |
Total control. No dependency to learn. |
You re-solve every bullet from “The problem” above, including the ones you didn’t know existed yet. Two to four engineering weeks, then forever to maintain. |
regstack’s bet is that for most FastAPI apps the right answer is embed a small Python library that owns the boring 80% correctly, and keep the user table in your own database — not “stand up a separate auth product” and not “write the boring 80% from scratch each time”.
What’s distinctive about regstack¶
Native pywebview setup tools, not just Click prompts.
regstack oauth setupopens a real desktop window that walks an operator through registering a Google OAuth 2.0 client and merging the credentials intoregstack.tomlnon-clobberingly — no copy-pasting the redirect URI four times.regstack theme designopens a live theme designer with a real-time preview of the SSR auth pages: tweak a colour, see the Sign-in card update on the right; click Save to writeregstack-theme.css. CSS-only re-skin in minutes, no template editing required. Both tools are local-only (127.0.0.1+ per-launch token), have a--headlessmode for headless CI (plus--dry-runfor no-write validation), and ship under the same test-from-the-outside Playwright suite the SSR pages do.
Zero vendor lock-in. Your user table is in your database, not someone else’s. Switch storage backends by changing one URL.
Opt-in everything. No SMS extra → no
twilio/aioboto3install. No SES → no AWS SDK. No SSR → no Jinja templates loaded. The base install is small.
About the examples¶
To keep URLs and config values consistent across the docs, every
example pretends to embed regstack into a fictional app hosted at
app.example.com. Throughout the docs:
What |
Value |
|---|---|
Public host |
|
|
|
Database host (prod) |
|
Database user |
|
Database password |
|
Database name |
|
Email sender |
|
Local dev port |
|
So a Postgres URL looks like
postgresql+asyncpg://<username>:<password>@dbhost.example.com:5432/dbname,
a MongoDB URL like
mongodb://<username>:<password>@dbhost.example.com:27017/dbname,
and the local SQLite path sqlite+aiosqlite:///./dbname.db. Substitute
your own values when copying — the shape is the only thing that
matters.
What’s in the box¶
Three storage backends, one API. SQLite (the default — single file, no server), Postgres (via asyncpg), MongoDB (via pymongo). Same routers, same hooks; switch by changing the
database_url.JSON API. Register, verify email, resend verification, log in (with optional SMS second step), log out,
me, change password, change email + confirm, forgot/reset password, delete account, admin endpoints.Server-rendered HTML pages (opt-in). Login, register, verify, forgot, reset, MFA confirm, account dashboard. Themed via CSS custom properties — no template editing required for a re-skin. Full template overrides are still possible per host.
CLIs + native pywebview tools.
regstack init(interactive project bootstrap),regstack oauth setup(guided Google OAuth client configuration in a native webview — see OAuth guide),regstack theme design(live theme designer with a real-time preview of the SSR widgets — see theming guide),regstack ses setup(guided SES email backend configuration that validates against AWS, new in 0.8.0),regstack create-admin,regstack doctor,regstack migrate(Alembic schema migrations for SQL backends),regstack validate(end-to-end probe of a deployed install). Every CLI command is documented under CLI reference.OAuth — Sign in with Google (opt-in, since 0.3.0). Authorization Code with PKCE, ID-token verification, identity-linking with a default-refuse policy hosts can opt out of. Connected-accounts panel on the SSR
/account/mepage. See the OAuth guide.Pluggable email and SMS. Email backends:
console(dev), SMTP, Amazon SES. SMS backends: Amazon SNS, Twilio. Plug your own in by implementing one method.Security defaults you would otherwise have to research. Argon2id password hashing, per-purpose JWT signing keys, per-token revocation, bulk session invalidation on password change, login lockout with HTTP 429 +
Retry-After, durable hashed verification tokens, 6-digit SMS codes with attempt limits, anti-enumeration on forgot/resend endpoints, CSP-friendly templates with no inline styles.
Where to next¶
New here? Start with the Quickstart — install, generate a config, register a user end-to-end.
Embedding regstack in an existing app? Read Embedding for the patterns most hosts adopt (custom email, hooks, multiple regstacks, theming).
Curious how it’s put together internally? See Architecture.
Designing a deployment? The Security model page is the threat model, the JWT scheme, and the things you still own as a host.
Getting started
Guides
- Architecture
- Security model
- Passwords
- JWT issuance and validation
- Revocation: two complementary mechanisms
- Account enumeration
- Login lockout
- Per-route IP rate limits
- Email verification (durable, hashed token)
- Password reset
- Email change (re-auth + re-verify)
- SMS 2FA
- OAuth (Sign in with Google)
- CSP and the SSR layer
- What you still own as a host
- Reporting vulnerabilities
- Embedding regstack in a host app
- Picking a backend
- Subscribing to events
- Custom email or SMS backends
- Enabling OAuth
- Overriding email and HTML templates
- Switching the SSR theme without templates
- Multiple regstacks in one process
- Bootstrapping the first admin
- Health-check and probes
- Extension surface —
RegStack.depsandRegStack.oauth - What regstack does not do
- OAuth (Sign in with Google)
- Theming the SSR pages
- CLI reference
Reference
- API reference
- Changelog
- Unreleased
- 0.8.2 — 2026-05-21
- 0.8.1 — 2026-05-19
- 0.8.0 — 2026-05-19
- 0.7.0 — 2026-05-17
- 0.6.0 — 2026-05-14
- 0.5.11 — 2026-05-14
- 0.5.10 — 2026-05-14
- 0.5.9 — 2026-05-13
- 0.5.8 — 2026-05-13
- 0.5.7 — 2026-05-13
- 0.5.6 — 2026-05-13
- 0.5.0 — 2026-05-02
- 0.4.0 — 2026-05-02
- 0.3.0 — 2026-04-30
- 0.2.6 — 2026-04-28
- 0.2.5 — 2026-04-28
- 0.2.4 — 2026-04-28
- 0.2.3 — 2026-04-28
- 0.2.2 — 2026-04-28
- 0.2.1 — 2026-04-28
- 0.2.0 — 2026-04-28
- 0.1.1 — 2026-04-27
- 0.1.0 — 2026-04-27
Project status¶
Alpha. Latest tagged release: v0.5.0. SQLite is the default and
runs with no infrastructure; PostgreSQL and MongoDB pass the same
parametrized integration suite. The full backend matrix runs in
parallel against every test, so a green CI on main is a strong
correctness signal.