From baeda235bb9b0474b80fc572a73e4da766d247e2 Mon Sep 17 00:00:00 2001 From: Ryan Crabbe Date: Sat, 4 Apr 2026 11:19:45 -0700 Subject: [PATCH] feat(ui): expose Azure Entra ID credential fields in provider form Adds tenant_id, client_id, and client_secret to the Azure provider entry in provider_create_fields.json so the credential add/edit modals and the add-model form surface Service Principal auth as an alternative to api_key. The Azure handler already reads these fields from litellm_params at request time via get_azure_ad_token(); this change makes them inputtable from the UI without code changes to the React components (the form is driven by GET /public/providers/fields). --- .../provider_create_fields.json | 30 +++++++++++++++++++ .../public_endpoints/test_public_endpoints.py | 28 +++++++++++++++++ 2 files changed, 58 insertions(+) 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()