Skip to content

Rate Limiter

dagster_authkit.auth.rate_limiter

Rate Limiter - Brute Force Protection

Supports both in-memory (single-pod) and Redis (distributed) backends.

RateLimiterBackend

Bases: ABC

Abstract rate limiter backend.

is_rate_limited abstractmethod

is_rate_limited(identifier, max_attempts, window_seconds)

Check if identifier is rate limited.

Parameters:

Name Type Description Default
identifier str

Username or IP address

required
max_attempts int

Maximum attempts allowed

required
window_seconds int

Time window in seconds

required

Returns:

Type Description
Tuple[bool, int]

Tuple[bool, int]: (is_limited, attempts_count)

record_attempt abstractmethod

record_attempt(identifier, window_seconds)

Record a failed attempt.

Parameters:

Name Type Description Default
identifier str

Username or IP address

required
window_seconds int

Time window in seconds

required

Returns:

Name Type Description
int int

Current attempt count

check_and_record abstractmethod

check_and_record(identifier, max_attempts, window_seconds)

Atomically check if rate limited and record an attempt.

Eliminates the TOCTOU race between is_rate_limited() and record_attempt() when called separately.

Parameters:

Name Type Description Default
identifier str

Username or IP address

required
max_attempts int

Maximum attempts allowed

required
window_seconds int

Time window in seconds

required

Returns:

Type Description
bool

Tuple[bool, int]: (is_limited, attempts_count)

int

Unlike check_and_record on the facade, this does NOT skip

Tuple[bool, int]

recording when already limited — the atomic operation records

Tuple[bool, int]

and checks in one step, returning the post-recording state.

reset abstractmethod

reset(identifier)

Reset attempts for identifier (after successful login).

Parameters:

Name Type Description Default
identifier str

Username or IP address

required

InMemoryRateLimiter

Bases: RateLimiterBackend

In-memory rate limiter (single-pod only).

WARNING: Does NOT work across multiple pods/instances! Each pod has its own memory, so rate limits are not shared.

Use RedisRateLimiter for distributed deployments.

__init__

__init__()

Initialise thread-safe in-memory attempt store with OOM protection.

is_rate_limited

is_rate_limited(identifier, max_attempts, window_seconds)

Check if identifier is rate limited.

check_and_record

check_and_record(identifier, max_attempts, window_seconds)

Atomically check and record an attempt. Holds the lock once.

record_attempt

record_attempt(identifier, window_seconds)

Record failed attempt.

reset

reset(identifier)

Reset counter after successful login.

RedisRateLimiter

Bases: RateLimiterBackend

Redis-backed rate limiter (distributed, multi-pod safe).

Uses Redis INCR + EXPIRE for atomic operations. Works correctly across multiple pods/instances.

__init__

__init__(redis_url)

Initialise Redis connection.

Parameters:

Name Type Description Default
redis_url str

Redis connection URL (redis:// or rediss://).

required

Raises:

Type Description
RuntimeError

If the redis package is not installed or the connection fails.

is_rate_limited

is_rate_limited(identifier, max_attempts, window_seconds)

Check if identifier is rate limited.

check_and_record

check_and_record(identifier, max_attempts, window_seconds)

Atomically check and record via Lua script.

reset

reset(identifier)

Reset attempts after successful login.

RateLimiter

Main rate limiter class (facade pattern).

Automatically selects backend based on configuration: - Redis if DAGSTER_AUTH_REDIS_URL is set - In-memory otherwise (with warning for multi-pod)

__init__

__init__(max_attempts=5, window_seconds=300, enabled=True, redis_url=None)

Initialise the rate limiter, auto-selecting the backend.

Parameters:

Name Type Description Default
max_attempts int

Maximum allowed attempts within the window.

5
window_seconds int

Time window in seconds.

300
enabled bool

If False, rate limiting is disabled entirely.

True
redis_url Optional[str]

Redis connection URL. Auto-detected from DAGSTER_AUTH_REDIS_URL if not provided.

None

check_and_record

check_and_record(identifier)

Atomically check if rate limited and record an attempt.

Delegates to the backend's atomic check_and_record, which eliminates the TOCTOU race between is_rate_limited() and record_attempt() when called separately.

Returns:

Type Description
bool

Tuple[bool, int]: (is_limited, attempts_count)

int

If is_limited is True, the attempt was recorded but

Tuple[bool, int]

the user exceeded the limit.

record_attempt

record_attempt(identifier)

Record a failed login attempt.

Parameters:

Name Type Description Default
identifier str

Username or IP address

required

Returns:

Name Type Description
int int

Current attempt count

is_rate_limited

is_rate_limited(identifier)

Check if identifier is rate limited.

Parameters:

Name Type Description Default
identifier str

Username or IP address

required

Returns:

Type Description
Tuple[bool, int]

Tuple[bool, int]: (is_limited, attempts_count)

reset

reset(identifier)

Reset attempts for identifier (after successful login).

Parameters:

Name Type Description Default
identifier str

Username or IP address

required

get_rate_limiter

get_rate_limiter()

Get rate limiter singleton (thread-safe with double-checked locking).

Returns:

Type Description
RateLimiter

Global RateLimiter instance

record_login_attempt

record_login_attempt(username)

Record failed login attempt.

Parameters:

Name Type Description Default
username str

Username

required

Returns:

Name Type Description
int int

Current attempt count

is_rate_limited

is_rate_limited(username)

Check if username is rate limited.

Parameters:

Name Type Description Default
username str

Username

required

Returns:

Type Description
Tuple[bool, int]

Tuple[bool, int]: (is_limited, attempts_count)

reset_rate_limit

reset_rate_limit(username)

Reset rate limit after successful login.

Parameters:

Name Type Description Default
username str

Username

required