Conversation
jonpspri
added this pull request to stack #6729
September 9, 2026 23:38
jonpspri
marked this pull request as ready for review
September 9, 2026 23:39
jonpspri
requested review from
Lang-Akshay,
brian-hussey,
crivetimihai,
ja8zyjits and
msureshkumar88
as code owners
September 9, 2026 23:39
jonpspri
force-pushed
the
feat/5976-external-group-mappings
branch
from
September 10, 2026 06:22
c6f2cad to
711a223
Compare
jonpspri
removed this pull request from stack #6729
September 12, 2026 08:50
jonpspri
force-pushed
the
feat/5976-external-group-mappings
branch
from
September 12, 2026 09:07
711a223 to
7e69c55
Compare
jonpspri
added this pull request to stack #6798
September 12, 2026 09:08
jonpspri
force-pushed
the
feat/5976-external-group-mappings
branch
2 times, most recently
from
September 12, 2026 09:48
dcb8093 to
d3978f1
Compare
jonpspri
force-pushed
the
feat/5976-external-group-mappings
branch
2 times, most recently
from
September 12, 2026 17:20
2063d23 to
e0f5198
Compare
jonpspri
force-pushed
the
feat/5976-external-group-mappings
branch
from
September 12, 2026 17:35
e0f5198 to
5edaeba
Compare
Signed-off-by: Jonathan Springer <jps@s390x.com>
…umns head PR #6735 added migration a824749abd27 (user_id columns on user_roles and email_team_members) parented at bf2998718ea1, which made e5f6a7b8c9d0 a sibling head. Re-parent e5f6a7b8c9d0 onto a824749abd27 to restore the single linear chain: bf2998718ea1 -> a824749abd27 -> e5f6a7b8c9d0. Signed-off-by: Jonathan Springer <jps@s390x.com>
…rnal identity cache The plain unique constraint on (issuer, tenant, external_group_id) treats NULL tenants as distinct on SQLite and PostgreSQL, permitting duplicate (issuer, external_group_id) rows when tenant IS NULL and weakening the one-group-to-one-team rule. Add a partial unique index (idempotent migration plus model declaration) for the NULL-tenant case and an application-level pre-check in mapping create/update that raises the existing 409 conflict. Wire the existing invalidate_external_identity_cache() into every successful mapping create/update/delete so mutations take effect for cached external token identities immediately. Signed-off-by: Jonathan Springer <jps@s390x.com>
jonpspri
force-pushed
the
feat/5976-external-group-mappings
branch
from
September 12, 2026 21:11
422c646 to
b29c785
Compare
Collaborator
Author
|
Requirement note (remediation) — three changes
See the note on #5976. |
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.
Adds the
external_group_mappingslayer for trust-mode Layer-1 scoping. One idempotent migration (e5f6a7b8c9d0, parentbf2998718ea1) creates the table:issuer,tenant(nullable),external_group_id,cf_team_id(FKemail_teams.id),cf_role(plainString(255)validated against therolestable at write time — NOT a foreign key, becauseroles.namecarries only a partial unique index),validation_status,last_validated_at, timestamps, and the unique key(issuer, tenant, external_group_id)with the one-group-one-team-one-role decision documented in the migration comment. TheExternalGroupMappingORM mirrors it.The resolver
resolve_external_groups_to_teams(issuer, tenant, groups, db)in the newmcpgateway/utils/trusted_claims.pyreturns(team_ids, role_names); unmapped groups contribute nothing (fail-closed). Raw external group IDs never reachtoken_teams. Admin CRUD lives under/admin/external-group-mappings(RBAC-scoped, sibling convention), with deny paths tested: 401 unauthenticated, 403 insufficient permission, 400 unknown team or role, 409 duplicate, 404 missing. The Graph existence validator ships as an injectable seam, disabled by default (returnsvalid); WARN-AND-ALLOW semantics documented — the real client lands with #5977.Visibility-gate and e2e team-isolation/no-mapping tests land as
xfail(strict=True, reason="Requires trust branch from #5900")— 404-not-403 per_check_agent_access.Tested with:
uv run pytest tests/unit/mcpgateway/ -k "group_mapping or external_group or visibility_gate" -q— 34 passed, 4 xfailed (TDD: collection ImportErrors first)e5f6a7b8c9d0; columns verified in the migrated DB. Postgres runs in the Epic 2 gate's docker stacks (constructs used are portable).make ruff— all checks passedmake test— 23268 passed, 879 skipped, 9 xfailedAcceptance criteria of #5976 are met. Risk to existing users: none — a new table and new endpoints; no existing table or path changed.
Stack: B.4 of epic #5885 (base: #6740).
Closes #5976