Skip to content

[BUG]: 12 admin partial/ids/search endpoints suppress other teams' public rows when filtering by team_id #6193

Description

@msureshkumar88

🐞 Bug Summary

12 admin /admin/*/partial, /admin/*/ids, and /admin/*/search endpoints in mcpgateway/admin.py build their queries by hand instead of going through BaseService/_apply_access_control(). Their team_id branch only adds globally-public rows owned by other teams when include_public=True — but nothing in the admin UI (admin.html, admin_ui/*.js) ever sets include_public=true. So filtering any resource table by team through the main admin UI (search, pagination, "select all", etc.) silently hides other teams' public rows, which contradicts the team_id semantics established by #4773/#6150/#6152 ("team_id narrows team-scoped rows, it does not suppress platform-public ones").

This is the inverse of the leak fixed in #6152 (under-inclusion instead of over-inclusion), and it's pre-existing — not introduced by #6152. Confirmed via review discussion on #6152: #6152 (comment)

Affected endpoints (mcpgateway/admin.py)

Endpoint Line
GET /admin/tools/partial 8822
GET /admin/tools/ids 9191
GET /admin/tools/search 9293
GET /admin/prompts/partial 9428
GET /admin/gateways/partial 9666
GET /admin/gateways/ids 9864
GET /admin/gateways/search 9929
GET /admin/resources/partial 10211
GET /admin/prompts/ids 10451
GET /admin/resources/ids 10549
GET /admin/resources/search 10647
GET /admin/prompts/search 10772

Each declares include_public: bool = False and, when team_id is set, only appends model_cls.visibility == "public" to the OR-conditions if include_public is true.

🧩 Affected Component

  • mcpgateway - API
  • mcpgateway - UI (admin panel)

🔁 Steps to Reproduce

  1. As a platform admin (or any user in ≥2 teams), create a public-visibility tool/resource/prompt/gateway owned by team A.
  2. In the Admin UI, select team B from the team filter on that resource's tab (drives ?team_id=B on the */partial endpoint).
  3. Team A's public item does not appear in the table, even though it should be visible platform-wide.

🤔 Expected Behavior

Filtering by team in the admin UI should follow the same team_id semantics as the service layer (fixed in #6152 for /admin/sections/* and the underlying services): team-scoped rows for the selected team, plus all globally-public rows regardless of owning team.

🧠 Environment Info

Key Value
Version or commit main@47419b485 (post-#6152)
Runtime N/A — logic bug, reproducible on any version
Platform / OS N/A
Container N/A

🧩 Additional Context

Likely fix: route these 12 endpoints through the same BaseService._team_scoped_conditions() helper introduced in #6152, or drop the include_public gate so team_id filtering always includes public rows from other teams, matching #4773's documented semantics. Out of scope for #6152 itself since these endpoints don't share code with BaseService._apply_access_control() — pulling them in would have expanded that PR's blast radius.

Related: #6152, #4773, #4732, #5496, #6150

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingtriageIssues / Features awaiting triageuiUser Interface

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions