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).
This commit is contained in:
Ryan Crabbe
2026-04-04 11:19:45 -07:00
parent a5322c6efc
commit baeda235bb
2 changed files with 58 additions and 0 deletions
@@ -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"
@@ -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()