diff --git a/litellm/proxy/auth/auth_utils.py b/litellm/proxy/auth/auth_utils.py index 9ba91de703b..f3d7805693b 100644 --- a/litellm/proxy/auth/auth_utils.py +++ b/litellm/proxy/auth/auth_utils.py @@ -647,6 +647,17 @@ def _iter_user_config_litellm_params(user_config: object) -> Iterator[Mapping[st yield params +def _user_config_search_tool_params(user_config: object) -> tuple[Mapping[str, object], ...]: + config: Final = _coerce_metadata_to_dict(user_config) + if config is None: + return () + return tuple( + params + for entry in _mappings_in(config.get("search_tools")) + if (params := _coerce_metadata_to_dict(entry.get("litellm_params"))) is not None + ) + + def iter_request_fallback_targets(request_body: Mapping[str, object]) -> Iterator[str | Mapping[str, object]]: for value in _iter_fallback_field_values(request_body): yield from _iter_fallback_targets(value, 0) @@ -806,7 +817,10 @@ def is_request_body_safe( banned_params=_BANNED_METADATA_PARAMS, rejects_secret_references=False, ) - for user_config_params in _iter_user_config_litellm_params(request_body.get("user_config")): + for user_config_params in ( + *_iter_user_config_litellm_params(request_body.get("user_config")), + *_user_config_search_tool_params(request_body.get("user_config")), + ): _reject_user_config_secret_references(user_config_params) return True diff --git a/tests/unit/proxy/auth/test_auth_utils.py b/tests/unit/proxy/auth/test_auth_utils.py index bd915f8d8e1..f634b8d7fcd 100644 --- a/tests/unit/proxy/auth/test_auth_utils.py +++ b/tests/unit/proxy/auth/test_auth_utils.py @@ -409,11 +409,13 @@ _USER_CONFIG_SECRET_REFERENCE_PARAMS: Final = ( def _user_config(slot: str, litellm_params: Mapping[str, object]) -> Mapping[str, object]: if slot == "default_litellm_params": return {"default_litellm_params": dict(litellm_params)} + if slot == "search_tools": + return {"search_tools": [{"search_tool_name": "caller-search", "litellm_params": dict(litellm_params)}]} return {"model_list": [{"model_name": "caller-model", "litellm_params": dict(litellm_params)}]} @pytest.mark.parametrize("litellm_params", _USER_CONFIG_SECRET_REFERENCE_PARAMS) -@pytest.mark.parametrize("slot", ("model_list", "default_litellm_params")) +@pytest.mark.parametrize("slot", ("model_list", "default_litellm_params", "search_tools")) def test_user_config_secret_references_are_rejected_despite_client_side_opt_in( litellm_params: Mapping[str, object], slot: str ) -> None: