mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-15 23:31:29 +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 |
||
|---|---|---|
| .. | ||
| auth | ||
| faults | ||
| guardrail_translation | ||
| outbound_credentials | ||
| conftest.py | ||
| test_byok_oauth_endpoints.py | ||
| test_callback_oauth_error_responses.py | ||
| test_db_credentials.py | ||
| test_discoverable_endpoints.py | ||
| test_gateway_dcr_flow.py | ||
| test_is_tool_name_prefixed.py | ||
| test_jwt_mcp_enforcement.py | ||
| test_jwt_mcp_simple.py | ||
| test_mcp_cost_calculator.py | ||
| test_mcp_custom_fields.py | ||
| test_mcp_debug.py | ||
| test_mcp_discovery.py | ||
| test_mcp_elicitation_handler.py | ||
| test_mcp_env_vars.py | ||
| test_mcp_header_alias_utils.py | ||
| test_mcp_hook_extra_headers.py | ||
| test_mcp_max_concurrent_requests.py | ||
| test_mcp_metadata_preservation.py | ||
| test_mcp_oauth_passthrough.py | ||
| test_mcp_oauth_passthrough_cold_start.py | ||
| test_mcp_oauth_passthrough_tools.py | ||
| test_mcp_partial_update.py | ||
| test_mcp_sampling_completion_flow.py | ||
| test_mcp_sampling_model_access.py | ||
| test_mcp_sampling_model_resolution.py | ||
| test_mcp_sampling_priority_selection.py | ||
| test_mcp_sampling_request_builder.py | ||
| test_mcp_sampling_response_conversion.py | ||
| test_mcp_sampling_tool_conversion.py | ||
| test_mcp_server.py | ||
| test_mcp_server_identity_env.py | ||
| test_mcp_server_manager.py | ||
| test_mcp_session_logging.py | ||
| test_mcp_sigv4_auth.py | ||
| test_mcp_stale_session.py | ||
| test_mcp_tool_search.py | ||
| test_mcp_toolset_scope.py | ||
| test_oauth2_flow_backfill.py | ||
| test_oauth2_token_cache.py | ||
| test_oauth_issuer_stamp_backfill.py | ||
| test_openapi_to_mcp_generator.py | ||
| test_openapi_tool_auth.py | ||
| test_rest_endpoints.py | ||
| test_semantic_tool_filter.py | ||
| test_short_mcp_tool_prefix.py | ||
| test_ui_session_utils.py | ||
| test_utils.py | ||