Skip to content

Configuration

All configuration lives in dataclasses in fastauth.config. Construct a FastAuthConfig, pass it to FastAuth, then call auth.mount(app).

from fastauth import FastAuth, FastAuthConfig, JWTConfig, PasswordConfig, SecurityConfig

config = FastAuthConfig(
    secret="...",             # required
    providers=[...],           # required
    adapter=...,              # required
    # everything below is optional
    token_adapter=...,
    jwt=JWTConfig(...),
    password=PasswordConfig(...),
    security=SecurityConfig(...),
)
auth = FastAuth(config)
auth.role_adapter = ...        # optional, post-construction
auth.session_adapter = ...     # optional, post-construction

FastAuthConfig

Required

Field Type Default Description
secret str HMAC secret for HS256. Must be ≥32 bytes. Generate with fastauth generate-secret.
providers list[Any] One or more provider instances.
adapter UserAdapter Reads/writes user records.

JWT and tokens

Field Type Default Description
jwt JWTConfig JWTConfig() JWT algorithm, lifetimes, JWKS settings.
token_adapter TokenAdapter \| None None Persists one-time tokens (verification, reset, email change) and refresh JTIs. Required for refresh tokens, magic links, email verification, password reset, email change, and login lockout tracking.
require_token_adapter_for_refresh bool True Reject refresh issuance when token_adapter is None. Set to False only for tests/demos; doing so disables revocation, replay detection, and password-reset revocation.
token_delivery "json" \| "cookie" "json" json returns tokens in the response body; cookie sets HttpOnly cookies.
Field Type Default Description
cookie_name_access str "access_token" Access-token cookie name.
cookie_name_refresh str "refresh_token" Refresh-token cookie name.
cookie_secure bool \| None None Nonenot debug (secure in prod, insecure in dev).
cookie_httponly bool True HttpOnly flag.
cookie_samesite "lax" \| "strict" \| "none" "lax" SameSite policy.
cookie_domain str \| None None Optional domain scope.
csrf_enabled bool True Require matching X-CSRF-Token header on cookie-authenticated unsafe requests.
csrf_cookie_name str "csrf_token" Readable CSRF cookie (set alongside access/refresh).
csrf_header_name str "X-CSRF-Token" Header the client must send.

Email

Field Type Default Description
email_transport EmailTransport \| None None If None, all email flows are silently no-ops.
email_template_dir str \| Path \| None None Directory of Jinja2 overrides; missing files fall back to built-ins via ChoiceLoader.
base_url str "http://localhost:8000" Public URL used to build verification/reset/email-change links.

OAuth

Field Type Default Description
oauth_adapter OAuthAccountAdapter \| None None Persists linked OAuth accounts. Required for all OAuth endpoints.
oauth_state_store SessionBackend \| None None Stores OAuth CSRF + PKCE state (TTL 600s). Required for OAuth.
oauth_redirect_url str \| None None Frontend URL FastAuth 302s to after a successful OAuth callback. Tokens are set as cookies on that response, never appended to the URL.
oauth_allowed_redirect_uris list[str] \| None None Exact provider-callback URLs allowed in redirect_uri on authorize/link endpoints. None accepts any URI — set this in production.
store_oauth_provider_tokens bool False Persist the OAuth provider's access/refresh tokens in OAuthAccountData.

Passkeys

Field Type Default Description
passkey_adapter PasskeyAdapter \| None None Persists passkey credential records. Required for /auth/passkeys/*.
passkey_state_store SessionBackend \| None None Stores WebAuthn challenge state (TTL 300s). Required for passkeys.

RBAC

Field Type Default Description
roles list[dict] \| None None Seed role definitions applied on auth.initialize_roles(). Each dict: {"name": str, "permissions": list[str]}.
default_role str \| None None Role auto-assigned to every newly created user (you must still set auth.role_adapter).

Sessions, CORS, routes, debug

Field Type Default Description
session_strategy "jwt" \| "database" "jwt" Currently informational only. FastAuth always issues JWT pairs. "database" is reserved for a future server-side session model and is not wired to auth routes.
session_backend SessionBackend \| None None Reserved for the future "database" strategy. To use /auth/sessions, assign auth.session_adapter = adapter.session instead.
cors_origins list[str] \| None None Adds Starlette CORSMiddleware with allow_credentials=True. None disables the middleware.
route_prefix str "/auth" URL prefix for all FastAuth endpoints. /.well-known/jwks.json is always mounted at root.
debug bool False Relaxes cookie security (Secure=False) and enables verbose error output. Never enable in production.

Hooks

Field Type Default Description
hooks EventHooks \| None None An EventHooks subclass instance for lifecycle callbacks. See Hooks.

JWTConfig

Field Type Default Description
algorithm "HS256" \| "RS256" \| "RS512" "HS256" Signing algorithm.
access_token_ttl int 900 (15 min) Access-token lifetime in seconds.
refresh_token_ttl int 2592000 (30 days) Refresh-token lifetime in seconds.
remember_me_ttl int 7776000 (90 days) Used when login is called with remember=true.
issuer str \| None None iss claim; validated on decode if set.
audience list[str] \| None None aud claim; validated on decode if set.
jwks_enabled bool False Expose /.well-known/jwks.json and use kid-headed signing. Required for RS256/RS512.
key_rotation_interval int \| None None Seconds between pruning old RSA keys. None keeps all keys.
private_key str \| None None PEM RSA private key. If None and jwks_enabled=True, a 2048-bit key is auto-generated on initialize_jwks().
public_key str \| None None PEM RSA public key. Same auto-generation rule.

Choosing HS256 vs RS256

  • HS256 — simplest. One shared secret. Fine for single-process apps and internal services that share secret.
  • RS256 / RS512 — asymmetric. Resource services verify tokens using only the public key from /.well-known/jwks.json. Required for microservices. You must set jwks_enabled=True and call await auth.initialize_jwks() inside your lifespan.

Provide your own PEM keys (recommended in production) or let JWKSManager.initialize() generate a fresh 2048-bit key pair at startup. Auto-generated keys are ephemeral — they change on every process restart, invalidating existing tokens. For production, load keys from a file or secret manager.

PasswordConfig

Field Default Description
min_length 8 Minimum password length.
max_length 128 Maximum password length.
require_uppercase False Require ≥1 uppercase.
require_lowercase False Require ≥1 lowercase.
require_digit False Require ≥1 digit.
require_special False Require ≥1 special character.

Passwords are hashed with Argon2 (argon2-cffi).

SecurityConfig

Field Default Description
max_login_attempts 5 Failed credential-login attempts before lockout.
lockout_duration 300 Lockout duration in seconds.
login_attempts_by_ip False Also throttle by client IP when available. Email-based throttling is always applied.
use_memory_login_attempts_without_token_adapter True In-process memory tracking when token_adapter is None. Non-production fallback; configure token_adapter so attempt state is shared and durable.

Validation

FastAuthConfig.__post_init__ raises ConfigError for:

  • empty secret
  • HS256 secret shorter than 32 bytes
  • empty providers
  • require_token_adapter_for_refresh=True without token_adapter
  • session_strategy="database" without session_backend
  • RS256/RS512 without jwks_enabled=True

Common mistakes

  • Setting cookie_secure=True on localhost — browsers reject Secure cookies on http://localhost. Use debug=True (sets Secure=False) or test over HTTPS.
  • Forgetting oauth_allowed_redirect_uris in production — defaults to accepting any redirect_uri, which is an OAuth open-redirect risk.
  • Setting oauth_redirect_url to the provider callbackoauth_redirect_url is your frontend post-callback URL; the provider callback is /auth/oauth/{provider}/callback, identified by redirect_uri on the authorize endpoint.