adminAuth now returns 429 with Retry-After once the bucket is exhausted, before key comparison; lockout applies to correct keys too (prevents hammering).
Verified constant-time key compare (crypto/subtle ConstantTimeCompare) was already in place (#40) — no change needed.
Failed attempts were already logged (#40); rate-limited attempts now also logged.
Tests (internal/api/adminratelimit_test.go): hammering bad keys yields 401s then 429 with Retry-After; correct key from same IP is locked out; correct key from a different IP still works; constant-time compare sanity check.
All tests pass (go build ./..., go vet ./..., go test ./...).
## Fixes #66
Admin endpoint (`/admin/api/settings`) had no rate limiting or lockout on key attempts.
- Added `rateLimitAdmin`: per-IP token bucket, 5 attempts/min, reusing the existing unlock rate limiter mechanism (#34 pattern).
- `adminAuth` now returns 429 with `Retry-After` once the bucket is exhausted, before key comparison; lockout applies to correct keys too (prevents hammering).
- Verified constant-time key compare (crypto/subtle ConstantTimeCompare) was already in place (#40) — no change needed.
- Failed attempts were already logged (#40); rate-limited attempts now also logged.
Tests (`internal/api/adminratelimit_test.go`): hammering bad keys yields 401s then 429 with Retry-After; correct key from same IP is locked out; correct key from a different IP still works; constant-time compare sanity check.
All tests pass (`go build ./...`, `go vet ./...`, `go test ./...`).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes #66
Admin endpoint (
/admin/api/settings) had no rate limiting or lockout on key attempts.rateLimitAdmin: per-IP token bucket, 5 attempts/min, reusing the existing unlock rate limiter mechanism (#34 pattern).adminAuthnow returns 429 withRetry-Afteronce the bucket is exhausted, before key comparison; lockout applies to correct keys too (prevents hammering).Tests (
internal/api/adminratelimit_test.go): hammering bad keys yields 401s then 429 with Retry-After; correct key from same IP is locked out; correct key from a different IP still works; constant-time compare sanity check.All tests pass (
go build ./...,go vet ./...,go test ./...).