From fe6a5351eeec18ca40aa06a9097ecabfd25b40d1 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Thu, 3 Sep 2026 13:40:18 -0700 Subject: [PATCH] fix(openai): let workload identity federation target the regional api.openai.com hosts --- litellm/llms/openai/workload_identity.py | 5 ++++- .../openai/test_openai_workload_identity.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/litellm/llms/openai/workload_identity.py b/litellm/llms/openai/workload_identity.py index 48e9b779a34..aef5d16807e 100644 --- a/litellm/llms/openai/workload_identity.py +++ b/litellm/llms/openai/workload_identity.py @@ -18,6 +18,7 @@ if TYPE_CHECKING: OPENAI_WIF_CLIENT_ID: Final = "litellm" _OPENAI_API_HOST: Final = "api.openai.com" +_OPENAI_REGIONAL_HOST_SUFFIX: Final = f".{_OPENAI_API_HOST}" _SDK_UPGRADE_MESSAGE: Final = ( "OpenAI workload identity federation requires openai>=2.32.0. " "Upgrade the installed openai package to use OPENAI_IDENTITY_PROVIDER_ID / " @@ -86,7 +87,9 @@ def _targets_openai_api(api_base: str | None) -> bool: if api_base is None: return True parsed: Final = urlparse(api_base) - return parsed.scheme == "https" and parsed.hostname == _OPENAI_API_HOST + if parsed.scheme != "https" or parsed.hostname is None: + return False + return parsed.hostname == _OPENAI_API_HOST or parsed.hostname.endswith(_OPENAI_REGIONAL_HOST_SUFFIX) @lru_cache(maxsize=16) diff --git a/tests/test_litellm/llms/openai/test_openai_workload_identity.py b/tests/test_litellm/llms/openai/test_openai_workload_identity.py index 1f010ef19ee..7965ca2df0a 100644 --- a/tests/test_litellm/llms/openai/test_openai_workload_identity.py +++ b/tests/test_litellm/llms/openai/test_openai_workload_identity.py @@ -97,6 +97,23 @@ class TestResolveConfig: def test_plaintext_http_api_base_disables(self, wif_env: OpenAIWorkloadIdentityConfig) -> None: assert resolve_openai_workload_identity_config(api_key=None, api_base="http://api.openai.com/v1") is None + @pytest.mark.parametrize("regional_host", ("eu.api.openai.com", "us.api.openai.com")) + def test_regional_openai_api_base_allows( + self, wif_env: OpenAIWorkloadIdentityConfig, regional_host: str + ) -> None: + assert ( + resolve_openai_workload_identity_config(api_key=None, api_base=f"https://{regional_host}/v1") == wif_env + ) + + @pytest.mark.parametrize( + "lookalike_base", + ("https://api.openai.com.evil.example/v1", "https://openai.com/v1", "https://euapi.openai.com/v1"), + ) + def test_openai_lookalike_api_base_disables( + self, wif_env: OpenAIWorkloadIdentityConfig, lookalike_base: str + ) -> None: + assert resolve_openai_workload_identity_config(api_key=None, api_base=lookalike_base) is None + def test_foreign_env_base_url_disables( self, wif_env: OpenAIWorkloadIdentityConfig, monkeypatch: pytest.MonkeyPatch ) -> None: