Skip to content

fix-2185: fix listing public server#2186

Merged
crivetimihai merged 4 commits intoIBM:mainfrom
KKNithin:fix-2185-unable-to-list-gateways
Jan 25, 2026
Merged

fix-2185: fix listing public server#2186
crivetimihai merged 4 commits intoIBM:mainfrom
KKNithin:fix-2185-unable-to-list-gateways

Conversation

@KKNithin
Copy link
Copy Markdown
Collaborator

@KKNithin KKNithin commented Jan 19, 2026

resolves issue #2185

closes #2185

@crivetimihai crivetimihai self-assigned this Jan 19, 2026
@crivetimihai
Copy link
Copy Markdown
Member

Review Feedback

Hi @KKNithin, thank you for investigating this issue and submitting a fix. I've done a deep dive into the RBAC and visibility system and found some concerns we need to address.

Consistency Issue

The proposed change makes gateway visibility behavior inconsistent with all other entity types:

Service When filtering by team_id
server_service Shows items from THAT team with visibility.in_(["team", "public"])
tool_service Shows items from THAT team with visibility.in_(["team", "public"])
resource_service Shows items from THAT team with visibility.in_(["team", "public"])
prompt_service Shows items from THAT team with visibility.in_(["team", "public"])
a2a_service Shows items from THAT team with visibility.in_(["team", "public"])
gateway_service (original) Shows items from THAT team with visibility.in_(["team", "public"])
gateway_service (this PR) Shows items from THAT team with visibility.in_(["team"]) + ALL public items from ANY team ❌

The original gateway_service was already consistent with all other services.

Root Cause Analysis

The reported bug ("Non-Admin user unable to list public gateways") likely occurs because:

  1. The user's JWT token contains a team_id
  2. When calling GET /gateways, the API auto-populates: team_id = team_id or token_team_id
  3. This triggers team-scoped filtering
  4. Public gateways from OTHER teams (or with team_id=NULL) don't appear

This is actually by design - when you filter by team, you see that team's items. The "All Teams" view (no team_id filter) shows all public items.

What Would Be Needed for a Complete Fix

If we decide to change the semantics so that public items are always visible regardless of team filter, we would need to:

  1. Make a deliberate design decision and document it
  2. Update ALL services consistently (servers, tools, resources, prompts, a2a, gateways)
  3. Update the admin UI (admin.py) to match
  4. Add tests covering the new behavior

Alternative Approaches to Consider

  1. Document current behavior: Team-scoped tokens see team-scoped views. Users should use "All Teams" view to see all public items.

  2. Don't auto-populate team_id for list operations: Let users explicitly choose to filter by team rather than inferring from token.

  3. Use public-only tokens: Tokens with empty teams array ([]) are designed for accessing public resources without team filtering.

What Works

The db.py changes adding gateway permission constants (GATEWAYS_CREATE, GATEWAYS_READ, GATEWAYS_UPDATE, GATEWAYS_DELETE) are useful additions that we can include in the final fix.


Let's discuss the right approach here before proceeding. We can use this same PR/issue to implement the complete fix once we've agreed on the direction.

@crivetimihai crivetimihai added this to the Release 1.0.0-RC1 milestone Jan 21, 2026
Add GATEWAYS_CREATE, GATEWAYS_READ, GATEWAYS_UPDATE, and GATEWAYS_DELETE
permission constants to the Permissions class for consistency with other
resource types (tools, resources, prompts, servers).

Note: The original PR IBM#2186 attempted to fix issue IBM#2185 by modifying
the visibility query logic, but that change was incorrect. The team
filter should only show resources BELONGING to the filtered team,
not all public resources globally. See todo/rbac.md for documentation.

Issue IBM#2185 needs further investigation - the reported bug may have
a different root cause.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Add gateway routes to token scoping middleware for consistent permission
enforcement:
- Add gateway pattern to _RESOURCE_PATTERNS for ID extraction
- Add gateway CRUD patterns to _PERMISSION_PATTERNS:
  - POST /gateways (exact) -> gateways.create
  - POST /gateways/{id}/... (sub-resources) -> gateways.update
  - PUT/DELETE -> gateways.update/delete
- Add gateway handling in _check_resource_team_ownership:
  - Public: accessible by all
  - Team: accessible by team members
  - Private: owner-only access (per RBAC doc)

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
…urces

Per RBAC doc, private visibility means "owner only" - not "team members".
Fixed private visibility checks for all resource types to validate
owner_email == requester instead of team membership:
- Servers
- Tools
- Resources
- Prompts
- Gateways (already correct from previous commit)

This aligns token scoping middleware with the documented RBAC model.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Add unit tests covering:
- Gateway permission patterns (POST create vs POST update sub-resources)
- Private visibility enforces owner-only access
- Team visibility allows team members only
- Public visibility allows all authenticated users

