Skip to content

fix(auth): set request.state.token_teams for proxy authentication flow to resolve admin status#4591

Open
bogdanmariusc10 wants to merge 1 commit intomainfrom
4587-bug-proxy-authenticated-admin-user-adminadmincom-cannot-access-private-tools-despite-is_admintrue-and-db-resolution
Open

fix(auth): set request.state.token_teams for proxy authentication flow to resolve admin status#4591
bogdanmariusc10 wants to merge 1 commit intomainfrom
4587-bug-proxy-authenticated-admin-user-adminadmincom-cannot-access-private-tools-despite-is_admintrue-and-db-resolution

Conversation

@bogdanmariusc10
Copy link
Copy Markdown
Collaborator

🔗 Related Issue

Closes #4587


📝 Summary

Fixes proxy-authenticated admin users being unable to access private/team-scoped tools despite having is_admin=true in the database.

Root Cause: The _authenticate_proxy_user() function correctly resolved admin status and teams from the database but failed to set request.state.token_teams. This caused downstream code in get_token_teams_from_request() to fall back to normalize_token_teams() instead of using the pre-resolved value, breaking admin bypass for proxy-authenticated requests.

Solution: Added request.state.token_teams assignment in both proxy authentication paths (DB user lookup and platform admin bootstrap), matching the pattern used by get_current_user() for JWT session tokens.

Impact: Admin users authenticated via proxy headers (when TRUST_PROXY_AUTH=true) now correctly receive admin bypass (token_teams=None) and can access all tools (public + team + private).


🏷️ Type of Change

  • Bug fix
  • Feature / Enhancement
  • Documentation
  • Refactor
  • Chore (deps, CI, tooling)
  • Other (describe below)

🧪 Verification

Check Command Status
Lint suite make lint ✅ Pass
Unit tests make test ✅ Pass
Coverage ≥ 80% make coverage ✅ Pass

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • Tests added/updated for changes
  • Documentation updated (if applicable)
  • No secrets or credentials committed

📓 Notes

Changes Made

File: mcpgateway/utils/verify_credentials.py

  1. Line 473 (DB user path): Added request.state.token_teams = token_teams after resolving teams via _resolve_teams_from_db()
  2. Line 489 (bootstrap admin path): Added request.state.token_teams = None for platform admin bootstrap when REQUIRE_USER_IN_DB=false

Why This Works

The fix ensures proxy-authenticated requests follow the same state-setting pattern as JWT session tokens:

  • JWT path (auth.py:1403): get_current_user() sets request.state.token_teams after calling resolve_session_teams()
  • Proxy path (now fixed): _authenticate_proxy_user() sets request.state.token_teams after calling _resolve_teams_from_db()

This makes get_token_teams_from_request() find the pre-resolved value immediately instead of falling back to normalize_token_teams(), ensuring consistent admin bypass behavior.

…esolve admin status

Signed-off-by: Bogdan-Marius-Catanus <bogdan-marius.catanus@ibm.com>
@bogdanmariusc10 bogdanmariusc10 added bug Something isn't working rbac Role-based Access Control labels May 5, 2026
@bogdanmariusc10 bogdanmariusc10 added SHOULD P2: Important but not vital; high-value items that are not crucial for the immediate release api REST API Related item labels May 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api REST API Related item bug Something isn't working rbac Role-based Access Control SHOULD P2: Important but not vital; high-value items that are not crucial for the immediate release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Proxy-authenticated admin user (admin@admin.com ) cannot access private tools despite is_admin=true and DB resolution

1 participant