Skip to content

fix: access control hardening and behavior consistency (h-batch-3)#3107

Merged
crivetimihai merged 2 commits intomainfrom
h-batch-3
Feb 22, 2026
Merged

fix: access control hardening and behavior consistency (h-batch-3)#3107
crivetimihai merged 2 commits intomainfrom
h-batch-3

Conversation

@crivetimihai
Copy link
Copy Markdown
Member

Summary

This PR hardens access-control and ownership-scope behavior across RPC, resource reads, OAuth gateway sync, and import sanitization, with focused regression coverage for allow/deny paths.

Changes

  • C-05

    • Enforced tools.execute for backward-compatible JSON-RPC tool invocation (method=<tool_name>) in addition to tools/call.
    • Added regression tests for deny and allow paths.
  • C-18

    • Added scoped ownership enforcement to GET /resources/{resource_id}/info.
    • Kept fail-closed ownership behavior aligned for ID-based access checks.
    • Added regression coverage for deny behavior.
  • C-19

    • Maintained root-management RBAC alignment (admin.system_config) across root routes.
  • C-20

    • Unified OAuth fetch-tools scope resolution with normalized token-team semantics.
    • Preserved public-only semantics for empty-team tokens while preventing unrestricted fallback.
    • Added allow/deny regression tests.
  • C-35

    • Kept server SSE existence + scope checks consistent with deterministic 404/403 behavior.
  • C-39

    • Expanded import field sanitization for scoped entities to drop untrusted team_id, owner_email, visibility, and team values before persistence.
    • Added regression coverage.
  • Token helper consistency

    • Updated JWT rich-token creation to distinguish omitted teams from explicit teams: null.
    • Preserves intended scoped-token semantics for admin and public-only flows.
    • Added unit coverage for omitted vs explicit-null teams behavior and CLI admin token generation path.

Validation

  • Targeted regressions:

    • uv run pytest -q tests/unit/mcpgateway/test_main.py::TestRPCEndpoints::test_rpc_legacy_tool_invocation_requires_tools_execute tests/unit/mcpgateway/test_main_extended.py::TestRpcHandling::test_handle_rpc_backward_compat_tool_requires_execute_permission tests/unit/mcpgateway/test_main_extended.py::TestRpcHandling::test_handle_rpc_backward_compat_tool_allows_when_authorized tests/unit/mcpgateway/test_main_extended.py::TestRemainingCoverageGaps::test_get_resource_info_success_and_not_found tests/unit/mcpgateway/test_main_extended.py::TestRemainingCoverageGaps::test_get_resource_info_denies_when_scope_enforcement_fails tests/unit/mcpgateway/routers/test_oauth_router.py::TestOAuthRouter::test_fetch_tools_after_oauth_cached_public_only_admin_token_stays_scoped tests/unit/mcpgateway/routers/test_oauth_router.py::TestOAuthRouter::test_fetch_tools_after_oauth_cached_public_only_admin_token_allow_path tests/unit/mcpgateway/services/test_import_service.py::test_sanitize_import_scope_fields_removes_team_and_owner tests/unit/mcpgateway/services/test_import_service.py::test_process_entities_strips_untrusted_scope_fields_before_processing tests/unit/mcpgateway/test_rpc_backward_compatibility.py
    • Result: pass
  • Full affected unit modules:

    • uv run pytest -q tests/unit/mcpgateway/test_main.py tests/unit/mcpgateway/test_main_extended.py tests/unit/mcpgateway/routers/test_oauth_router.py tests/unit/mcpgateway/services/test_import_service.py tests/unit/mcpgateway/test_rpc_backward_compatibility.py
    • Result: pass
  • Token helper tests:

    • uv run pytest -q tests/unit/mcpgateway/utils/test_create_jwt_token.py
    • Result: pass
  • Playwright checks relevant to entity delete behavior:

    • uv run pytest -q tests/playwright/entities/test_entity_lifecycle.py::TestToolLifecycle::test_delete_tool tests/playwright/entities/test_entity_lifecycle.py::TestResourceLifecycle::test_delete_resource tests/playwright/entities/test_entity_lifecycle.py::TestPromptLifecycle::test_delete_prompt tests/playwright/entities/test_entity_lifecycle.py::TestServerLifecycle::test_delete_server
    • Result: pass
  • Scope matrix check:

    • uv run pytest -q tests/playwright/security/test_token_scope_matrix.py::TestTokenTeamsMatrix::test_teams_claim_matrix_controls_visibility
    • Result: pass
  • Quality gates:

    • make flake8 (pass)
    • make pylint (pass, 10.00/10)

Changelog

  • Updated CHANGELOG.md under 1.0.0-RC2 to capture the hardening details and token-helper semantics update.

Refs: C-05, C-18, C-19, C-20, C-35, C-39

- C-05: require tools.execute for both tools/call and legacy JSON-RPC tool invocation paths

- C-18: enforce scoped access on GET /resources/{resource_id}/info and maintain fail-closed ID ownership checks

- C-19: align root management endpoints with admin.system_config authorization requirements

- C-20: harden OAuth fetch-tools scope resolution and ownership checks with normalized token-team semantics

- C-35: validate server existence and scoped access before SSE setup, preserving deterministic 404/403 behavior

- C-39: sanitize imported scoped fields (team_id, owner_email, visibility, team) before persistence

- C-18: harden JWT rich-token teams semantics by distinguishing omitted teams from explicit teams=null

- add/update regression tests for allow/deny coverage across RPC, OAuth, resource info, import sanitization, and token helpers

- update CHANGELOG and local issue evidence/index entries for the hardening follow-up

Refs: C-05 C-18 C-19 C-20 C-35 C-39
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
@crivetimihai crivetimihai self-assigned this Feb 22, 2026
@crivetimihai crivetimihai added security Improves security revisit Revisit this PR at a later date to address further issues, or if problems arise. labels Feb 22, 2026
@crivetimihai crivetimihai added this to the Release 1.0.0-GA milestone Feb 22, 2026
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
@crivetimihai crivetimihai merged commit 60b2ad7 into main Feb 22, 2026
54 checks passed
@crivetimihai crivetimihai deleted the h-batch-3 branch February 22, 2026 22:20
@crivetimihai crivetimihai changed the title fix: access control hardening and behavior consistency fix: access control hardening and behavior consistency (h-batch-3) Feb 23, 2026
vishu-bh pushed a commit that referenced this pull request Feb 24, 2026
* fix: access control hardening and behavior consistency

- C-05: require tools.execute for both tools/call and legacy JSON-RPC tool invocation paths

- C-18: enforce scoped access on GET /resources/{resource_id}/info and maintain fail-closed ID ownership checks

- C-19: align root management endpoints with admin.system_config authorization requirements

- C-20: harden OAuth fetch-tools scope resolution and ownership checks with normalized token-team semantics

- C-35: validate server existence and scoped access before SSE setup, preserving deterministic 404/403 behavior

- C-39: sanitize imported scoped fields (team_id, owner_email, visibility, team) before persistence

- C-18: harden JWT rich-token teams semantics by distinguishing omitted teams from explicit teams=null

- add/update regression tests for allow/deny coverage across RPC, OAuth, resource info, import sanitization, and token helpers

- update CHANGELOG and local issue evidence/index entries for the hardening follow-up

Refs: C-05 C-18 C-19 C-20 C-35 C-39
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

* Update tests

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

revisit Revisit this PR at a later date to address further issues, or if problems arise. security Improves security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant