fix: Implement throttling for POST /api/v1/authorize - #1187
fix: Implement throttling for POST /api/v1/authorize#1187ShradhaGupta31 wants to merge 1 commit into
Conversation
ShradhaGupta31
commented
Aug 10, 2026
- Implemented IP token-bucket limiter (burst 5, refill 1/12s) to the Login handler.
- IP token-bucket limiter (burst 5, refill 1/12s) to the Login handler.
- Update the Fuego/OpenAPI declaration with the 429 response
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1187 +/- ##
==========================================
+ Coverage 49.72% 49.78% +0.06%
==========================================
Files 146 146
Lines 13455 13491 +36
==========================================
+ Hits 6691 6717 +26
- Misses 6184 6192 +8
- Partials 580 582 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds per-IP rate limiting to the v1 login endpoint (POST /api/v1/authorize) and hardens client-IP derivation by configuring Gin trusted proxies so X-Forwarded-For cannot be spoofed in direct-access deployments.
Changes:
- Implement per-IP token-bucket throttling for login attempts (burst + sustained refill) with 429 responses.
- Add
HTTP_TRUSTED_PROXIESconfiguration and wire Gin’sSetTrustedProxiesto controlClientIP()behavior. - Document the new 429 response in the Fuego/OpenAPI route registration.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/controller/openapi/devices.go | Documents a 429 response for /api/v1/authorize. |
| internal/controller/httpapi/v1/login.go | Adds per-IP rate limiter + cleanup loop and returns 429 on limit exceeded. |
| internal/controller/httpapi/v1/login_test.go | Adds tests for throttling and X-Forwarded-For spoofing behavior. |
| internal/app/app.go | Configures Gin trusted proxies based on config to prevent IP spoofing bypass. |
| config/config.go | Adds trusted_proxies (HTTP_TRUSTED_PROXIES) to HTTP config + defaults/comments. |
| .env.example | Documents HTTP_TRUSTED_PROXIES environment variable. |
Suppressed comments (1)
internal/controller/httpapi/v1/login_test.go:110
for i := range loginRateBurstdoes not compile becauseloginRateBurstis an int constant; use a conventional for-loop instead.
// Exhaust the burst using a different spoofed IP on every request. If the
// header were trusted, each would get its own bucket and never throttle.
for i := range loginRateBurst {
w := makeRequest(fmt.Sprintf("10.10.10.%d", i))
require.Equal(t, http.StatusUnauthorized, w.Code)
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| // Exhaust the burst allowance (loginRateBurst == 5). | ||
| for range loginRateBurst { | ||
| w := makeRequest() | ||
| require.Equal(t, http.StatusUnauthorized, w.Code) | ||
| } |
| func (lr *LoginRoute) Login(c *gin.Context) { | ||
| if !lr.getLimiter(c.ClientIP()).Allow() { | ||
| c.Header("Retry-After", "60") | ||
| c.JSON(http.StatusTooManyRequests, gin.H{ | ||
| errorKey: "too many requests", | ||
| messageKey: "Too many login attempts. Please try again later.", | ||
| }) | ||
|
|
||
| return | ||
| } |
| func NewLoginRoute(configData *config.Config) *LoginRoute { | ||
| lr := &LoginRoute{ | ||
| Config: configData, | ||
| Config: configData, | ||
| limiters: make(map[string]*ipEntry), | ||
| } | ||
|
|
||
| go lr.cleanupLoop() | ||
|
|
- Implemented IP token-bucket limiter (burst 5, refill 1/12s) to the Login handler. - IP token-bucket limiter (burst 5, refill 1/12s) to the Login handler. - Update the Fuego/OpenAPI declaration with the 429 response Signed-off-by: ShradhaGupta31 <shradha.gupta@intel.com>