Fix/issue 2340 - eliminate RBAC middleware session accumulation under high load#2549
Fix/issue 2340 - eliminate RBAC middleware session accumulation under high load#2549crivetimihai merged 1 commit intomainfrom
Conversation
17dc9c3 to
0ae8b60
Compare
0ae8b60 to
b7516dd
Compare
|
Excellent work on this PR, @Lang-Akshay! The analysis is thorough - the load test data clearly demonstrates the session accumulation problem, and the fix using The code looks good:
One minor observation: The new To merge: The DCO check is failing. Please sign off your commits: git rebase HEAD~N --signoff # where N is number of commits
# or for a single commit:
git commit --amend --signoff
git push --force-with-leaseOnce that's done, this should be ready to merge. Great contribution! |
Replace long-lived database sessions in RBAC middleware with fresh_db_session() context manager to prevent session accumulation under high concurrent load. Changes: - Remove db parameter from get_current_user_with_permissions() - Use fresh_db_session() context manager for short-lived DB access - Keep "db": None in user context for backward compatibility - Add deprecation warnings to get_db() and get_permission_service() - Update all permission decorators to use fresh_db_session() fallback - Update PermissionChecker to use fresh_db_session() pattern - Simplify db.py by reusing get_db() generator for fresh_db_session Security fixes: - Use named kwargs (user, _user, current_user, current_user_ctx) for user context extraction instead of scanning all dicts for "email" to prevent request body injection attacks Performance fixes: - PermissionChecker.has_any_permission now uses single session for all permission checks instead of opening N sessions This prevents idle-in-transaction bottlenecks where sessions were held for entire request duration instead of milliseconds. Closes #2340 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
1455fa8 to
317b6de
Compare
Review ChangesRebased onto main and applied the following fixes during code review: Security Fix
Backward Compatibility Fix
Performance Fix
Test Updates
Pre-existing Issue IdentifiedDuring review, identified that 22 endpoints across Tracked separately in: #2641 |
…BM#2549) Replace long-lived database sessions in RBAC middleware with fresh_db_session() context manager to prevent session accumulation under high concurrent load. Changes: - Remove db parameter from get_current_user_with_permissions() - Use fresh_db_session() context manager for short-lived DB access - Keep "db": None in user context for backward compatibility - Add deprecation warnings to get_db() and get_permission_service() - Update all permission decorators to use fresh_db_session() fallback - Update PermissionChecker to use fresh_db_session() pattern - Simplify db.py by reusing get_db() generator for fresh_db_session Security fixes: - Use named kwargs (user, _user, current_user, current_user_ctx) for user context extraction instead of scanning all dicts for "email" to prevent request body injection attacks Performance fixes: - PermissionChecker.has_any_permission now uses single session for all permission checks instead of opening N sessions This prevents idle-in-transaction bottlenecks where sessions were held for entire request duration instead of milliseconds. Closes IBM#2340 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> Signed-off-by: hughhennnelly <hughhennelly06@gmail.com>
…BM#2549) Replace long-lived database sessions in RBAC middleware with fresh_db_session() context manager to prevent session accumulation under high concurrent load. Changes: - Remove db parameter from get_current_user_with_permissions() - Use fresh_db_session() context manager for short-lived DB access - Keep "db": None in user context for backward compatibility - Add deprecation warnings to get_db() and get_permission_service() - Update all permission decorators to use fresh_db_session() fallback - Update PermissionChecker to use fresh_db_session() pattern - Simplify db.py by reusing get_db() generator for fresh_db_session Security fixes: - Use named kwargs (user, _user, current_user, current_user_ctx) for user context extraction instead of scanning all dicts for "email" to prevent request body injection attacks Performance fixes: - PermissionChecker.has_any_permission now uses single session for all permission checks instead of opening N sessions This prevents idle-in-transaction bottlenecks where sessions were held for entire request duration instead of milliseconds. Closes IBM#2340 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Problem
The RBAC middleware held database sessions open for the entire request duration via
Depends(get_db), causing critical performance degradation under high load:Load test results (4000 concurrent users, 10 workers):
Root cause:
get_current_user_with_permissions()opened a session at request start and kept it open until response completion, even though database access was only needed briefly for user lookup. Under high load, sessions accumulated faster than they could be released.Impact:
All 346 authenticated endpoints were affected.
Solution
Remove long-lived database sessions from RBAC middleware and use
fresh_db_session()context manager for short-lived, on-demand database access:Before:
After:
Changes Made
mcpgateway/middleware/rbac.py
db: Session = Depends(get_db)parameter fromget_current_user_with_permissions()fresh_db_session()context manager for EmailUser lookup"db": Nonefrom all user context return dictionariesdb.commit()anddb.close()calls (context manager handles this)require_permission,require_admin_permission,require_any_permission) to usefresh_db_session()when no endpoint session existsPermissionCheckerclass to usefresh_db_session()patternget_db()andget_permission_service()functionsTest Files Updated
tests/unit/mcpgateway/middleware/test_rbac.pytests/unit/mcpgateway/middleware/test_auth_method_propagation.pytests/unit/mcpgateway/utils/test_proxy_auth.py(8 test methods)tests/unit/mcpgateway/test_main.pytests/unit/mcpgateway/test_main_extended.pytests/unit/mcpgateway/test_admin_catalog_htmx.pyBenefits
fresh_db_session()automaticallyExpected Impact
After this fix, under 4000 concurrent users:
Related Issues
Testing
Run the test suite to verify all RBAC tests pass with new session management:
make test