Complete authentication and authorization library for Python.
Install
pip install authfort[fastapi]
# or with SQLite: pip install authfort[sqlite,fastapi]
Quick Start
from authfort import AuthFort, CookieConfig
from fastapi import FastAPI, Depends
auth = AuthFort(
database_url="postgresql+asyncpg://user:pass@localhost/mydb",
cookie=CookieConfig(),
)
app = FastAPI()
app.include_router(auth.fastapi_router(), prefix="/auth")
app.include_router(auth.jwks_router())
@app.get("/profile")
async def profile(user=Depends(auth.current_user)):
return {"email": user.email, "roles": user.roles}
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /auth/signup | Create account |
| POST | /auth/login | Sign in |
| POST | /auth/refresh | Refresh access token |
| POST | /auth/logout | Sign out |
| GET | /auth/me | Get current user |
| POST | /auth/magic-link | Request magic link |
| POST | /auth/magic-link/verify | Verify magic link |
| POST | /auth/otp | Request email OTP |
| POST | /auth/otp/verify | Verify email OTP |
| POST | /auth/verify-email | Verify email address |
| GET | /auth/oauth/{provider}/authorize | Start OAuth flow |
| GET | /auth/oauth/{provider}/callback | OAuth callback |
| POST | /auth/introspect | Token introspection |
| GET | /.well-known/jwks.json | Public signing keys |
Features
- Email/password auth with argon2 hashing
- JWT RS256 with automatic key management
- Refresh token rotation with theft detection
- OAuth 2.1 with PKCE (Google, GitHub, or any provider via GenericOAuthProvider/GenericOIDCProvider)
- Email verification, magic links, email OTP (passwordless)
- Role-based access control
- Password reset (programmatic — you control delivery)
- Change password (with old password verification)
- Session management (list, revoke, revoke all except current)
- Ban/unban users
- Rate limiting — per-endpoint IP + email based, in-memory sliding window, pluggable storage
- Admin user management — list, search, get, delete users programmatically
- Event hooks (24 event types)
- JWKS + key rotation
- Cookie and bearer token modes
- Multi-database: PostgreSQL (default), SQLite, MySQL via SQLAlchemy
OAuth
from authfort import AuthFort, GoogleProvider, GitHubProvider, GenericOIDCProvider
auth = AuthFort(
database_url="...",
providers=[
GoogleProvider(client_id="...", client_secret="..."),
GitHubProvider(client_id="...", client_secret="..."),
GenericOIDCProvider(
"keycloak",
client_id="...",
client_secret="...",
discovery_url="https://keycloak.example.com/realms/myrealm/.well-known/openid-configuration",
),
],
)
Programmatic API
# Create users without the HTTP endpoint
result = await auth.create_user("admin@example.com", "password", name="Admin")
# Roles
await auth.add_role(user_id, "admin")
await auth.remove_role(user_id, "editor")
# Password reset (you handle delivery — email, SMS, etc.)
token = await auth.create_password_reset_token("user@example.com")
if token:
send_email(email, f"https://myapp.com/reset?token={token}")
await auth.reset_password(token, "new_password")
# Change password (authenticated)
await auth.change_password(user_id, "old_password", "new_password")
# Sessions
sessions = await auth.get_sessions(user_id, active_only=True)
await auth.revoke_session(session_id)
await auth.revoke_all_sessions(user_id, exclude=user.session_id) # keep current
# Ban/unban
await auth.ban_user(user_id)
await auth.unban_user(user_id)
# Admin user management
users = await auth.list_users(query="john", role="admin", limit=20)
user = await auth.get_user(user_id)
await auth.delete_user(user_id)
count = await auth.get_user_count(banned=True)
License
Release files for authfort 0.0.31
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| authfort-0.0.31.tar.gz | 131.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| authfort-0.0.31-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 230.3 kB
Release files / authfort-0.0.31.tar.gz
| Download URL | authfort-0.0.31.tar.gz |
|---|---|
| Size | 131.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
30432b5211ed3eb1ad34c26583a2e2fb09256b6c9e8cc8e346e1d0bc2b8f4a3f
|
|
BLAKE2b-256 checksum How to use checksums |
b28a0bc1f5f0fad63fed7bb3f885f971fb33cec22cf9f40f4198577ee1816cff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / authfort-0.0.31-py3-none-any.whl
| Download URL | authfort-0.0.31-py3-none-any.whl |
|---|---|
| Size | 98.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6e87541ded47d6fdf2baf29d6a822501aed55bbc36e9e8798b19946e47cb121c
|
|
BLAKE2b-256 checksum How to use checksums |
6bf2fc12ea7e9d26b04c3ef65be4898d7cfcde8ee111f565f0f402302887314b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|