diff --git a/tests/tools/test_delegation_local_provider.py b/tests/tools/test_delegation_local_provider.py index f3d4650d46c..5d4a5797b5a 100644 --- a/tests/tools/test_delegation_local_provider.py +++ b/tests/tools/test_delegation_local_provider.py @@ -107,6 +107,18 @@ class TestLocalProviderCredentials(unittest.TestCase): creds = _resolve_delegation_credentials(cfg, parent) self.assertEqual(creds["api_key"], "my-secret-key") + def test_localhost_base_url_whitespace_api_key_gets_placeholder(self): + """Whitespace-only api_key should be treated as absent and get placeholder.""" + parent = _make_mock_parent() + cfg = { + "model": "devstral-small-2:24b-cloud", + "provider": "custom", + "base_url": "http://localhost:11434/v1", + "api_key": " ", + } + creds = _resolve_delegation_credentials(cfg, parent) + self.assertEqual(creds["api_key"], "ollama") + # --- base_url path (remote) should still require API key --- def test_remote_base_url_still_requires_api_key(self): @@ -224,6 +236,16 @@ class TestIsLocalBaseUrlHelper(unittest.TestCase): from tools.delegate_tool import _is_local_base_url self.assertFalse(_is_local_base_url(None)) + def test_ipv6_loopback(self): + """IPv6 loopback [::1] should be recognized as local.""" + from tools.delegate_tool import _is_local_base_url + self.assertTrue(_is_local_base_url("http://[::1]:11434/v1")) + + def test_172_outside_private_range(self): + """172.32.x.x is NOT in 172.16/12 and should not be treated as local.""" + from tools.delegate_tool import _is_local_base_url + self.assertFalse(_is_local_base_url("http://172.32.0.1:11434/v1")) + if __name__ == "__main__": unittest.main() \ No newline at end of file diff --git a/tools/delegate_tool.py b/tools/delegate_tool.py index bdd99a90d52..f064ad4fa9b 100644 --- a/tools/delegate_tool.py +++ b/tools/delegate_tool.py @@ -2106,6 +2106,15 @@ def _is_local_base_url(base_url: Optional[str]) -> bool: - localhost / loopback (127.0.0.1, ::1) - .local mDNS hostnames (e.g. studio.local) - RFC 1918 private networks (10/8, 172.16/12, 192.168/16) + + .. note:: + Any URL that resolves as "local" by this function will receive a + placeholder ``"ollama"`` API key. If an internal service on a + private network actually requires authentication (e.g. a corporate + AI gateway at 192.168.x.x), the placeholder key will be rejected + by that server (401/403). This is intentional — local servers that + genuinely don't need auth work out-of-the-box, while misconfigured + endpoints fail loudly rather than silently. """ if not base_url: return False