feat(middleware): add Redis-backed rate limiting with tier-based limits - #4423
Merged
Conversation
MohanLaksh
requested review from
brian-hussey,
crivetimihai,
kevalmahajan and
madhav165
as code owners
April 24, 2026 05:16
MohanLaksh
force-pushed
the
feature/api-rate-limiting-v2
branch
4 times, most recently
from
April 24, 2026 06:27
d5a81ec to
068cefd
Compare
Collaborator
Author
|
@brian-hussey , @ja8zyjits , Please help me review and merge this. |
MohanLaksh
force-pushed
the
feature/api-rate-limiting-v2
branch
from
May 8, 2026 07:11
98e66ed to
11069a9
Compare
- Add RateLimitMiddleware with Redis-backed sliding window algorithm - Implement tier-based rate limits (CRITICAL/HIGH/MEDIUM/LOW) per endpoint - Add lockout mechanism after excessive violations (5 violations = 15 min lockout) - Add multi-dimensional limiting (IP → User → Team) - Include security event logging for audit trail - Add 107 unit tests with 95% coverage Implements X-Force Red security findings for API rate limiting. Closes #4168 Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com>
Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com>
Rate limiting middleware was causing 38 test failures with 429 responses. Tests make rapid sequential requests that exceed rate limits. Follow existing pattern in conftest.py to disable optional middleware during tests (admin API, UI, llmchat are similarly disabled). Tests specifically for rate limiting (test_rate_limit_middleware.py) explicitly enable the middleware via settings override. Fixes test suite CI failures after rate limiting feature merge. Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com>
- Prevent infinite lockout loop by skipping violation increment during lockout - Add timestamp-based expiry to memory violation counts - Harden IP extraction against proxy spoofing via request.scope - Use atomic Lua script for Redis sliding window check+add - Reuse pre-check results to avoid double-counting on success - Update tests to properly exercise Redis Lua script path - Add regression tests for lockout expiry and no-increment behavior Signed-off-by: Jonathan Springer <jps@s390x.com>
Signed-off-by: Jonathan Springer <jps@s390x.com>
jonpspri
force-pushed
the
feature/api-rate-limiting-v2
branch
from
May 10, 2026 06:11
11069a9 to
11b89e9
Compare
Add tests for previously uncovered code paths: - Redis init success and exception handling - User object email extraction from request.state.user - Redis Lua script blocked (0) response - Lockout async executor exception fallback - Redis lockout count below threshold - Memory violation expiry cleanup and initialization - Violation increment async exception fallback - Redis violation increment exception fallback - Main app middleware registration when rate limiting enabled Signed-off-by: Jonathan Springer <jps@s390x.com>
msureshkumar88
pushed a commit
that referenced
this pull request
May 13, 2026
…ts (#4423) * feat(middleware): add Redis-backed rate limiting with tier-based limits - Add RateLimitMiddleware with Redis-backed sliding window algorithm - Implement tier-based rate limits (CRITICAL/HIGH/MEDIUM/LOW) per endpoint - Add lockout mechanism after excessive violations (5 violations = 15 min lockout) - Add multi-dimensional limiting (IP → User → Team) - Include security event logging for audit trail - Add 107 unit tests with 95% coverage Implements X-Force Red security findings for API rate limiting. Closes #4168 Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com> * chore: fix end of file newline Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com> * test: disable rate limiting in test suite Rate limiting middleware was causing 38 test failures with 429 responses. Tests make rapid sequential requests that exceed rate limits. Follow existing pattern in conftest.py to disable optional middleware during tests (admin API, UI, llmchat are similarly disabled). Tests specifically for rate limiting (test_rate_limit_middleware.py) explicitly enable the middleware via settings override. Fixes test suite CI failures after rate limiting feature merge. Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com> * fix(middleware): rate limiting council review fixes - Prevent infinite lockout loop by skipping violation increment during lockout - Add timestamp-based expiry to memory violation counts - Harden IP extraction against proxy spoofing via request.scope - Use atomic Lua script for Redis sliding window check+add - Reuse pre-check results to avoid double-counting on success - Update tests to properly exercise Redis Lua script path - Add regression tests for lockout expiry and no-increment behavior Signed-off-by: Jonathan Springer <jps@s390x.com> * chore: update .secrets.baseline timestamp Signed-off-by: Jonathan Springer <jps@s390x.com> * test(middleware): improve rate limiting diff coverage to 100% Add tests for previously uncovered code paths: - Redis init success and exception handling - User object email extraction from request.state.user - Redis Lua script blocked (0) response - Lockout async executor exception fallback - Redis lockout count below threshold - Memory violation expiry cleanup and initialization - Violation increment async exception fallback - Redis violation increment exception fallback - Main app middleware registration when rate limiting enabled Signed-off-by: Jonathan Springer <jps@s390x.com> --------- Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com> Signed-off-by: Jonathan Springer <jps@s390x.com> Co-authored-by: Jonathan Springer <jps@s390x.com>
brian-hussey
pushed a commit
that referenced
this pull request
May 19, 2026
…ts (#4423) * feat(middleware): add Redis-backed rate limiting with tier-based limits - Add RateLimitMiddleware with Redis-backed sliding window algorithm - Implement tier-based rate limits (CRITICAL/HIGH/MEDIUM/LOW) per endpoint - Add lockout mechanism after excessive violations (5 violations = 15 min lockout) - Add multi-dimensional limiting (IP → User → Team) - Include security event logging for audit trail - Add 107 unit tests with 95% coverage Implements X-Force Red security findings for API rate limiting. Closes #4168 Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com> * chore: fix end of file newline Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com> * test: disable rate limiting in test suite Rate limiting middleware was causing 38 test failures with 429 responses. Tests make rapid sequential requests that exceed rate limits. Follow existing pattern in conftest.py to disable optional middleware during tests (admin API, UI, llmchat are similarly disabled). Tests specifically for rate limiting (test_rate_limit_middleware.py) explicitly enable the middleware via settings override. Fixes test suite CI failures after rate limiting feature merge. Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com> * fix(middleware): rate limiting council review fixes - Prevent infinite lockout loop by skipping violation increment during lockout - Add timestamp-based expiry to memory violation counts - Harden IP extraction against proxy spoofing via request.scope - Use atomic Lua script for Redis sliding window check+add - Reuse pre-check results to avoid double-counting on success - Update tests to properly exercise Redis Lua script path - Add regression tests for lockout expiry and no-increment behavior Signed-off-by: Jonathan Springer <jps@s390x.com> * chore: update .secrets.baseline timestamp Signed-off-by: Jonathan Springer <jps@s390x.com> * test(middleware): improve rate limiting diff coverage to 100% Add tests for previously uncovered code paths: - Redis init success and exception handling - User object email extraction from request.state.user - Redis Lua script blocked (0) response - Lockout async executor exception fallback - Redis lockout count below threshold - Memory violation expiry cleanup and initialization - Violation increment async exception fallback - Redis violation increment exception fallback - Main app middleware registration when rate limiting enabled Signed-off-by: Jonathan Springer <jps@s390x.com> --------- Signed-off-by: Mohan Lakshmaiah <mohan.economist@gmail.com> Signed-off-by: Jonathan Springer <jps@s390x.com> Co-authored-by: Jonathan Springer <jps@s390x.com> Signed-off-by: Brian Hussey <brian.hussey@ie.ibm.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements comprehensive Redis-backed rate limiting with tier-based endpoint protection.
Problem Statement
API endpoints currently accept unlimited requests in rapid succession. This PR adds configurable rate limiting to prevent abuse and ensure system stability.
Solution Overview
This PR implements production-grade rate limiting with:
✅ Redis-backed sliding window algorithm (graceful in-memory fallback)
✅ Endpoint-specific tiers with appropriate protection levels
✅ Multi-dimensional limiting (per-IP, per-user, per-team)
✅ SecurityLogger integration (complete audit trail)
✅ Lockout mechanism (temporary lockout after repeated violations)
✅ RFC-compliant response headers (X-RateLimit-*, Retry-After)
Implementation Details
1. Endpoint Tiers (Criticality-Based Protection)
/auth/email/*,/auth/sso/*/tokens/*,/oauth/*,/rbac/*/mcp,/tools/*,/llmchat/*/health,/metrics,/docsDesign decision: No burst allowance for auth/admin endpoints to prevent rapid repeated attempts. Burst allowed for API endpoints to support legitimate client spikes.
2. Multi-Dimensional Rate Limiting
Checks limits across three dimensions independently:
Example:
3. Redis Sliding Window Algorithm
Uses sorted sets for precise sliding window rate limiting:
Fallback: Graceful degradation to in-memory dict if Redis unavailable (single-instance dev environments).
4. SecurityLogger Integration
All rate limit violations persist to
SecurityEventtable with full context:rate_limit_exceeded→brute_force_attempt(on lockout)Benefit: Complete audit trail for compliance, SIEM integration, pattern analysis.
5. Lockout Mechanism
After 5 rate limit violations in 5-minute window:
brute_force_attempt(HIGH severity)Design decision: Lockout instead of progressive delays to avoid blocking event loop (no
asyncio.sleep()in production middleware).6. Response Headers (RFC 6585)
All responses include rate limit headers:
On 429 (rate limit exceeded):
Benefit: Clients can implement proactive rate limiting, reducing 429 errors.
Technical Implementation
Architecture
Middleware Position: After
HttpAuthMiddleware(Starlette LIFO execution)request.state.user_emailandrequest.state.team_idAsync/Sync Bridge:
ThreadPoolExecutorfor sync Redis calls in async middlewarePattern Reuse: Uses existing
auth._get_sync_redis_client()(consistent with project patterns).Configuration (Environment Variables)
Files Changed
mcpgateway/config.py(+25 lines) - Configuration settingsmcpgateway/main.py(+12 lines) - Middleware registrationmcpgateway/middleware/rate_limit_middleware.py(+407 lines) - Implementationtests/unit/.../test_rate_limit_middleware.py(+1051 lines) - 100+ test casesTotal: +1495 lines, 0 breaking changes
Testing
Coverage
✅ 100+ unit tests covering:
Test Execution
Expected: All tests pass (100+ tests)
Operational Considerations
Performance Impact
Redis Path:
In-Memory Fallback:
Backward Compatibility
✅ No breaking changes
✅ Feature flag:
RATE_LIMITING_ENABLED=true(can disable if needed)✅ Graceful degradation: In-memory fallback if Redis unavailable
✅ Existing config preserved:
validation_max_requests_per_minuteretained for testsReferences
Checklist
Closes #4327