mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-16 23:41:43 +00:00
Tool-level MCP entitlements are enforced in one place, check_tool_permission_for_key_team, reached from pre_call_tool_check. Two dispatch paths reached a tool handler without passing through it. execute_mcp_tool's legacy fallback dispatched into the local tool registry after retrying the unprefixed name, with no allowed/banned-tool check, no key/team/org tool permissions and no parameter validation. It now runs the same gate, and only when something can actually dispatch: when the unprefixed name is absent from the local registry too, the existing 404 stands rather than becoming a misleading "server unavailable". The server the tool-level checks need is available even though the tool name is not in the tool -> server mapping: a non-empty prefix has already been compared against the caller's allowed_mcp_servers by exact name, so the named server is in that list. It is resolved from allowed_mcp_servers rather than from the manager's registry, because the registry can return a server the caller holds no grant for, and matching on anything other than name would accept a server the server-level check never validated. The remaining case is a prefix segment that is empty, which the server-level check skips entirely because it is gated on a non-empty server name; that now fails closed with 503 instead of dispatching for a caller holding no server grant at all. An entitled caller's legacy call therefore still dispatches, so a configuration that worked before keeps working; only the unentitled call is refused, now with the entitlement gate's own 403. call_tool ran pre_call_tool_check inside `if proxy_logging_obj:`, so an absent logging object would have skipped authorization silently. This half is defensive with no live hole: all four call sites source the module-level ProxyLogging singleton from proxy_server.py, which is never None. The shape was still wrong. pre_call_tool_check now runs its three authorization checks unconditionally and only the guardrail hooks, which are dispatched through the logger, depend on one being present. A third reported path, where allow_all_keys, BYOM-submitted and upstream-delegated servers are unioned in after the resolver's ceilings, was investigated and found not to be a defect. The widening is real, but a server's tool surface is already boundable for every caller at registration through MCPServer.allowed_tools / disallowed_tools, enforced by check_allowed_or_banned_tools ahead of the entitlement check, and per-caller narrowing plus the org tool ceiling remain available. Nothing here changes that path. Resolves LIT-4956 |
||
|---|---|---|
| .. | ||
| mcp_server | ||