fix(rate-limit): exempt register-challenge from the per-IP floor (stateless mint) #441
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/BUNYIP-450-exempt-register-challenge-rate-floor"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
BUNYIP-450 (relates BUNYIP-445 / BUNYIP-449). The durable fix behind the E2E register-challenge 429s.
Problem
GET /v1/auth/register-challengesits under the per-IPAPI_UNAUTHrate-limit floor (20 req/60s/IP) because it is not inrate_limit_floor::EXEMPT_PATHS. But its handler mints only a stateless HS256 timestamp token (JwtService::create_signup_challenge_token,crates/bunyip-domain/src/services/jwt.rs:260- no DB write, no side effect) and documents "needs no rate limit". So the floor adds no protection there; it only produces a false 429 for any real clients that share a source IP (a NAT/proxy) and for the E2E runner's single egress IP - which failed the disposable-account specs (BUNYIP-445 run #2453, mitigated harness-side in BUNYIP-449).Change
Add
/v1/auth/register-challengetoEXEMPT_PATHS. The register POST it precedes (POST /v1/auth/register) stays under the floor and the BUNYIP-377 bot guard, so removing the floor from the challenge mint alone opens no registration-abuse path.Tests: the exempt-list test now asserts register-challenge is exempt; the capped-list test asserts
/v1/auth/register(POST) stays floored and that the/v1/auth/register-challenge/extranear-miss does not fall through the exact-match list.Verification
just check-container(fmt + clippy -D warnings + workspace lib tests) passes.🤖 Generated with Claude Code