+10
−0
+64
−0
Loading
The public /auth/login route runs a full-cost bcrypt compare on every request — including the anti-enumeration dummy-hash compare for an unknown user — with no bound on how many run at once. A flood of concurrent logins therefore pins every core in bcrypt, starving the rest of the API. Cap the simultaneous compares with a small non-blocking concurrency limiter (a buffered-channel semaphore): a login that cannot take a slot is shed with 429 auth_busy before the compare, rather than piling more work onto the scheduler. The slot guards only the hash and is released the instant the compare returns. It is a concurrency cap, not a per-account lockout, so it never fences out the one admin trying to break-glass in, and the 429 lands before any credential distinction so it leaks nothing about the username. The cap follows the existing "zero disables" lever idiom (WakeCooldown, MaxRunningServers); cmd/felis wires it to the core count (floored at 4).