Server API
Constructor
Section titled “Constructor”AuthFort(
database_url: str,
*,
access_token_ttl: int = 900,
refresh_token_ttl: int = 2592000,
jwt_issuer: str = "authfort",
cookie: CookieConfig | None = None,
providers: list | None = None,
key_rotation_ttl: int = 172800,
introspect_secret: str | None = None,
allow_signup: bool = True,
password_reset_ttl: int = 3600,
rsa_key_size: int = 2048,
frontend_url: str | None = None,
email_verify_ttl: int = 86400,
magic_link_ttl: int = 600,
email_otp_ttl: int = 300,
allow_passwordless_signup: bool = False,
rate_limit: RateLimitConfig | None = None,
trust_proxy: bool = False,
trusted_proxies: list[str] | None = None,
) AuthFort(
database_url: str,
*,
access_token_ttl: int = 900,
refresh_token_ttl: int = 2592000,
jwt_issuer: str = "authfort",
cookie: CookieConfig | None = None,
providers: list | None = None,
key_rotation_ttl: int = 172800,
introspect_secret: str | None = None,
allow_signup: bool = True,
password_reset_ttl: int = 3600,
rsa_key_size: int = 2048,
frontend_url: str | None = None,
email_verify_ttl: int = 86400,
magic_link_ttl: int = 600,
email_otp_ttl: int = 300,
allow_passwordless_signup: bool = False,
rate_limit: RateLimitConfig | None = None,
trust_proxy: bool = False,
trusted_proxies: list[str] | None = None,
) See Configuration for parameter details.
Authentication
Section titled “Authentication”create_user(email, password, *, name=None, avatar_url=None, phone=None, email_verified=False)
Section titled “create_user(email, password, *, name=None, avatar_url=None, phone=None, email_verified=False)”Create a new user. Works regardless of allow_signup setting.
| Param | Type | Description |
|---|---|---|
email | str | User email (normalized) |
password | str | Plain text password (hashed with argon2) |
name | str | None | Display name |
avatar_url | str | None | Profile image URL |
phone | str | None | Phone number |
email_verified | bool | Mark email as verified at creation (default False). Fires email_verified event when True. |
Returns: AuthResponse
Raises: AuthError if email already exists
login(email, password)
Section titled “login(email, password)”Authenticate with email and password.
Returns: AuthResponse
Raises: AuthError if credentials invalid or user banned
refresh(raw_refresh_token)
Section titled “refresh(raw_refresh_token)”Exchange a refresh token for new tokens.
Returns: AuthResponse
Raises: AuthError if token invalid, expired, or revoked
logout(raw_refresh_token)
Section titled “logout(raw_refresh_token)”Revoke a refresh token.
Returns: None
Password Management
Section titled “Password Management”create_password_reset_token(email)
Section titled “create_password_reset_token(email)”Generate a password reset token. Works for all users — including passwordless and OAuth users who want to set their initial password.
Returns: str | None — token string, or None if email not found
reset_password(token, new_password)
Section titled “reset_password(token, new_password)”Reset password using a reset token. Bumps token version and revokes all refresh tokens.
Returns: bool — True if successful, False if token invalid/expired
change_password(user_id, old_password, new_password)
Section titled “change_password(user_id, old_password, new_password)”Change password for an authenticated user. Bumps token version and revokes all refresh tokens.
Returns: None
Raises: AuthError if old password is wrong, or if user has no password (code: no_password for passwordless, oauth_account for OAuth)
set_password(user_id, new_password)
Section titled “set_password(user_id, new_password)”Set an initial password for a passwordless user (magic link, OTP, or OAuth). Only works when the user has no password set.
Returns: None
Raises: AuthError if user already has a password (code: password_already_set) or user not found
Email Verification
Section titled “Email Verification”create_email_verification_token(user_id)
Section titled “create_email_verification_token(user_id)”Generate an email verification token.
| Param | Type | Description |
|---|---|---|
user_id | UUID | User ID |
Returns: str | None — token string, or None if already verified or user not found
verify_email(token)
Section titled “verify_email(token)”Verify a user’s email using a verification token.
Returns: bool — True if successful
Raises: AuthError if token invalid or expired
Passwordless Login
Section titled “Passwordless Login”create_magic_link_token(email)
Section titled “create_magic_link_token(email)”Generate a magic link token for passwordless login.
Returns: str | None — token string, or None if email not found (and passwordless signup disabled) or user banned
verify_magic_link(token)
Section titled “verify_magic_link(token)”Verify a magic link token and log the user in. Also sets email_verified=True.
Returns: AuthResponse
Raises: AuthError if token invalid/expired or user banned
create_email_otp(email)
Section titled “create_email_otp(email)”Generate a 6-digit OTP code for passwordless login.
Returns: str | None — 6-digit code, or None if email not found (and passwordless signup disabled) or user banned
verify_email_otp(email, code)
Section titled “verify_email_otp(email, code)”Verify an OTP code and log the user in. Also sets email_verified=True.
| Param | Type | Description |
|---|---|---|
email | str | User email (must match the OTP request) |
code | str | 6-digit OTP code |
Returns: AuthResponse
Raises: AuthError if code invalid/expired or user banned
Role Management
Section titled “Role Management”add_role(user_id, role, *, immediate=True)
Section titled “add_role(user_id, role, *, immediate=True)”Assign a role to a user.
| Param | Type | Default | Description |
|---|---|---|---|
user_id | UUID | — | User ID |
role | str | — | Role name |
immediate | bool | True | Bump token version to invalidate existing tokens |
Returns: None
remove_role(user_id, role, *, immediate=True)
Section titled “remove_role(user_id, role, *, immediate=True)”Remove a role from a user.
Returns: None
get_roles(user_id)
Section titled “get_roles(user_id)”Get all roles assigned to a user.
Returns: list[str]
has_role(user_id, role)
Section titled “has_role(user_id, role)”Check if a user has a specific role.
| Param | Type | Description |
|---|---|---|
user_id | UUID | User ID |
role | str | Role name |
Returns: bool
User Management
Section titled “User Management”ban_user(user_id)
Section titled “ban_user(user_id)”Ban a user. Sets banned flag, bumps token version, revokes all refresh tokens.
Returns: None
unban_user(user_id)
Section titled “unban_user(user_id)”Unban a user.
Returns: None
update_user(user_id, *, name, avatar_url, phone, email_verified)
Section titled “update_user(user_id, *, name, avatar_url, phone, email_verified)”Update a user’s profile fields. Only provided fields are changed — omitted fields are left untouched. Pass None to clear a field.
| Param | Type | Description |
|---|---|---|
user_id | UUID | User ID |
name | str | None | Display name (omit to leave unchanged) |
avatar_url | str | None | Profile image URL (omit to leave unchanged) |
phone | str | None | Phone number (omit to leave unchanged) |
email_verified | bool | Set email verification status (omit to leave unchanged). Fires email_verified event only when transitioning from False to True. |
Returns: UserResponse
Raises: AuthError if user not found, or if no fields are provided
list_users(*, limit=50, offset=0, query=None, banned=None, role=None, sort_by="created_at", sort_order="desc")
Section titled “list_users(*, limit=50, offset=0, query=None, banned=None, role=None, sort_by="created_at", sort_order="desc")”List users with pagination and filtering.
| Param | Type | Default | Description |
|---|---|---|---|
limit | int | 50 | Max users per page |
offset | int | 0 | Number of users to skip |
query | str | None | None | Case-insensitive partial match on email or name |
banned | bool | None | None | Filter by banned status |
role | str | None | None | Filter by role |
sort_by | str | "created_at" | Sort field — "created_at", "email", or "name" |
sort_order | str | "desc" | "asc" or "desc" |
Returns: ListUsersResponse
get_user(user_id)
Section titled “get_user(user_id)”Get a single user by ID with roles.
| Param | Type | Description |
|---|---|---|
user_id | UUID | User ID |
Returns: UserResponse (includes roles)
Raises: AuthError if user not found
delete_user(user_id)
Section titled “delete_user(user_id)”Delete a user and all related data (roles, tokens, accounts, verification tokens). Fires a user_deleted event.
| Param | Type | Description |
|---|---|---|
user_id | UUID | User ID |
Returns: None
Raises: ValueError if user not found
get_user_count(*, query=None, banned=None, role=None)
Section titled “get_user_count(*, query=None, banned=None, role=None)”Count users with optional filters. Same filters as list_users().
| Param | Type | Default | Description |
|---|---|---|---|
query | str | None | None | Case-insensitive partial match on email or name |
banned | bool | None | None | Filter by banned status |
role | str | None | None | Filter by role |
Returns: int
Session Management
Section titled “Session Management”The session_id is stable across refresh token rotations — it is assigned when a user logs in and stays the same through all subsequent refreshes. The JWT sid claim contains this stable ID. Use it to identify and manage individual sessions (e.g. “sign out other devices”).
get_sessions(user_id, *, active_only=False)
Section titled “get_sessions(user_id, *, active_only=False)”List sessions for a user. Results are deduplicated by session_id — each entry represents one logical session regardless of how many token rotations have occurred.
| Param | Type | Default | Description |
|---|---|---|---|
user_id | UUID | — | User ID |
active_only | bool | False | Only return non-revoked, non-expired sessions |
Returns: list[SessionResponse]
revoke_session(session_id)
Section titled “revoke_session(session_id)”Revoke a session. Invalidates all refresh tokens in that session’s rotation chain.
Returns: bool — True if found and revoked
revoke_all_sessions(user_id, *, exclude=None)
Section titled “revoke_all_sessions(user_id, *, exclude=None)”Revoke all sessions for a user. Bumps token version.
| Param | Type | Default | Description |
|---|---|---|---|
user_id | UUID | — | User ID |
exclude | UUID | None | None | Session ID to keep alive (e.g. the current session) |
Returns: None
Key Management
Section titled “Key Management”rotate_key()
Section titled “rotate_key()”Create a new signing key and retire the current one.
Returns: str — new key ID (kid)
cleanup_expired_keys()
Section titled “cleanup_expired_keys()”Delete expired signing keys from the database.
Returns: int — number of keys deleted
cleanup_expired_tokens()
Section titled “cleanup_expired_tokens()”Delete expired verification tokens (password reset, email verify, magic link, OTP).
Returns: int — number of tokens deleted
cleanup_expired_sessions()
Section titled “cleanup_expired_sessions()”Delete expired or revoked refresh tokens (sessions).
Returns: int — number of sessions deleted
get_jwks()
Section titled “get_jwks()”Get the JWKS (JSON Web Key Set) as a dict. Returns the public signing keys in JWK format. Useful for serving JWKS from non-FastAPI frameworks (Django, Flask, etc.).
Returns: dict — JWKS document with keys array
get_provider_tokens(user_id, provider)
Section titled “get_provider_tokens(user_id, provider)”Get the stored OAuth tokens for a provider account.
| Param | Type | Description |
|---|---|---|
user_id | UUID | User ID |
provider | str | Provider name (e.g., "google", "github", or any generic provider name) |
Returns: dict | None — dict with access_token, refresh_token, and expires_at keys, or None if no account exists for this provider
Event Hooks
Section titled “Event Hooks”on(event_name)
Section titled “on(event_name)”Decorator to register an event hook.
@auth.on("login")
async def on_login(event):
... @auth.on("login")
async def on_login(event):
... add_hook(event_name, callback)
Section titled “add_hook(event_name, callback)”Programmatically register an event hook.
Database
Section titled “Database”migrate()
Section titled “migrate()”Run pending Alembic migrations programmatically. Prefer the CLI instead: authfort migrate --database-url "...".
Returns: None
dispose()
Section titled “dispose()”Dispose the database engine and connection pool.
Returns: None
get_session()
Section titled “get_session()”Async context manager for database sessions (for non-FastAPI code).
async with auth.get_session() as session:
... async with auth.get_session() as session:
... FastAPI Integration
Section titled “FastAPI Integration”fastapi_router()
Section titled “fastapi_router()”Returns a FastAPI APIRouter with all auth endpoints (signup, login, logout, refresh, me, password reset, OAuth). Mount with app.include_router(auth.fastapi_router(), prefix="/auth").
Returns: APIRouter
jwks_router()
Section titled “jwks_router()”Returns a FastAPI APIRouter serving /.well-known/jwks.json. Mount separately: app.include_router(auth.jwks_router()).
Returns: APIRouter
current_user
Section titled “current_user”FastAPI dependency that extracts and verifies the JWT from the request. Returns a UserResponse.
@app.get("/profile")async def profile(user: UserResponse = Depends(auth.current_user)): return userrequire_role(role)
Section titled “require_role(role)”FastAPI dependency factory that checks if the authenticated user has a specific role (or any of a list of roles).
| Param | Type | Description |
|---|---|---|
role | str | list[str] | Required role(s) — user must have at least one |
@app.get("/admin")async def admin(user=Depends(auth.require_role("admin"))): ...See FastAPI Integration for full usage guide.
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
config | AuthFortConfig | Read-only access to configuration |
session_factory | async_sessionmaker | The async session factory |
hooks | HookRegistry | The event hook registry |