-
Notifications
You must be signed in to change notification settings - Fork 614
[BUG][AUTH]: Multi-team users denied access to non-primary teams and cannot see public resources from other teams #2189
Description
Here’s the updated bug issue content with the added case included in the Steps to Reproduce:
🐞 Bug Summary
Users who belong to any team cannot see public tools owned by other teams in the list tools API, and filtering by a different team than the token’s team ID returns 403—even when the user is a member of that team.
🧩 Affected Component
Select the area of the project impacted:
-
mcpgateway- API -
mcpgateway- UI (admin panel) -
mcpgateway.wrapper- stdio wrapper - Federation or Transports
- CLI, Makefiles, or shell scripts
- Container setup (Docker/Podman/Compose)
- Other (explain below)
🔁 Steps to Reproduce
- Create Team A and Team B.
- Add the same user to both Team A and Team B.
- Issue a token for that user where the first team in the token is Team A.
- Call list tools API with
team_id=Team Band observe 403 due to team-id mismatch with token. - Create a public tool owned by Team B.
- Call list tools API without a team filter and observe Team B public tool is missing.
🤔 Expected Behavior
Public tools should be visible to all users regardless of team membership, and filtering by another team should allow access if the user is a member of that team—even if the token’s “first team” differs.
📓 Logs / Error Output
{
"message": "Access issue: This API token does not have the required permissions for this team."
}
🧠 Environment Info
You can retrieve most of this from the /version endpoint.
| Key | Value |
|---|---|
| Version or commit | 1.0.0-BETA-1 |
| Runtime | Python 3.13 |
| Platform / OS | Windows 10.0.26100 |
| Container | none |
🧩 Additional Context (optional)
in mcpgateway/auth.py: token parsing returns only the first team from the JWT payload
mcp-context-forge/mcpgateway/auth.py
Lines 157 to 159 in aba7f4c
| team_id = payload.get("teams")[0] if payload.get("teams") else None | |
| if isinstance(team_id, dict): | |
| team_id = team_id.get("id") |
mcpgateway/main.py the mismatch check at team_id vs token_team_id only considers that first team and ignores any other teams in the token: mcp-context-forge/mcpgateway/main.py
Lines 2637 to 2644 in aba7f4c
| token_team_id = getattr(request.state, "team_id", None) | |
| # Check for team ID mismatch | |
| if team_id is not None and token_team_id is not None and team_id != token_team_id: | |
| return JSONResponse( | |
| content={"message": "Access issue: This API token does not have the required permissions for this team."}, | |
| status_code=status.HTTP_403_FORBIDDEN, | |
| ) |