Add metered open signups, per-IP limits, and auth security hardening

Enables public beta signup metering: DAILY_OPEN_SIGNUPS env var controls
how many users can register without an invite code per day (0=disabled,
-1=unlimited, N=daily cap). Invite codes always bypass the limit.

Also adds per-IP signup throttling (DAILY_SIGNUPS_PER_IP, default 3/day)
and fail-closed rate limiting on auth endpoints when Redis is down.

Client dynamically fetches /api/auth/signup-info to show invite field
as optional with remaining slots when open signups are enabled.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken
2026-02-24 14:28:28 -05:00
parent 3d02d739e5
commit 6461a7f0c7
9 changed files with 320 additions and 14 deletions

View File

@@ -81,11 +81,15 @@ class RateLimitMiddleware(BaseHTTPMiddleware):
# Generate client key
client_key = self.limiter.get_client_key(request, user_id)
# Check rate limit
# Check rate limit (fail closed for auth endpoints)
endpoint_key = self._get_endpoint_key(path)
full_key = f"{endpoint_key}:{client_key}"
allowed, info = await self.limiter.is_allowed(full_key, limit, window)
is_auth_endpoint = path.startswith("/api/auth")
if is_auth_endpoint:
allowed, info = await self.limiter.is_allowed_strict(full_key, limit, window)
else:
allowed, info = await self.limiter.is_allowed(full_key, limit, window)
# Build response
if allowed: