fix: allow team-scoped RBAC roles for mutate operations without explicit team_id#2894
Merged
crivetimihai merged 3 commits intomainfrom Feb 13, 2026
Merged
fix: allow team-scoped RBAC roles for mutate operations without explicit team_id#2894crivetimihai merged 3 commits intomainfrom
crivetimihai merged 3 commits intomainfrom
Conversation
…cit team_id
The RBAC `require_permission` decorator's fail-closed mutate logic excluded
team-scoped roles when team_id could not be derived from the request. This
caused 403 errors for team developers creating gateways/servers and platform
admins deleting resources.
The fix uses `check_any_team=True` for both read and mutate operations when
no team_id is available, separating authorization ("does this user have the
permission?") from resource scoping ("which team owns this?"). Team assignment
is still enforced downstream by endpoint logic (verify_team_for_user, token
membership checks).
Also adds team_id injection to delete forms in admin.js as defense-in-depth.
Closes #2883
Closes #2891
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
If the platform_admin role creation fails but the role already exists in the DB (e.g. from a previous boot), the assignment was silently skipped because the role wasn't in the created_roles list. Now falls back to a DB lookup. Also improves error messages to mention the downstream impact (allow_admin_bypass=False routes returning 403). Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Fix accept_invitation returning bool instead of EmailTeamMember, which caused the router to always return 404 despite memberships being created in the DB. Add comprehensive E2E Playwright tests for RBAC permission enforcement on admin UI operations (regression tests for #2883 and #2891). Closes #2883 Closes #2891 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Member
Author
Regression Testing UpdateAdded comprehensive E2E Playwright tests for RBAC permission enforcement in Bug Fix IncludedInvitation acceptance 404 — Tests Cover
Results10 passed, 1 skipped (admin delete gateway — requires real MCP server for gateway creation via API). |
This was referenced Feb 13, 2026
ja8zyjits
pushed a commit
that referenced
this pull request
Feb 13, 2026
…cit team_id (#2894) * fix: allow team-scoped RBAC roles for mutate operations without explicit team_id The RBAC `require_permission` decorator's fail-closed mutate logic excluded team-scoped roles when team_id could not be derived from the request. This caused 403 errors for team developers creating gateways/servers and platform admins deleting resources. The fix uses `check_any_team=True` for both read and mutate operations when no team_id is available, separating authorization ("does this user have the permission?") from resource scoping ("which team owns this?"). Team assignment is still enforced downstream by endpoint logic (verify_team_for_user, token membership checks). Also adds team_id injection to delete forms in admin.js as defense-in-depth. Closes #2883 Closes #2891 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix: harden bootstrap platform_admin role assignment with DB fallback If the platform_admin role creation fails but the role already exists in the DB (e.g. from a previous boot), the assignment was silently skipped because the role wasn't in the created_roles list. Now falls back to a DB lookup. Also improves error messages to mention the downstream impact (allow_admin_bypass=False routes returning 403). Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix: repair invitation acceptance and add E2E RBAC Playwright tests Fix accept_invitation returning bool instead of EmailTeamMember, which caused the router to always return 404 despite memberships being created in the DB. Add comprehensive E2E Playwright tests for RBAC permission enforcement on admin UI operations (regression tests for #2883 and #2891). Closes #2883 Closes #2891 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> --------- Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
vishu-bh
pushed a commit
that referenced
this pull request
Feb 18, 2026
…cit team_id (#2894) * fix: allow team-scoped RBAC roles for mutate operations without explicit team_id The RBAC `require_permission` decorator's fail-closed mutate logic excluded team-scoped roles when team_id could not be derived from the request. This caused 403 errors for team developers creating gateways/servers and platform admins deleting resources. The fix uses `check_any_team=True` for both read and mutate operations when no team_id is available, separating authorization ("does this user have the permission?") from resource scoping ("which team owns this?"). Team assignment is still enforced downstream by endpoint logic (verify_team_for_user, token membership checks). Also adds team_id injection to delete forms in admin.js as defense-in-depth. Closes #2883 Closes #2891 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix: harden bootstrap platform_admin role assignment with DB fallback If the platform_admin role creation fails but the role already exists in the DB (e.g. from a previous boot), the assignment was silently skipped because the role wasn't in the created_roles list. Now falls back to a DB lookup. Also improves error messages to mention the downstream impact (allow_admin_bypass=False routes returning 403). Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix: repair invitation acceptance and add E2E RBAC Playwright tests Fix accept_invitation returning bool instead of EmailTeamMember, which caused the router to always return 404 despite memberships being created in the DB. Add comprehensive E2E Playwright tests for RBAC permission enforcement on admin UI operations (regression tests for #2883 and #2891). Closes #2883 Closes #2891 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> --------- Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
kcostell06
pushed a commit
to kcostell06/mcp-context-forge
that referenced
this pull request
Feb 24, 2026
…cit team_id (IBM#2894) * fix: allow team-scoped RBAC roles for mutate operations without explicit team_id The RBAC `require_permission` decorator's fail-closed mutate logic excluded team-scoped roles when team_id could not be derived from the request. This caused 403 errors for team developers creating gateways/servers and platform admins deleting resources. The fix uses `check_any_team=True` for both read and mutate operations when no team_id is available, separating authorization ("does this user have the permission?") from resource scoping ("which team owns this?"). Team assignment is still enforced downstream by endpoint logic (verify_team_for_user, token membership checks). Also adds team_id injection to delete forms in admin.js as defense-in-depth. Closes IBM#2883 Closes IBM#2891 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix: harden bootstrap platform_admin role assignment with DB fallback If the platform_admin role creation fails but the role already exists in the DB (e.g. from a previous boot), the assignment was silently skipped because the role wasn't in the created_roles list. Now falls back to a DB lookup. Also improves error messages to mention the downstream impact (allow_admin_bypass=False routes returning 403). Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix: repair invitation acceptance and add E2E RBAC Playwright tests Fix accept_invitation returning bool instead of EmailTeamMember, which caused the router to always return 404 despite memberships being created in the DB. Add comprehensive E2E Playwright tests for RBAC permission enforcement on admin UI operations (regression tests for IBM#2883 and IBM#2891). Closes IBM#2883 Closes IBM#2891 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> --------- Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
require_permissiondecorator excluded team-scoped roles (e.g.developer,team_admin,platform_admin) whenteam_idcould not be derived from the request, causing 403 on create/delete operationscheck_any_team=Truefor both read and mutate operations, separating authorization from resource scopingrequire_any_permissionfor consistencyteam_idinjection tohandleDeleteSubmit()in admin.js as defense-in-depthRoot cause
rbac.py:552-558had mutate-specific fail-closed logic that proceeded withteam_id=Nonewhen team context couldn't be derived. This caused_get_user_roles()to exclude all team-scoped roles with a specificscope_id, resulting in 403 for any user whose permissions came from team-scoped role assignments.What was affected
team_idin body ([BUG][RBAC]: Getting 403 when adding MCP server or virtual server from team #2883)team_id=NULLor delete form lackedteam_id([BUG][RBAC]: Platform admin blocked by RBAC on gateway delete (allow_admin_bypass=False) #2891)Why this is safe
The RBAC check only answers "does this user have this permission in any team?" — resource team assignment is enforced downstream by
verify_team_for_user(), token membership checks, and inline team validation in endpoint logic. Read operations already usedcheck_any_team=Truewithout security issues.Verified
POST /gateways(no team_id)POST /servers(no team_id)DELETE /gateways/{id}POST /gatewaysPOST /gatewaysCloses #2883
Closes #2891