fix(cmd-tlm-api): scope auth rate limit counters per client - #3733
fix(cmd-tlm-api): scope auth rate limit counters per client#3733jmthomas wants to merge 4 commits into
Conversation
The failed login counters were single global Redis keys, so bad passwords from any one client rate limited every other client, including requests carrying the correct password. Key the counters by client ip instead so a client can only rate limit itself. Also refresh the counter TTL on every bad attempt and clear the counter after a successful authentication. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3733 +/- ##
==========================================
+ Coverage 80.00% 80.02% +0.01%
==========================================
Files 885 885
Lines 65382 65404 +22
Branches 2543 2543
==========================================
+ Hits 52311 52341 +30
+ Misses 12411 12399 -12
- Partials 660 664 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR fixes an authentication rate-limiting flaw in openc3-cosmos-cmd-tlm-api where failed-login counters were global Redis keys, allowing one client’s bad attempts to rate-limit all clients. It scopes rate-limit counters per client IP, refreshes the TTL on each bad attempt (sliding window), and clears counters on successful authentication.
Changes:
- Scope bad-attempt counters by client identifier (derived from
request.remote_ip/remote_addr) instead of using global Redis keys. - Refresh the bad-attempt TTL on every failed attempt and clear the counter after successful auth / password change.
- Update Rails controller specs and Playwright notes, and document the proxy header safety expectations in Traefik config comments.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| playwright/tests/auth.p.spec.ts | Clarifies Playwright test limitations now that rate limiting is per-client-IP. |
| openc3-traefik/traefik.yaml | Adds documentation about forwarded header handling to keep client-IP scoping safe. |
| openc3-cosmos-cmd-tlm-api/spec/controllers/auth_controller_spec.rb | Adds controller-level specs covering per-client scoping, proxy behavior, and counter clearing. |
| openc3-cosmos-cmd-tlm-api/app/controllers/auth_controller.rb | Implements per-client-IP Redis keys, sliding-window TTL refresh, and counter clearing on success. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The failed login counters were single global Redis keys, so bad passwords from any one client rate limited every other client, including requests carrying the correct password. Key the counters by client ip instead so a client can only rate limit itself. Also refresh the counter TTL on every bad attempt, clear the counter after a successful authentication, and re-apply the window if a counter is ever found without an expiration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…3/cosmos into auth-rate-limit-per-client # Conflicts: # openc3-cosmos-cmd-tlm-api/app/controllers/auth_controller.rb # openc3-cosmos-cmd-tlm-api/spec/controllers/auth_controller_spec.rb
The X-Forwarded-For example set the header inline and only reset the memoized @remote_ip. Route it through set_client_ip so the rack env value is cleared too. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
|
related to #2921 |



The failed login counters were single global Redis keys, so bad passwords from any one client rate limited every other client, including requests carrying the correct password. Key the counters by client ip instead so a client can only rate limit itself.
Also refresh the counter TTL on every bad attempt and clear the counter after a successful authentication.
Note: This is Core only and does not affect Enterprise which authenticates through Keycloak
🤖 Generated with Claude Code