Files
litellm/ui
ryan-crabbe-berri 90b5104475 feat(mcp/auth): additive key access-group grants + opt-in member assignment (#29313)
* fix(mcp): make key.access_group_ids grants additive over team ceiling

A key whose unified access_group_ids grant a private MCP server was
having that grant intersected against its team's MCP ceiling, so a key
in a team scoped to other servers (or with no own scope) lost the
granted server entirely. Resolve access_group_ids once as ungated
additive grants and union them on top of the key/team ceiling instead
of folding them into the key scope that gets intersected.

* test(mcp): align key access-group tests with additive-grant model

The previous commit moved key.access_group_ids resolution out of the
intersected key ceiling (_get_allowed_mcp_servers_for_key) and into the
ungated additive grant path (_get_key_access_group_mcp_server_extras),
unioned on top of the team ceiling. Five tests from #28890/#29195 still
asserted the old gated / in-key-scope contract and failed:

- _get_allowed_mcp_servers_for_key now returns the object_permission
  ceiling only and never resolves access_group_ids; two tests now assert
  the group resolver is not called from that path (with and without an
  object_permission present).
- The extras path is ungated, so a group whose assigned_team_ids /
  assigned_key_ids exclude the caller still contributes its servers.
- The end-to-end test asserts the grant surfaces via the extras path
  rather than the base key path.
- Dropped test_key_access_group_ids_empty_returns_no_extras; the empty
  case is already covered by the extras family's no-groups test.

* feat(auth): gate member access-group assignment on keys behind opt-in

Non-admin team members could attach access_group_ids to keys they create
or update, letting them self-grant resources (MCP servers/models) the team
admin never intended. Add an opt-in KEY_ACCESS_GROUP_ASSIGNMENT team-member
permission (default-deny) enforced at /key/generate and /key/update; proxy
and team admins bypass. Surfaces automatically as a checkbox in the team
Member Permissions UI.

* fix(auth): gate access-group assignment on /key/regenerate too

RegenerateKeyRequest inherits access_group_ids and prepare_key_update_data
persists it, so a non-admin key owner could self-grant access groups by
regenerating. Apply the same opt-in member gate using the existing key's
team.

* test(auth): cover member access-group gate and additive MCP grants

Add unit tests for enforce_member_can_assign_access_groups (deny without
opt-in, allow with opt-in, and proxy-admin / team-admin / non-team-key
bypasses) and for _get_key_access_group_mcp_server_extras (no-auth and
no-resolved-servers return empty, resolved ids are expanded, errors
degrade to no grants).
2026-05-30 17:35:31 -07:00
..