Configuration Reference¶
Session Configuration¶
Passed to SessionServiceFactory or SessionService:
| Parameter | Default | Description |
|---|---|---|
token_prefix |
nz_session_ |
Prefix for session tokens |
session_lifetime_seconds |
604800 (7 days) |
Maximum session duration |
sliding_window_seconds |
3600 (1 hour) |
Extension on activity (None to disable) |
max_sessions_per_subject |
None (unlimited) | Maximum concurrent sessions |
Password Factor¶
PasswordFactor accepts a PasswordHasherProtocol implementation.
The recommended hasher is pwdlib.PasswordHash.recommended() which
uses Argon2id.
Password policy is enforced at the application level. NeoZen provides
PasswordPolicy for validation:
| Setting | Default | Description |
|---|---|---|
min_length |
8 | Minimum password length |
max_length |
128 | Maximum password length |
require_uppercase |
false | Require uppercase letter |
require_lowercase |
false | Require lowercase letter |
require_digit |
false | Require digit |
require_special |
false | Require special character |
Magic Link Configuration¶
MagicLinkConfig (frozen dataclass):
| Setting | Default | Description |
|---|---|---|
token_lifetime |
15 minutes | Token validity period |
max_pending_per_subject |
3 | Max pending tokens (rate limit) |
rate_limit_window |
1 hour | Rate limit window |
token_prefix |
nz_ml_ |
Token prefix |
link_base_url |
"" (required) |
Base URL for verify endpoint |
TOTP Configuration¶
TOTPConfig (frozen dataclass):
| Setting | Default | Description |
|---|---|---|
issuer |
(required) | App name in authenticator |
digits |
6 | OTP code length |
interval |
30 | Code rotation (seconds) |
backup_code_count |
8 | Number of backup codes |
backup_code_length |
8 | Backup code length |
Password Reset Configuration¶
PasswordResetConfig (frozen dataclass):
| Setting | Default | Description |
|---|---|---|
token_lifetime |
1 hour | Reset token validity |
max_pending_requests |
3 | Max pending resets per subject |
rate_limit_window |
24 hours | Rate limit window |
token_prefix |
nz_pr_ |
Token prefix |
Rate Limiting¶
RateLimitConfig:
| Setting | Default | Description |
|---|---|---|
max_attempts |
5 | Max attempts in window |
window_seconds |
60 | Time window |
Account Lockout¶
LockoutConfig:
| Setting | Default | Description |
|---|---|---|
max_attempts |
5 | Failures before lockout |
lockout_duration_seconds |
300 | Lockout period |
progressive |
true | Increase duration on repeat lockouts |
OAuth Server¶
The [oauth_server] section of neozen.toml. NeoZenFactory turns it into configured services: create_oauth_token_service(...), create_authorization_endpoint(...), create_id_token_generator() and create_discovery_metadata(base_url). They raise ConfigError unless enabled = true. Token and code hashes are keyed with security.secret_key.
| Setting | Default | Description |
|---|---|---|
enabled |
false | Allow the factory to build OAuth services |
issuer |
unset | The server's identifier: iss of ID tokens and JWT access tokens, and the discovery issuer |
access_token_lifetime |
1h |
Access token validity |
refresh_token_lifetime |
30d |
Refresh token validity |
authorization_code_lifetime |
10m |
Authorization code validity |
require_pkce |
true | When false, confidential clients may skip PKCE. Public clients always need S256 |
allow_refresh_token_rotation |
true | Issue a new refresh token on each refresh and revoke the old one. Public clients always rotate |
jwt_access_tokens |
false | Issue RFC 9068 JWT access tokens (typ: at+jwt) instead of opaque ones; needs issuer and jwt_audience |
jwt_audience |
unset | aud claim of JWT access tokens |
jwt_algorithm |
RS256 |
Signing algorithm for ID tokens and JWT access tokens: RS256 or ES256 |
One key manager signs ID tokens and JWT access tokens and backs the JWKS: the factory's key_manager. Pass a persistent KeyManager (signing with jwt_algorithm) to NeoZenFactory(config, key_manager=...) in production; the default in-memory one loses its keys on restart. JWT access tokens are still stored hashed, so introspection and revocation work as for opaque tokens.
[oauth_server]
enabled = true
issuer = "https://auth.example.com"
access_token_lifetime = "15m"
jwt_access_tokens = true
jwt_audience = "https://api.example.com"
jwt_algorithm = "ES256"
from neozen.ext.litestar.oauth import create_oauth_router, create_oidc_router
from neozen.web.oidc import DiscoveryEndpoint, JWKSEndpoint
factory = NeoZenFactory(load_config(), key_manager=my_persistent_key_manager)
token_service = factory.create_oauth_token_service(
client_repo, code_repo, access_token_repo, refresh_token_repo
)
authorization_endpoint = factory.create_authorization_endpoint(
client_service, grant_repo, code_repo
)
# Discovery and JWKS under /.well-known, so resource servers can verify tokens
oidc_router = create_oidc_router(
DiscoveryEndpoint(factory.create_discovery_metadata("https://auth.example.com")),
JWKSEndpoint(factory.key_manager),
)
Starlette and Flask have the same pair: create_oauth_routes / create_oidc_routes and create_oauth_blueprint / create_oidc_blueprint.
Token Prefixes¶
| Prefix | Purpose |
|---|---|
nz_session_ |
Session token |
nz_ev_ |
Email verification |
nz_ml_ |
Magic link |
nz_pr_ |
Password reset |
nz_at_ |
OAuth access token |
nz_rt_ |
OAuth refresh token |
nz_ac_ |
OAuth authorization code |