litellm/litellm/proxy/common_utils
Yassin Kortam a187cb9886
feat(mcp): enforce per-user MCP tool-call entitlements in the auth module (#35146)
The MCP gateway resolved a caller's allowed servers and per-server tool
allowlists from the key, the team, the end user and the agent, but never from
the internal user row, so an admin had no way to bound what a person may call
across every key they hold. Anything the key allowed went through

The internal user now carries the same object_permission an admin already
attaches to a key or a team, and the resolver applies it as a ceiling: the
caller ends up with the intersection of what the key allows and what the user
allows, so adding a user entitlement can only narrow, never widen. A level
that names no server and no tool places no ceiling, which keeps every existing
deployment on its current behavior

/user/new and /user/update accept object_permission and reuse the same
create-or-update helper the team endpoints use, so the row is written once and
the three cached views of it (the user row, the object-permission link and the
permission itself) are invalidated on write. Clearing it with an empty object
now really unlinks the permission instead of being swallowed as an empty value

A row that cannot be read at all places no ceiling, but a row that names a
permission the database cannot return denies the call rather than falling
through to the wider set, so a partial outage cannot hand out access the admin
withheld

The users page grows the MCP servers, access groups, toolsets and per-server
tool pickers the key and team pages already have. A save keeps a tool
allowlist whenever an access group or toolset the admin retained could still
supply that server, since an allowlist is what narrows a grant and an absent
one reads as no restriction; it drops the allowlist once nothing indirect
survives to supply the server, so removing a grant really removes it
2026-07-30 12:06:33 -07:00
..
html_forms feat(proxy): configurable response headers and login-page hint (#30792) 2026-06-18 18:12:45 -07:00
admin_ui_utils.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
banner.py style: run black formatter on entire codebase 2026-03-11 17:07:57 -03:00
cache_coordinator.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
cache_pydantic_utils.py fix(proxy): stop CacheCodec dropping null fields on cache round-trip (#32207) 2026-07-06 12:53:00 -07:00
callback_utils.py fix(proxy): sanitize per-key callback config out of logged metadata 2026-07-24 22:16:50 -07:00
custom_openapi_spec.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
debug_utils.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
encrypt_decrypt_utils.py fix(proxy): stop the decrypt-failure debug log from leaking the raw value 2026-07-03 13:03:45 -07:00
expired_ui_session_key_cleanup_manager.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
get_routes.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
http_parsing_utils.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
json_merge_patch.py fix(team): bound json merge patch recursion depth 2026-07-11 09:36:15 -07:00
key_rotation_manager.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
load_config_utils.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
model_listing_utils.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
openai_endpoint_utils.py build(deps-dev): bump black to 26.3.1 and apply formatting (#28525) 2026-05-21 17:24:18 -07:00
openapi_schema_compat.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
path_utils.py fix(ci): resolve mypy and ruff lint failures 2026-04-15 21:12:51 -07:00
performance_utils.md build: migrate packaging, CI, and Docker from Poetry to uv (#25007) 2026-04-09 11:46:23 -07:00
performance_utils.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
proxy_rate_limit_error.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
proxy_state.py (feat) UI - Disable Usage Tab once SpendLogs is 1M+ Rows (#7208) 2024-12-12 18:43:17 -08:00
rbac_utils.py style: unify ruff format width on 120 (#31518) 2026-06-27 12:39:29 -07:00
realtime_utils.py style: run black formatter on entire codebase 2026-03-11 17:07:57 -03:00
reset_budget_job.py fix(proxy): global max_budget ignores budget_duration; enforce against the resettable proxy budget row (#33732) 2026-07-25 11:29:39 -07:00
resource_ownership.py fix(ownership): reject identity-less callers instead of sharing a sentinel scope 2026-05-04 23:40:22 +00:00
static_asset_utils.py fix(static-assets): browser-load remote branding assets 2026-04-30 11:30:57 -07:00
swagger_utils.py show all error types on swagger 2024-08-29 18:50:41 -07:00
timezone_utils.py feat(budgets): add configurable budget_reset_time of day (#31007) 2026-07-21 13:35:01 -07:00
user_api_key_cache.py feat(mcp): enforce per-user MCP tool-call entitlements in the auth module (#35146) 2026-07-30 12:06:33 -07:00