diff --git a/litellm/proxy/public_endpoints/provider_create_fields.json b/litellm/proxy/public_endpoints/provider_create_fields.json index dda8e49d4c..860593a6ea 100644 --- a/litellm/proxy/public_endpoints/provider_create_fields.json +++ b/litellm/proxy/public_endpoints/provider_create_fields.json @@ -406,6 +406,36 @@ "field_type": "password", "options": null, "default_value": null + }, + { + "key": "tenant_id", + "label": "Tenant ID", + "placeholder": "Enter your Azure AD tenant ID", + "tooltip": "Entra ID (Service Principal) auth. Provide tenant id, client id, and client secret together as an alternative to api key.", + "required": false, + "field_type": "text", + "options": null, + "default_value": null + }, + { + "key": "client_id", + "label": "Client ID", + "placeholder": "Enter your Service Principal client ID", + "tooltip": "Entra ID (Service Principal) auth. Provide tenant id, client id, and client secret together as an alternative to api key.", + "required": false, + "field_type": "text", + "options": null, + "default_value": null + }, + { + "key": "client_secret", + "label": "Client Secret", + "placeholder": "Enter your Service Principal client secret", + "tooltip": "Entra ID (Service Principal) auth. Provide tenant id, client id, and client secret together as an alternative to api key.", + "required": false, + "field_type": "password", + "options": null, + "default_value": null } ], "default_model_placeholder": "azure/my-deployment" diff --git a/tests/test_litellm/proxy/public_endpoints/test_public_endpoints.py b/tests/test_litellm/proxy/public_endpoints/test_public_endpoints.py index 53c98c8c40..d62f88bf16 100644 --- a/tests/test_litellm/proxy/public_endpoints/test_public_endpoints.py +++ b/tests/test_litellm/proxy/public_endpoints/test_public_endpoints.py @@ -110,6 +110,34 @@ def test_watsonx_provider_fields(): assert "zen_api_key" in field_keys +def test_azure_provider_fields_include_entra_id(): + """Azure provider must expose Entra ID (Service Principal) credential fields so + the UI can input tenant_id / client_id / client_secret as an alternative to api_key.""" + app = FastAPI() + app.include_router(router) + client = TestClient(app) + + response = client.get("/public/providers/fields") + providers = response.json() + + azure = next((p for p in providers if p["provider"] == "Azure"), None) + assert azure is not None + + fields_by_key = {f["key"]: f for f in azure["credential_fields"]} + # API-key auth still supported + assert "api_key" in fields_by_key + # Entra ID fields + assert "tenant_id" in fields_by_key + assert "client_id" in fields_by_key + assert "client_secret" in fields_by_key + # client_secret must be masked in the UI + assert fields_by_key["client_secret"]["field_type"] == "password" + # Entra ID is an alternative to api_key, so none of these are individually required + assert fields_by_key["tenant_id"]["required"] is False + assert fields_by_key["client_id"]["required"] is False + assert fields_by_key["client_secret"]["required"] is False + + def test_public_model_hub_with_healthy_model(): """Test that health information is populated for a healthy model""" app = FastAPI()