Add per-toolkit access-group grants - #1598
Open
TheLiberal wants to merge 3 commits into
Open
Conversation
Tenant-scoped access_group/access_group_member tables plus a nullable connection.access_group column. A restricted org connection is invisible and uninvokable for non-members on every read and invoke surface, with no existence oracle; membership is read live per call. Management rides executor.accessGroups behind host admin gates (cloud /org/access-groups*, self-host /api/admin/access-groups*), never the any-member ExecutorApi. Platform view and subject-less org bindings stay unfiltered by design.
The cascade tripwire caught the gap: the hand-written purge list must name every tenant table, and access_group/access_group_member were missing.
A toolkit granted to a group exists only for its members: the slug resolves to nothing for anyone else (toolkit MCP sessions block-all, identical to an unknown slug) and its CRUD reads answer not-found. Grants are managed through the extension's setAccessGroup, exposed only on the host admin planes; the group-deletion path refuses to orphan a toolkit grant. Plugins gain a read-only core seam (accessGroups.visibleGroupIds) to apply the same restricted-is-invisible rule core applies to connections.
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.
Stacked on #1597 — includes its commits until it merges; only the last commit is new here.
A toolkit granted to a group exists only for that group's members: its slug resolves to nothing for anyone else (a toolkit MCP session then blocks everything, identical to an unknown slug) and its CRUD reads answer not-found — the same restricted-is-invisible rule #1597 applies to connections.
accessGroupis an optional field on the toolkit record (absent = unrestricted, so every pre-existing record keeps its semantics); gates ingetBySlugEntry/requireToolkit/listread membership live per call through a new read-only plugin core seam,ctx.core.accessGroups.visibleGroupIds().setAccessGroup/listRestrictedToolkitson the toolkits extension, exposed only on the host admin planes — deliberately not on the member-facing toolkit routes. The management path reads the raw record so an admin can ungrant a toolkit they are not a member of; their runtime view stays filtered like everyone's.Tests: toolkit visibility/grant suite (member vs non-member slug resolution, admin-runtime-filtered, live ungrant, personal/unknown-toolkit rejection) plus the self-host node test extended with the toolkit-grant HTTP round trip and the delete-while-granted refusal.