These tests validate the RBAC fixes in token scoping middleware.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
@crivetimihai
Copy link
Copy Markdown
Member

PR Rework Summary

This PR has been significantly reworked from the original submission. Here's what changed:

Design Decision: Team Filter Semantics (Option A)

After deep analysis of the RBAC model, we chose Option A (pure filter semantics):

  • When filtering by team_id, show only resources belonging to that team
  • Users who want to see public resources from other teams should use the "All Teams" view
  • This preserves the admin experience: selecting "Team X" shows "Team X's stuff", not "Team X's stuff + all public resources globally"

The original "fix" conflated visibility (access control) with team_id (ownership), which broke this behavior.

Changes in This PR

1. Gateway Permission Constants (mcpgateway/db.py)

GATEWAYS_CREATE = "gateways.create"
GATEWAYS_READ = "gateways.read"
GATEWAYS_UPDATE = "gateways.update"
GATEWAYS_DELETE = "gateways.delete"

2. Gateway Token Scoping (mcpgateway/middleware/token_scoping.py)

  • Added gateway pattern to _RESOURCE_PATTERNS for ID extraction
  • Added gateway CRUD patterns to _PERMISSION_PATTERNS:
    • POST /gateways (exact) → gateways.create
    • POST /gateways/{id}/... (sub-resources like state, toggle, refresh) → gateways.update
    • PUT/DELETEgateways.update/delete
  • Added gateway visibility handling in _check_resource_team_ownership

3. RBAC Fix: Private Visibility = Owner-Only

Fixed a pre-existing bug where private visibility allowed team member access instead of owner-only:

  • Before: Private resources accessible by anyone in the team
  • After: Private resources accessible only by owner_email (per RBAC doc)

Applied consistently to: Servers, Tools, Resources, Prompts, Gateways

4. Unit Tests

Added tests for:

  • Gateway permission patterns (create vs update POST distinction)
  • Private visibility enforces owner-only access
  • Team visibility allows team members only
  • Public visibility allows all authenticated users

Commits

874004e3f test: Add tests for gateway permissions and visibility RBAC
3b0232b44 fix: Enforce owner-only access for private visibility across all resources
30649c17e feat: Add gateway permission patterns to token scoping middleware
32054def0 feat: Add Gateway permission constants

Related

@crivetimihai crivetimihai force-pushed the fix-2185-unable-to-list-gateways branch from 2dc98ee to 874004e Compare January 25, 2026 12:50
Copy link
Copy Markdown
Member

@crivetimihai crivetimihai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please retest, and open a new issue if necessary.

@crivetimihai crivetimihai merged commit 5f3087f into IBM:main Jan 25, 2026
53 checks passed
kcostell06 pushed a commit to kcostell06/mcp-context-forge that referenced this pull request Feb 24, 2026
* feat: Add Gateway permission constants

Add GATEWAYS_CREATE, GATEWAYS_READ, GATEWAYS_UPDATE, and GATEWAYS_DELETE
permission constants to the Permissions class for consistency with other
resource types (tools, resources, prompts, servers).

Note: The original PR IBM#2186 attempted to fix issue IBM#2185 by modifying
the visibility query logic, but that change was incorrect. The team
filter should only show resources BELONGING to the filtered team,
not all public resources globally. See todo/rbac.md for documentation.

Issue IBM#2185 needs further investigation - the reported bug may have
a different root cause.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* feat: Add gateway permission patterns to token scoping middleware

Add gateway routes to token scoping middleware for consistent permission
enforcement:
- Add gateway pattern to _RESOURCE_PATTERNS for ID extraction
- Add gateway CRUD patterns to _PERMISSION_PATTERNS:
  - POST /gateways (exact) -> gateways.create
  - POST /gateways/{id}/... (sub-resources) -> gateways.update
  - PUT/DELETE -> gateways.update/delete
- Add gateway handling in _check_resource_team_ownership:
  - Public: accessible by all
  - Team: accessible by team members
  - Private: owner-only access (per RBAC doc)

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* fix: Enforce owner-only access for private visibility across all resources

Per RBAC doc, private visibility means "owner only" - not "team members".
Fixed private visibility checks for all resource types to validate
owner_email == requester instead of team membership:
- Servers
- Tools
- Resources
- Prompts
- Gateways (already correct from previous commit)

This aligns token scoping middleware with the documented RBAC model.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* test: Add tests for gateway permissions and visibility RBAC

Add unit tests covering:
- Gateway permission patterns (POST create vs POST update sub-resources)
- Private visibility enforces owner-only access
- Team visibility allows team members only
- Public visibility allows all authenticated users

These tests validate the RBAC fixes in token scoping middleware.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

---------

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Co-authored-by: Mihai Criveti <crivetimihai@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG][AUTH]: Non-admin user unable to list public gateways

2 participants