Configuration
The AuthFort constructor accepts the following parameters. Only database_url is required — everything else has sensible defaults.
from authfort import AuthFort, CookieConfig, GoogleProvider, RateLimitConfig
auth = AuthFort(
database_url="postgresql+asyncpg://user:pass@localhost/mydb",
access_token_ttl=900,
refresh_token_ttl=2592000,
jwt_issuer="authfort",
cookie=CookieConfig(),
providers=[GoogleProvider(client_id="...", client_secret="...")],
key_rotation_ttl=172800,
introspect_secret="shared-secret-with-services",
allow_signup=True,
password_reset_ttl=3600,
rsa_key_size=2048,
frontend_url="https://app.example.com",
email_verify_ttl=86400,
magic_link_ttl=600,
email_otp_ttl=300,
allow_passwordless_signup=False,
rate_limit=RateLimitConfig(),
trust_proxy=False,
trusted_proxies=["172.18.0.0/16"],
) from authfort import AuthFort, CookieConfig, GoogleProvider, RateLimitConfig
auth = AuthFort(
database_url="postgresql+asyncpg://user:pass@localhost/mydb",
access_token_ttl=900,
refresh_token_ttl=2592000,
jwt_issuer="authfort",
cookie=CookieConfig(),
providers=[GoogleProvider(client_id="...", client_secret="...")],
key_rotation_ttl=172800,
introspect_secret="shared-secret-with-services",
allow_signup=True,
password_reset_ttl=3600,
rsa_key_size=2048,
frontend_url="https://app.example.com",
email_verify_ttl=86400,
magic_link_ttl=600,
email_otp_ttl=300,
allow_passwordless_signup=False,
rate_limit=RateLimitConfig(),
trust_proxy=False,
trusted_proxies=["172.18.0.0/16"],
) Parameters
Section titled “Parameters”database_url (required)
Section titled “database_url (required)”SQLAlchemy-compatible async database URL.
| Database | URL Format |
|---|---|
| PostgreSQL | postgresql+asyncpg://user:pass@host/dbname |
| SQLite | sqlite+aiosqlite:///path/to/db.sqlite |
| MySQL | mysql+aiomysql://user:pass@host/dbname |
access_token_ttl
Section titled “access_token_ttl”Access token lifetime in seconds. Default: 900 (15 minutes).
Short-lived tokens limit the window of exposure if a token is leaked. The client SDK handles automatic refresh before expiry.
refresh_token_ttl
Section titled “refresh_token_ttl”Refresh token lifetime in seconds. Default: 2592000 (30 days).
This is effectively the “remember me” duration. Each time the token is refreshed, the expiry resets — so the user only has to log in again after 30 days of inactivity.
jwt_issuer
Section titled “jwt_issuer”The iss claim in issued JWTs. Default: "authfort".
Microservices using authfort-service must configure the same issuer value.
cookie
Section titled “cookie”Cookie configuration. Default: None (bearer-only mode).
Pass CookieConfig() to enable cookie-based token delivery. See Cookies & Bearer for all cookie options.
providers
Section titled “providers”List of OAuth providers. Default: None.
from authfort import GoogleProvider, GitHubProvider, GenericOIDCProvider
providers=[
GoogleProvider(client_id="...", client_secret="..."),
GitHubProvider(client_id="...", client_secret="..."),
GenericOIDCProvider("keycloak", client_id="...", client_secret="...",
discovery_url="https://keycloak.example.com/.well-known/openid-configuration"),
] from authfort import GoogleProvider, GitHubProvider, GenericOIDCProvider
providers=[
GoogleProvider(client_id="...", client_secret="..."),
GitHubProvider(client_id="...", client_secret="..."),
GenericOIDCProvider("keycloak", client_id="...", client_secret="...",
discovery_url="https://keycloak.example.com/.well-known/openid-configuration"),
] See OAuth Providers for setup details.
key_rotation_ttl
Section titled “key_rotation_ttl”How long a retired signing key stays valid after rotation, in seconds. Default: 172800 (48 hours).
When you call rotate_key(), the old key’s expiry is set to now + key_rotation_ttl. It stays in JWKS until then, so tokens signed with the old key remain valid during the transition.
introspect_secret
Section titled “introspect_secret”Shared secret for the token introspection endpoint. Default: None (introspection disabled).
Set this to a strong random string. Microservices using authfort-service must know this secret to call the introspection endpoint.
allow_signup
Section titled “allow_signup”Whether to allow public user registration via the /auth/signup endpoint. Default: True.
Set to False to disable public signup. You can still create users programmatically via auth.create_user().
password_reset_ttl
Section titled “password_reset_ttl”Password reset token lifetime in seconds. Default: 3600 (1 hour).
After this time, the reset token expires and the user must request a new one.
rsa_key_size
Section titled “rsa_key_size”RSA key size in bits. Default: 2048. Must be >= 2048.
Controls the size of RSA keys generated for JWT signing. Larger keys are more secure but slower. 2048-bit keys are considered safe for most use cases. Use 4096 for higher security requirements.
frontend_url
Section titled “frontend_url”Frontend origin URL for cross-origin OAuth redirects. Default: None.
When your frontend and API are on different domains (e.g., app.example.com and api.example.com), set this to your frontend origin. AuthFort will prepend it to redirect_to paths so OAuth redirects land on the correct domain.
auth = AuthFort( database_url="...", frontend_url="https://app.example.com", # ...)Without frontend_url, a redirect_to=/dashboard will redirect to api.example.com/dashboard (the API server). With frontend_url="https://app.example.com", it redirects to https://app.example.com/dashboard.
If your frontend and API share the same origin, you don’t need this.
email_verify_ttl
Section titled “email_verify_ttl”Email verification token lifetime in seconds. Default: 86400 (24 hours).
magic_link_ttl
Section titled “magic_link_ttl”Magic link token lifetime in seconds. Default: 600 (10 minutes).
Short-lived for security — magic links are sensitive since they grant full login access.
email_otp_ttl
Section titled “email_otp_ttl”Email OTP code lifetime in seconds. Default: 300 (5 minutes).
Short-lived since OTP codes are easier to guess (6 digits = 1,000,000 combinations).
allow_passwordless_signup
Section titled “allow_passwordless_signup”Whether magic links and email OTP auto-create users for unknown emails. Default: False.
When True, requesting a magic link or OTP for a non-existent email creates a new user with no password. The user can only log in via passwordless methods until they set a password via the password reset flow.
This is independent of allow_signup — you can disable password-based signup but allow passwordless signup.
rate_limit
Section titled “rate_limit”Rate limiting configuration. Default: None (disabled). Strongly recommended for production — see Rate Limiting.
Pass a RateLimitConfig to enable per-endpoint rate limiting on all auth endpoints. Uses an in-memory sliding window counter by default.
from authfort import RateLimitConfig
auth = AuthFort( database_url="...", rate_limit=RateLimitConfig(), # all defaults)
# Or customize per endpointauth = AuthFort( database_url="...", rate_limit=RateLimitConfig( login="10/min", signup="5/min", refresh=None, # disable for refresh ),)| Endpoint | Default |
|---|---|
login | 5/min |
signup | 3/min |
magic_link | 5/min |
otp | 5/min |
verify_email | 5/min |
refresh | 30/min |
oauth_authorize | 10/min |
Format: "{count}/{period}" where period is sec, min, hour, or day. Set to None to disable for that endpoint.
See Rate Limiting for details on IP/email-based limiting, events, and custom storage backends.
trust_proxy
Section titled “trust_proxy”Whether to trust proxy headers (X-Forwarded-For, X-Real-IP) from any source. Default: False.
Enable this when AuthFort runs behind a single reverse proxy (nginx, traefik, cloud load balancer) and you trust all incoming connections. The leftmost IP in X-Forwarded-For is used as the client IP for rate limiting and audit events.
Only enable this if AuthFort is not directly exposed to the internet. An attacker can spoof X-Forwarded-For to bypass IP-based rate limiting.
trusted_proxies
Section titled “trusted_proxies”List of trusted proxy IPs or CIDR ranges. Default: None. Recommended for production.
Only requests arriving from these addresses will have their proxy headers read. Requests from other IPs use request.client.host directly, preventing spoofing.
Supports individual IPs and CIDR notation:
auth = AuthFort( database_url="...", trusted_proxies=["172.18.0.0/16", "10.0.0.1"],)When trusted_proxies is set, trust_proxy is ignored — the trusted list takes precedence. Networks are parsed once at startup using Python’s ipaddress module (zero per-request overhead).