Rate limiting¶
AuthRateLimitConfig.from_shared_backend() is the canonical public entrypoint for the common shared-backend recipe. It materializes endpoint-specific EndpointRateLimit values from the private auth slot catalog while keeping manual AuthRateLimitConfig(..., EndpointRateLimit(...)) assembly available as the advanced escape hatch.
Import the builder aliases from litestar_auth.ratelimit when app code annotates shared-backend inputs:
AuthRateLimitEndpointSlotnames the per-endpoint keys accepted byenabled,disabled,scope_overrides,namespace_overrides, andendpoint_overrides.AuthRateLimitEndpointGroupnames the shared-backend keys accepted bygroup_backends.
Those aliases are the stable builder identifiers:
AuthRateLimitEndpointSlot value |
AuthRateLimitEndpointGroup value |
Default scope | Default namespace token |
|---|---|---|---|
login |
login |
ip_email |
login |
refresh |
refresh |
ip |
refresh |
register |
register |
ip |
register |
forgot_password |
password_reset |
ip_email |
forgot-password |
reset_password |
password_reset |
ip |
reset-password |
totp_enable |
totp |
ip |
totp-enable |
totp_confirm_enable |
totp |
ip |
totp-confirm-enable |
totp_verify |
totp |
ip |
totp-verify |
totp_disable |
totp |
ip |
totp-disable |
verify_token |
verification |
ip |
verify-token |
request_verify_token |
verification |
ip_email |
request-verify-token |
There is no extra preset or namespace-family mode behind those aliases. Use group_backends, scope_overrides,
namespace_overrides, disabled, and endpoint_overrides directly when migrating existing key shapes.
Override precedence is:
endpoint_overrideswins per slot and can replace the limiter or set it toNone.- Otherwise, only slots enabled by
enabled(defaults to all supported slots) and not listed indisabledare generated. - Generated limiters start from
backend, thengroup_backendscan swap the backend for the slot's group. scope_overridesandnamespace_overridesadjust the generated limiter for that slot.
Those identifiers are the public builder contract. The private recipe objects that store them remain internal implementation details.
litestar_auth.ratelimit
¶
Rate-limiting helpers for authentication endpoints.
Use :meth:AuthRateLimitConfig.from_shared_backend for the common case where a
single :class:InMemoryRateLimiter or :class:RedisRateLimiter should back the
standard auth endpoint set. Keep manual AuthRateLimitConfig(...) plus
EndpointRateLimit(...) assembly for advanced cases that need fully custom
per-endpoint wiring.
Examples:
Build the canonical shared-backend recipe::
from litestar_auth.ratelimit import AuthRateLimitConfig, RedisRateLimiter
rate_limit_config = AuthRateLimitConfig.from_shared_backend(
RedisRateLimiter(redis=redis_client, max_attempts=5, window_seconds=60),
)
AuthRateLimitEndpointGroup = Literal['login', 'password_reset', 'refresh', 'register', 'totp', 'verification']
¶
AuthRateLimitEndpointSlot = Literal['login', 'refresh', 'register', 'forgot_password', 'reset_password', 'totp_enable', 'totp_confirm_enable', 'totp_verify', 'totp_disable', 'verify_token', 'request_verify_token']
¶
RateLimitScope = Literal['ip', 'ip_email']
¶
TotpSensitiveEndpoint = Literal['enable', 'confirm_enable', 'verify', 'disable']
¶
AuthRateLimitConfig(login=None, refresh=None, register=None, forgot_password=None, reset_password=None, totp_enable=None, totp_confirm_enable=None, totp_verify=None, totp_disable=None, verify_token=None, request_verify_token=None)
dataclass
¶
Optional rate-limit rules for auth-related endpoints.
from_shared_backend(backend, *, enabled=None, disabled=(), group_backends=None, scope_overrides=None, namespace_overrides=None, endpoint_overrides=None, trusted_proxy=False, identity_fields=_DEFAULT_IDENTITY_FIELDS, trusted_headers=_DEFAULT_TRUSTED_HEADERS)
classmethod
¶
Build endpoint-specific limiters from the package-owned shared-backend recipe.
The builder uses the private endpoint catalog for default scopes and namespace tokens, then applies override precedence in this order:
backendfor every enabled slotgroup_backendsfor slot groups such astotporverificationscope_overrides/namespace_overridesfor slot-specific tweaksendpoint_overridesfor full slot replacement or explicitNonedisablement
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
backend
|
RateLimiterBackend
|
Default limiter backend for enabled auth slots. |
required |
enabled
|
Iterable[AuthRateLimitEndpointSlot] | None
|
Optional auth slot names to build. Defaults to all supported slots. |
None
|
disabled
|
Iterable[AuthRateLimitEndpointSlot]
|
Auth slot names to leave unset, even when they would otherwise be enabled. |
()
|
group_backends
|
Mapping[AuthRateLimitEndpointGroup, RateLimiterBackend] | None
|
Optional backend overrides keyed by auth slot group:
|
None
|
scope_overrides
|
Mapping[AuthRateLimitEndpointSlot, RateLimitScope] | None
|
Optional per-slot scope overrides to preserve existing key behavior. |
None
|
namespace_overrides
|
Mapping[AuthRateLimitEndpointSlot, str] | None
|
Optional per-slot namespace tokens to preserve existing key names. |
None
|
endpoint_overrides
|
Mapping[AuthRateLimitEndpointSlot, EndpointRateLimit | None] | None
|
Optional full per-slot replacements. |
None
|
trusted_proxy
|
bool
|
Shared trusted-proxy setting applied to generated limiters. |
False
|
identity_fields
|
tuple[str, ...]
|
Shared request body identity fields applied to generated limiters. |
_DEFAULT_IDENTITY_FIELDS
|
trusted_headers
|
tuple[str, ...]
|
Shared trusted proxy header names applied to generated limiters. |
_DEFAULT_TRUSTED_HEADERS
|
Returns:
| Type | Description |
|---|---|
Self
|
New config populated from the shared-backend builder inputs. |
Source code in litestar_auth/ratelimit/_config.py
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | |
EndpointRateLimit(backend, scope, namespace, trusted_proxy=False, identity_fields=_DEFAULT_IDENTITY_FIELDS, trusted_headers=_DEFAULT_TRUSTED_HEADERS)
dataclass
¶
Per-endpoint rate-limit settings and request hook.
before_request(request)
async
¶
Reject the request with 429 when its key is over the configured limit.
Security
Only set trusted_proxy=True when this service is behind a trusted
proxy or load balancer that overwrites client IP headers. Otherwise,
attackers can spoof headers like X-Forwarded-For and evade or
poison rate-limiting keys.
Raises:
| Type | Description |
|---|---|
TooManyRequestsException
|
If the request exceeded the configured limit. |
Source code in litestar_auth/ratelimit/_config.py
build_key(request)
async
¶
Build the backend key for the given request.
Returns:
| Type | Description |
|---|---|
str
|
Namespaced rate-limit key for the request. |
Source code in litestar_auth/ratelimit/_config.py
increment(request)
async
¶
Record a failed or rate-limited attempt for the current request.
reset(request)
async
¶
InMemoryRateLimiter(*, max_attempts, window_seconds, max_keys=100000, sweep_interval=1000, clock=time.monotonic)
¶
Async-safe in-memory sliding-window rate limiter.
Not safe for multi-process or multi-host deployments; use :class:RedisRateLimiter
for shared storage (e.g. multi-worker or multi-pod).
Store the limiter configuration and request counters.
Raises:
| Type | Description |
|---|---|
ValueError
|
If any limiter or storage configuration is invalid. |
Source code in litestar_auth/ratelimit/_memory.py
is_shared_across_workers
property
¶
In-memory counters are process-local and not shared across workers.
check(key)
async
¶
Return whether key can perform another attempt.
Source code in litestar_auth/ratelimit/_memory.py
increment(key)
async
¶
Record a new attempt for key in the current window.
Source code in litestar_auth/ratelimit/_memory.py
reset(key)
async
¶
retry_after(key)
async
¶
Return the remaining block duration for key in whole seconds.
Source code in litestar_auth/ratelimit/_memory.py
RedisRateLimiter(*, redis, max_attempts, window_seconds, key_prefix=DEFAULT_KEY_PREFIX, clock=time.time)
¶
Redis-backed sliding-window rate limiter backed by a sorted set.
Store the Redis client and shared rate-limiter configuration.
Source code in litestar_auth/ratelimit/_redis.py
is_shared_across_workers
property
¶
Redis-backed counters are shared across workers using the same Redis.
check(key)
async
¶
Return whether key can perform another attempt.
Source code in litestar_auth/ratelimit/_redis.py
increment(key)
async
¶
Record a new attempt for key atomically in Redis.
Source code in litestar_auth/ratelimit/_redis.py
reset(key)
async
¶
retry_after(key)
async
¶
Return the remaining block duration for key in whole seconds.
Source code in litestar_auth/ratelimit/_redis.py
RateLimiterBackend
¶
TotpRateLimitOrchestrator(enable=None, confirm_enable=None, verify=None, disable=None, _ACCOUNT_STATE_RESET_ENDPOINTS=frozenset({'verify'}))
dataclass
¶
Orchestrate TOTP endpoint rate-limit behavior with explicit semantics.
External behavior stays unchanged:
- verify uses before-request checks, increments on invalid attempts, and
resets on success/account-state failures.
- enable and disable do not consume verify counters.
Endpoints that should reset on account-state failures are listed in
_ACCOUNT_STATE_RESET_ENDPOINTS (currently only verify).
before_request(endpoint, request)
async
¶
Run endpoint-specific before-request checks.
Source code in litestar_auth/ratelimit/_orchestrator.py
on_account_state_failure(endpoint, request)
async
¶
Apply endpoint-specific account-state failure behavior.
Source code in litestar_auth/ratelimit/_orchestrator.py
on_invalid_attempt(endpoint, request)
async
¶
Record endpoint-specific invalid attempt failures.
Source code in litestar_auth/ratelimit/_orchestrator.py
on_success(endpoint, request)
async
¶
Apply endpoint-specific success behavior.