A framework-agnostic, batteries-included authentication library for Python.
Project description
🔒 deadbolt
A framework-agnostic, batteries-included authentication library for Python. Own your auth, mount it on any framework — no hosted service, no lock-in.
deadbolt is what Better Auth is for the TypeScript world, rebuilt
idiomatically for Python: a self-hosted auth engine with a database-adapter abstraction, signed
cookie-based sessions, and a plugin system — mountable onto any Python web framework.
Why
- Framework-agnostic. One async-first core speaks a normalized request/response contract; a ~30-line adapter mounts it on FastAPI, Starlette, Flask, and more. WSGI frameworks are served from the async core through a background-loop sync bridge.
- Bring your own database. A uniform adapter interface (built on SQLAlchemy 2.0 Core) covers Postgres/MySQL/SQLite; an in-memory adapter ships for tests and local dev.
- Secure by default. Argon2id hashing, opaque DB-backed sessions stored hashed, signed
__Host-cookies, session rotation, rate limiting, origin-based CSRF checks, and timing-safe sign-in. - Alias-first API. Everything hangs off one object:
import deadbolt as db→db.Auth(...).
Install
pip install deadbolt # core (email/password + sessions)
pip install "deadbolt[fastapi,sqlalchemy]" # + a framework mount + a database adapter
pip install "deadbolt[all]" # everything, including every plugin's deps
Quickstart
import deadbolt as db
from deadbolt.integrations.fastapi import mount
auth = db.Auth(
adapter=db.MemoryAdapter(), # or db.SQLAlchemyAdapter(engine)
secret=SECRET, # 32+ random bytes
email_and_password=db.EmailPassword(enabled=True),
)
# Mount on any framework — this is the whole integration:
mount(app, auth, prefix="/api/auth")
# ...or call endpoints directly, no HTTP:
result = await auth.api.sign_in_email(email="a@b.com", password="…", as_response=True)
Add features by dropping in plugins:
from deadbolt.plugins.oauth import social, google
from deadbolt.plugins.totp import totp
from deadbolt.plugins.passkeys import passkeys
auth = db.Auth(
adapter=db.MemoryAdapter(),
secret=SECRET,
email_and_password=db.EmailPassword(enabled=True),
plugins=[
social(providers=[google(client_id=..., client_secret=..., redirect_uri=...)]),
totp(),
passkeys(rp_id="example.com", rp_name="Example", origin="https://example.com"),
],
)
Plugins
| Plugin | Import | What it adds |
|---|---|---|
| Username | deadbolt.plugins.username |
Sign in with a username |
| Magic link | deadbolt.plugins.magic_link |
Passwordless email links |
| Email OTP | deadbolt.plugins.email_otp |
Passwordless email codes |
| Phone OTP | deadbolt.plugins.phone |
Passwordless SMS codes |
| Social OAuth | deadbolt.plugins.oauth |
Google, GitHub, or any OAuth2/OIDC provider |
| Passkeys | deadbolt.plugins.passkeys |
WebAuthn registration + authentication |
| TOTP 2FA | deadbolt.plugins.totp |
Authenticator apps + backup codes |
| Organizations | deadbolt.plugins.organization |
Multi-tenancy, RBAC, invitations, teams |
| API keys | deadbolt.plugins.api_keys |
Machine-to-machine keys |
| Admin | deadbolt.plugins.admin |
Roles, bans, user management |
| JWT | deadbolt.plugins.jwt |
Stateless bearer tokens |
CLI
Generate SQL DDL for your full schema (core plus every enabled plugin) from your Auth config:
deadbolt generate --config myapp.auth:auth --dialect postgresql
Development
uv sync --all-extras --group dev
uv run pre-commit install
uv run pytest
uv run ruff check . && uv run ruff format --check . && uv run mypy
Security
Please report vulnerabilities via GitHub private advisories — see SECURITY.md in the repository.
Never open a public issue for a security bug. The architecture spec and STRIDE threat model live in
the repository's docs/ directory.
License
MIT © the deadbolt contributors.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file deadbolt-0.2.0.tar.gz.
File metadata
- Download URL: deadbolt-0.2.0.tar.gz
- Upload date:
- Size: 217.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f6c3d904b395c7c4d161c1b3e6e8734120bc03adce86b9c763c1dce8fe5ecec
|
|
| MD5 |
170f33da9e2fb2ff88429b15ad799a65
|
|
| BLAKE2b-256 |
ba15e587a5878ef177f7fa23efebd1a0bd53f7a0a7284c78f9cf62971525d9ab
|
Provenance
The following attestation bundles were made for deadbolt-0.2.0.tar.gz:
Publisher:
release.yml on ruban-s/deadbolt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
deadbolt-0.2.0.tar.gz -
Subject digest:
5f6c3d904b395c7c4d161c1b3e6e8734120bc03adce86b9c763c1dce8fe5ecec - Sigstore transparency entry: 2115850789
- Sigstore integration time:
-
Permalink:
ruban-s/deadbolt@3a3bd3af8a4562c0795237e39442d7e5ab197cab -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ruban-s
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3a3bd3af8a4562c0795237e39442d7e5ab197cab -
Trigger Event:
push
-
Statement type:
File details
Details for the file deadbolt-0.2.0-py3-none-any.whl.
File metadata
- Download URL: deadbolt-0.2.0-py3-none-any.whl
- Upload date:
- Size: 67.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
04d59cb42fff68ff5689aec822a2ee57f591774c5245dea31a17e1fae5e663f6
|
|
| MD5 |
35bfc3518b765df21a9b2fc35cd13fa7
|
|
| BLAKE2b-256 |
2a52e378af5de41f2c96dee55e4decc9b1f7cc479559be73cd4fab60b0e8d4f1
|
Provenance
The following attestation bundles were made for deadbolt-0.2.0-py3-none-any.whl:
Publisher:
release.yml on ruban-s/deadbolt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
deadbolt-0.2.0-py3-none-any.whl -
Subject digest:
04d59cb42fff68ff5689aec822a2ee57f591774c5245dea31a17e1fae5e663f6 - Sigstore transparency entry: 2115850946
- Sigstore integration time:
-
Permalink:
ruban-s/deadbolt@3a3bd3af8a4562c0795237e39442d7e5ab197cab -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ruban-s
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3a3bd3af8a4562c0795237e39442d7e5ab197cab -
Trigger Event:
push
-
Statement type: