Skip to content

fix: exclude personal team roles from check_any_team RBAC aggregation#2900

Merged
crivetimihai merged 1 commit intomainfrom
rbac-exclude-personal-teams
Feb 13, 2026
Merged

fix: exclude personal team roles from check_any_team RBAC aggregation#2900
crivetimihai merged 1 commit intomainfrom
rbac-exclude-personal-teams

Conversation

@crivetimihai
Copy link
Copy Markdown
Member

Summary

  • Every user gets an auto-created personal team with team_admin role, which includes full mutate permissions (servers.create, tools.create, etc.)
  • When check_any_team=True (session tokens without explicit team_id), _get_user_roles() aggregated ALL team-scoped roles including personal team roles
  • This made RBAC ineffective: viewers, outsiders, and all authenticated users could create/update/delete resources via the REST API

Fix: Filter out roles scoped to personal teams (EmailTeam.is_personal=True) from the include_all_teams query in _get_user_roles(). Direct team_id queries are unaffected — users retain full team_admin on their personal team when operating within it explicitly.

Test plan

  • 61 unit tests pass (3 new tests for personal team exclusion)
  • 103 RBAC middleware tests pass
  • 11,079 total unit tests pass (0 regressions)
  • 55 REST API RBAC tests across 5 roles (admin, developer, team_admin, viewer, outsider) × 9 operation groups — all pass
  • 10/11 Playwright RBAC E2E tests pass (1 skipped)
  • 196/200 full Playwright suite pass (4 pre-existing UI failures unrelated to RBAC)

Every user gets a personal team with team_admin role auto-assigned.
When check_any_team=True aggregated ALL team-scoped roles, it picked
up team_admin from personal teams, granting every authenticated user
full mutate permissions (servers.create, tools.create, etc.) and
making RBAC ineffective for create/update/delete operations.

Filter out personal team roles (EmailTeam.is_personal=True) from the
include_all_teams query in _get_user_roles(). Direct team_id queries
are unaffected, so users retain full team_admin on their personal team
when operating within it explicitly.

Closes #2883

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
@crivetimihai crivetimihai self-assigned this Feb 13, 2026
@crivetimihai crivetimihai added the rbac Role-based Access Control label Feb 13, 2026
@crivetimihai crivetimihai added this to the Release 1.0.0-RC1 milestone Feb 13, 2026
@crivetimihai crivetimihai merged commit 4f14285 into main Feb 13, 2026
52 checks passed
@crivetimihai crivetimihai deleted the rbac-exclude-personal-teams branch February 13, 2026 08:28
crivetimihai added a commit that referenced this pull request Feb 13, 2026
Closes #2387

Add systematic RBAC test coverage across 7 new test files:
- Permission matrix: 235 parametrized tests for all 5 roles × permissions
- Token scoping: 20 tests for normalize_token_teams() truth table
- Admin bypass: 11 tests for allow_admin_bypass=True/False enforcement
- Fail-closed: 10 tests for error/expired/deactivated role denial
- Cross-team isolation: 18 tests including #2900 personal team regression
- Endpoint coverage: 69 tests verifying decorator usage across all routers
- Management endpoints: 10 HTTP-level integration tests for RBAC admin

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
crivetimihai added a commit that referenced this pull request Feb 13, 2026
* test: add comprehensive RBAC regression test suite (373 tests)

Closes #2387

Add systematic RBAC test coverage across 7 new test files:
- Permission matrix: 235 parametrized tests for all 5 roles × permissions
- Token scoping: 20 tests for normalize_token_teams() truth table
- Admin bypass: 11 tests for allow_admin_bypass=True/False enforcement
- Fail-closed: 10 tests for error/expired/deactivated role denial
- Cross-team isolation: 18 tests including #2900 personal team regression
- Endpoint coverage: 69 tests verifying decorator usage across all routers
- Management endpoints: 10 HTTP-level integration tests for RBAC admin

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

* test: add Playwright E2E tests for RBAC on tools, resources, prompts, and teams

Extends test_rbac_permissions.py with 15 new E2E tests covering:
- Tool CRUD: developer create (team + all-teams view), viewer denied
- Resource CRUD: developer create, viewer denied
- Prompt CRUD: developer create, viewer denied
- Team management: viewer denied manage members, team_admin granted
- REST API: developer/viewer create tool/resource/prompt via API

Closes #2387

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

* fix: resolve Playwright RBAC test failures for prompts, teams, and API

- Prompt form: skip template fill (textarea has default content)
- Team management: test POST add-member (viewer denied) + verify
  team_admin passes RBAC (ownership check is business logic, not RBAC)
- REST API viewer deny: assert not in (200, 201) since FastAPI may
  return 422 (schema validation) before RBAC check runs

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

* fix: use Apache-2.0 license identifier consistently across all test files

Replace SPDX-License-Identifier: MIT with Apache-2.0 to match the
rest of the project.

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

---------

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
suciu-daniel pushed a commit that referenced this pull request Feb 16, 2026
* test: add comprehensive RBAC regression test suite (373 tests)

Closes #2387

Add systematic RBAC test coverage across 7 new test files:
- Permission matrix: 235 parametrized tests for all 5 roles × permissions
- Token scoping: 20 tests for normalize_token_teams() truth table
- Admin bypass: 11 tests for allow_admin_bypass=True/False enforcement
- Fail-closed: 10 tests for error/expired/deactivated role denial
- Cross-team isolation: 18 tests including #2900 personal team regression
- Endpoint coverage: 69 tests verifying decorator usage across all routers
- Management endpoints: 10 HTTP-level integration tests for RBAC admin

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

* test: add Playwright E2E tests for RBAC on tools, resources, prompts, and teams

Extends test_rbac_permissions.py with 15 new E2E tests covering:
- Tool CRUD: developer create (team + all-teams view), viewer denied
- Resource CRUD: developer create, viewer denied
- Prompt CRUD: developer create, viewer denied
- Team management: viewer denied manage members, team_admin granted
- REST API: developer/viewer create tool/resource/prompt via API

Closes #2387

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

* fix: resolve Playwright RBAC test failures for prompts, teams, and API

- Prompt form: skip template fill (textarea has default content)
- Team management: test POST add-member (viewer denied) + verify
  team_admin passes RBAC (ownership check is business logic, not RBAC)
- REST API viewer deny: assert not in (200, 201) since FastAPI may
  return 422 (schema validation) before RBAC check runs

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

* fix: use Apache-2.0 license identifier consistently across all test files

Replace SPDX-License-Identifier: MIT with Apache-2.0 to match the
rest of the project.

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
…#2900)

Every user gets a personal team with team_admin role auto-assigned.
When check_any_team=True aggregated ALL team-scoped roles, it picked
up team_admin from personal teams, granting every authenticated user
full mutate permissions (servers.create, tools.create, etc.) and
making RBAC ineffective for create/update/delete operations.

Filter out personal team roles (EmailTeam.is_personal=True) from the
include_all_teams query in _get_user_roles(). Direct team_id queries
are unaffected, so users retain full team_admin on their personal team
when operating within it explicitly.

Closes #2883

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
vishu-bh pushed a commit that referenced this pull request Feb 18, 2026
* test: add comprehensive RBAC regression test suite (373 tests)

Closes #2387

Add systematic RBAC test coverage across 7 new test files:
- Permission matrix: 235 parametrized tests for all 5 roles × permissions
- Token scoping: 20 tests for normalize_token_teams() truth table
- Admin bypass: 11 tests for allow_admin_bypass=True/False enforcement
- Fail-closed: 10 tests for error/expired/deactivated role denial
- Cross-team isolation: 18 tests including #2900 personal team regression
- Endpoint coverage: 69 tests verifying decorator usage across all routers
- Management endpoints: 10 HTTP-level integration tests for RBAC admin

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

* test: add Playwright E2E tests for RBAC on tools, resources, prompts, and teams

Extends test_rbac_permissions.py with 15 new E2E tests covering:
- Tool CRUD: developer create (team + all-teams view), viewer denied
- Resource CRUD: developer create, viewer denied
- Prompt CRUD: developer create, viewer denied
- Team management: viewer denied manage members, team_admin granted
- REST API: developer/viewer create tool/resource/prompt via API

Closes #2387

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

* fix: resolve Playwright RBAC test failures for prompts, teams, and API

- Prompt form: skip template fill (textarea has default content)
- Team management: test POST add-member (viewer denied) + verify
  team_admin passes RBAC (ownership check is business logic, not RBAC)
- REST API viewer deny: assert not in (200, 201) since FastAPI may
  return 422 (schema validation) before RBAC check runs

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

* fix: use Apache-2.0 license identifier consistently across all test files

Replace SPDX-License-Identifier: MIT with Apache-2.0 to match the
rest of the project.

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
…IBM#2900)

Every user gets a personal team with team_admin role auto-assigned.
When check_any_team=True aggregated ALL team-scoped roles, it picked
up team_admin from personal teams, granting every authenticated user
full mutate permissions (servers.create, tools.create, etc.) and
making RBAC ineffective for create/update/delete operations.

Filter out personal team roles (EmailTeam.is_personal=True) from the
include_all_teams query in _get_user_roles(). Direct team_id queries
are unaffected, so users retain full team_admin on their personal team
when operating within it explicitly.

Closes IBM#2883

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
kcostell06 pushed a commit to kcostell06/mcp-context-forge that referenced this pull request Feb 24, 2026
)

* test: add comprehensive RBAC regression test suite (373 tests)

Closes IBM#2387

Add systematic RBAC test coverage across 7 new test files:
- Permission matrix: 235 parametrized tests for all 5 roles × permissions
- Token scoping: 20 tests for normalize_token_teams() truth table
- Admin bypass: 11 tests for allow_admin_bypass=True/False enforcement
- Fail-closed: 10 tests for error/expired/deactivated role denial
- Cross-team isolation: 18 tests including IBM#2900 personal team regression
- Endpoint coverage: 69 tests verifying decorator usage across all routers
- Management endpoints: 10 HTTP-level integration tests for RBAC admin

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

* test: add Playwright E2E tests for RBAC on tools, resources, prompts, and teams

Extends test_rbac_permissions.py with 15 new E2E tests covering:
- Tool CRUD: developer create (team + all-teams view), viewer denied
- Resource CRUD: developer create, viewer denied
- Prompt CRUD: developer create, viewer denied
- Team management: viewer denied manage members, team_admin granted
- REST API: developer/viewer create tool/resource/prompt via API

Closes IBM#2387

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

* fix: resolve Playwright RBAC test failures for prompts, teams, and API

- Prompt form: skip template fill (textarea has default content)
- Team management: test POST add-member (viewer denied) + verify
  team_admin passes RBAC (ownership check is business logic, not RBAC)
- REST API viewer deny: assert not in (200, 201) since FastAPI may
  return 422 (schema validation) before RBAC check runs

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

* fix: use Apache-2.0 license identifier consistently across all test files

Replace SPDX-License-Identifier: MIT with Apache-2.0 to match the
rest of the project.

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

---------

Signed-off-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

rbac Role-based Access Control

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant