mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
* fix(ui_sso): resolve highest privilege Entra app role, not first in claim A user assigned more than one Entra app role — commonly by belonging to several assigned groups — arrives at the Microsoft SSO callback with every role in the id_token `roles` claim. LiteLLM stores a single role per user, and get_microsoft_callback_response collapsed the list by taking the first value that resolved to a LitellmUserRoles and breaking. Entra does not guarantee the ordering of the `roles` claim, so which role won was effectively arbitrary: a user in one group mapped to internal_user and another mapped to proxy_admin_viewer could be silently demoted to internal_user, and proxy_admin could lose to either. The generic/Okta path already resolves this correctly via determine_role_from_groups, which walks a documented privilege hierarchy. Hoist that hierarchy into LITELLM_USER_ROLE_HIERARCHY and reuse it, so app-role logins and group-mapping logins agree. Extract the selection into MicrosoftSSOHandler.get_user_role_from_app_roles so it is directly testable — the existing tests re-implemented the loop inline, which is why the ordering bug was not caught. Behaviour is unchanged for single-role claims, unrecognised values, and empty claims. Roles the hierarchy does not rank (org_admin, team, customer) are resolved deterministically rather than by claim order. * refactor(ui_sso): trim role selection prose and use immutable annotations Addresses review feedback on the app role selection helper. Drop the explanatory comments and the Args/Returns docstring boilerplate that restated the control flow, keeping only the part a reader cannot infer from the code: that Entra does not guarantee claim ordering, and how unranked roles resolve. Type the parameter as Sequence[str] rather than list[str] and build the resolved set as a frozenset, so the helper stops adding an LIT001 mutable-collection annotation. Make LITELLM_USER_ROLE_HIERARCHY a tuple for the same reason. No behaviour change: the ordering regression tests still fail against the previous first-match-wins logic and pass here. |
||
|---|---|---|
| .. | ||
| management_v1 | ||
| policy_endpoints | ||
| scim | ||
| search_endpoints | ||
| usage_endpoints | ||
| test_access_group_endpoints.py | ||
| test_access_group_management.py | ||
| test_activity_tenant_scoping.py | ||
| test_auto_router_endpoints.py | ||
| test_budget_endpoints.py | ||
| test_cache_settings_endpoints.py | ||
| test_callback_management_endpoints.py | ||
| test_common_daily_activity.py | ||
| test_common_utils.py | ||
| test_compliance_endpoints.py | ||
| test_config_override_endpoints.py | ||
| test_coordination_redis_endpoints.py | ||
| test_cost_estimate_endpoint.py | ||
| test_cost_tracking_settings.py | ||
| test_credential_migration.py | ||
| test_customer_budget.py | ||
| test_customer_endpoints.py | ||
| test_delete_callbacks_endpoint.py | ||
| test_delete_verification_tokens_failed.py | ||
| test_encryption_endpoints.py | ||
| test_entraid_app_roles.py | ||
| test_gateway_request_endpoints.py | ||
| test_internal_user_endpoints.py | ||
| test_key_management_endpoints.py | ||
| test_mcp_management_endpoints.py | ||
| test_model_management_endpoints.py | ||
| test_org_admin_team_access.py | ||
| test_organization_endpoints.py | ||
| test_policy_endpoints.py | ||
| test_project_org_authz.py | ||
| test_ptu_model_settings.py | ||
| test_router_settings_endpoints.py | ||
| test_saml_sso.py | ||
| test_tag_management_endpoints.py | ||
| test_team_callback_endpoints.py | ||
| test_team_default_params.py | ||
| test_team_endpoints.py | ||
| test_team_model_alias_merge.py | ||
| test_tool_management_endpoints.py | ||
| test_ui_sso.py | ||
| test_workflow_management_endpoints.py | ||