Skip to content

Configuration

The AuthFort constructor accepts the following parameters. Only database_url is required — everything else has sensible defaults.

Example
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"],
)

SQLAlchemy-compatible async database URL.

DatabaseURL Format
PostgreSQLpostgresql+asyncpg://user:pass@host/dbname
SQLitesqlite+aiosqlite:///path/to/db.sqlite
MySQLmysql+aiomysql://user:pass@host/dbname

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 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.

The iss claim in issued JWTs. Default: "authfort".

Microservices using authfort-service must configure the same issuer value.

Cookie configuration. Default: None (bearer-only mode).

Pass CookieConfig() to enable cookie-based token delivery. See Cookies & Bearer for all cookie options.

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.

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.

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.

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 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 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 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 verification token lifetime in seconds. Default: 86400 (24 hours).

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 code lifetime in seconds. Default: 300 (5 minutes).

Short-lived since OTP codes are easier to guess (6 digits = 1,000,000 combinations).

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 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 endpoint
auth = AuthFort(
database_url="...",
rate_limit=RateLimitConfig(
login="10/min",
signup="5/min",
refresh=None, # disable for refresh
),
)
EndpointDefault
login5/min
signup3/min
magic_link5/min
otp5/min
verify_email5/min
refresh30/min
oauth_authorize10/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.

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.

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).