Providers
The Providers screen lets you connect model providers (cloud or local) to your tenant, test the connection, switch a provider off at once and import the models it serves into the registry. Portal path: /llm/providers (LLM management > Providers). It is used by the AI platform administrators (tenant_admin, platform_admin, ai_platform_engineer); the other LLM readers see the catalog and the state of each provider. The screen is built in portal/src/screens/llm.tsx (Providers, ProviderDrawer, DiscoveryPanel).
What the screen shows
The screen is a catalog of cards, not a table. The built-in presets of the portal are merged with the catalog read from GET /v1/providers/catalog: OpenAI, Azure OpenAI, AWS Bedrock, Gemini, Google Vertex AI, Anthropic, Qwen (Alibaba), Z.AI, DeepSeek, MiniMax, Ollama, LM Studio, vLLM, OpenAI Codex, Github Copilot, Mistral, Groq, Hugging Face, Cohere, Together AI, Fireworks AI, OpenRouter, Azure AI Foundry, Custom OpenAI Compatible and Custom Anthropic Compatible, plus any extra entry of the API catalog.
| Element | Content |
|---|---|
| Search box Search providers | Filters on the label and the identifier of the provider. |
| Filter Hosting | All hostings, Cloud or Local. |
| Filter Status | All statuses, Configured, Not configured or Disabled. |
| Counter | N provider(s) shown after the filters. |
| Section Configured providers (n) | Providers connected to this tenant, enabled ones first. Hint: use the ... menu to fetch their models, disable them or disconnect them. When empty: "No provider configured yet: pick one below and configure it." |
| Section Available providers (n) | The rest of the catalog. Hint: configure a provider to connect it; it then moves to the top of the page. |
| Card | Two letter badge, label, base URL (or Base URL required), status badge (Configured, Not configured, Not connected, Disabled), hosting badge (Cloud or Local), the note Manual entry only when the provider has no model listing API, and "Enable the provider to fetch its models." when it is disabled. |
| Pagination | One pager per section. |
When the catalog cannot be read, an error panel with Retry is shown at the top and every card is listed as available with the status Not connected.
Configure opens a side drawer titled with the provider label ("Fields come from the provider catalog. Secrets are write only."):
- Accepted credential sets when the provider accepts several combinations, and the model hints as badges;
- the Enabled switch (kill switch: "disabling stops every call to this provider immediately"), only once the provider is configured;
- the form: Name (
a-z, 0-9, -), Base URL when the catalog has no address field, then the fields of the provider (for exampleregion,access_key_id,secret_access_key,role_arnfor AWS Bedrock;endpoint,api_version,deployment,api_keyfor Azure OpenAI;project,location,service_account_jsonfor Vertex AI). Secret fields are write only; when you edit, "Leave empty to keep the stored value"; - Save, then Test connection with the JSON answer of the test.
Fetch models opens the dialog Models of <provider>: models read from the provider API with the stored credentials. It has a search box, a category filter, the summary N model(s) found, M already registered, Fetch again, and a table with the columns: selection box, Provider model (with the suggested registry id below), Name, Context, Max output, Price / 1M tokens (in / out), Category (a selector per row) and State (Registered or New). Registered models cannot be selected again. For a provider without listing API the dialog says "This provider has no model listing API", gives the reason (Vertex AI only lists the publisher catalogue; an Azure AI Foundry endpoint serves one model; a subscription account has no public listing) and offers Add manually.
Actions
| Button or action | What it does | API call | Roles |
|---|---|---|---|
| Configure (card) | Opens the configuration drawer of the provider. | none (catalog already loaded) | everyone who sees the screen; saving needs an administrator role |
| Save (drawer, new provider) | Creates the provider: secrets go to credentials, the other fields to config. Toast Saved. | POST /v1/providers | tenant_admin, platform_admin, ai_platform_engineer |
| Save (drawer, configured provider) | Updates the configuration; empty secret fields keep the stored value. | PATCH /v1/providers/{pid} | tenant_admin, platform_admin, ai_platform_engineer |
| Enabled switch (drawer) | Kill switch: off disables every call to the provider, on enables it again. | POST /v1/providers/{pid}/disable or POST /v1/providers/{pid}/enable | disable: the three administrator roles and security_officer; enable: the three administrator roles |
| Test connection (drawer) | Tests the saved configuration and shows the JSON answer. Disabled until the configuration is saved. | POST /v1/providers/{pid}/test | tenant_admin, platform_admin, ai_platform_engineer |
| Fetch models (... menu, configured provider) | Opens the models dialog and lists the models the provider serves, with the categories of the tenant. | POST /v1/providers/{pid}/models/discover, GET /v1/llm/categories | tenant_admin, platform_admin, ai_platform_engineer |
| Disable (... menu, configured provider) | Asks a confirmation (recorded in the audit log), then disables the provider. | POST /v1/providers/{pid}/disable | menu shown to tenant_admin, platform_admin, ai_platform_engineer |
| Enable (... menu, disabled provider) | Enables the provider again. | POST /v1/providers/{pid}/enable | tenant_admin, platform_admin, ai_platform_engineer |
| Disconnect (... menu) | After confirmation, deletes the configuration and the credentials. Models already imported stay in the registry, without a configured provider. | DELETE /v1/providers/{pid} | tenant_admin, platform_admin, ai_platform_engineer |
| Fetch again (models dialog) | Reads the model list of the provider again. | POST /v1/providers/{pid}/models/discover | tenant_admin, platform_admin, ai_platform_engineer |
| Import the selection (n) (models dialog) | Registers the selected new models with the chosen category. Toast N model(s) imported, M already registered. | POST /v1/models/import | tenant_admin, platform_admin, ai_platform_engineer |
| Add manually (provider without listing) | Opens the Models registry to type the model. | none | tenant_admin, platform_admin, ai_platform_engineer |
| Retry (error panel) | Reads the catalog again. | GET /v1/providers/catalog | LLM readers |
Roles
- Reading (
GET /v1/providers/catalog,GET /v1/providers,GET /v1/providers/{pid}): theREADroles ofservices/control-plane/src/eai/domains/llm/__init__.py, which are thellmReadersofportal/src/lib/kit.ts:tenant_admin,platform_admin,security_officer,finops,developer,auditor,viewer,agent,ai_platform_engineer,ai_governance_officer,support_engineer. - Administration (create, update, test, enable, discover, import, delete): the
ADMINrolestenant_admin,platform_admin,ai_platform_engineer(ROLES.llmAdmins). The ... menu of a card is shown only to these roles. - Disable:
ADMINplussecurity_officeron the server (ROLES.llmDisablers). A security officer uses the Enabled switch of the drawer, because the card menu is reserved to the administrators. platform_adminpasses every role check of the Control Plane. Only a platform administrator changes a provider defined at platform level.
Typical tasks
Connect a cloud provider
- Find the provider. Type its name in Search providers or set Hosting to Cloud, so that you work on the right card. Expected result: the card shows Not configured. If it fails: if every card shows Not connected, the catalog cannot be read; click Retry.
- Fill the configuration. Click Configure, keep or change Name, and type the credentials (for OpenAI,
api_key). The secrets are stored in the secret backend and never displayed again. Expected result: the form accepts the values. If it fails: a required field is marked Required. - Save. Click Save to create the provider. Expected result: toast Saved, the card moves to Configured providers with the badge Configured. If it fails: read the message in the drawer and see the Troubleshooting section below.
- Test the connection. Click Test connection, so that you know the credentials work before the models are used. Expected result: a JSON answer of the provider test. If it fails: fix the credentials, Save again, then test again.
Import the models of a provider
- Open the model list. On a configured card, open ... > Fetch models. The Control Plane reads the list from the provider API, it never invents one. Expected result: the dialog shows
N model(s) found, M already registered. If it fails: an error panel with Retry gives the cause (credentials refused, timeout, no address). - Choose the models. Tick the New rows you want, or the header box to select every new model shown, and set the Category of each row. Expected result: the footer shows
n selected. If it fails: a row marked Registered cannot be ticked, it is already in the registry. - Import. Click Import the selection (n). Expected result: toast
N model(s) imported, M already registered; the models appear in the Models registry. If it fails: "Some selected models are invalid: nothing was imported." lists the problems; fix the category and import again.
Cut a provider in an emergency
- Open the provider. Click Configure on the configured card. Expected result: the drawer shows the Enabled switch. If it fails: the switch only exists once the provider is saved.
- Switch it off. Turn Enabled off: every call to this provider stops at once (kill switch). Expected result: toast Saved, the card shows Disabled; the gateway answers "This provider is disabled (kill switch)." If it fails: a
forbiddenerror means your role cannot disable a provider. - Switch it on again. When the incident is closed, turn Enabled on or use ... > Enable. Expected result: the card shows Configured again. If it fails: enabling needs an administrator role, not
security_officer.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Error panel at the top, every card Not connected | GET /v1/providers/catalog failed, for example "The Control Plane API cannot be reached." | Check that the Control Plane runs and that NEXT_PUBLIC_EAI_API_URL is right, then Retry. |
"Missing required field <field> for this provider." (missing_credential_field, 422) | A required credential or one accepted credential set is missing. | Fill the field named in the message, or one of the Accepted credential sets. |
"Field <field> is not accepted by this provider." (unknown_credential_field) | The body holds a field the provider catalog does not declare. | Remove the field; only the fields of the drawer are accepted. |
"Remote providers must be reached over HTTPS." (tls_required, 422) | The base URL of a remote provider is not https. | Use an https:// address. |
"A provider with this name already exists." (provider_exists, 409) | Name is already used in the tenant. | Choose another name, or edit the existing provider. |
"Only a platform administrator can change platform level entries." (platform_only, 403) | The provider is defined at platform level. | Ask a platform_admin. |
| Test connection is greyed | The configuration is not saved yet. | Click Save first ("Save the configuration before testing the connection."). |
"The provider <host> refused the stored credentials (HTTP <status>)." (discovery_auth_failed, 502) | The provider rejects the key. | Type a valid secret in the drawer and Save. |
"The provider <host> did not answer within <n> seconds." or "could not be reached" (discovery_timeout, discovery_network_error, 502) | Network, proxy or egress rule. | Check the network path and the egress policy, then Fetch again. |
"This provider has no endpoint address: set it before fetching its models." (discovery_no_api_base, 422) | No base URL is configured. | Set Base URL in the drawer. |
"This provider is disabled (kill switch)." (provider_disabled, 409) on Fetch models | The provider is disabled. | Enable it first. |
"Some selected models are invalid: nothing was imported." (import_invalid, 422) or "Category <category> does not exist." (category_unknown, 422) | A selected row is invalid or its category is unknown. | Pick an existing category (see Models registry, Categories tab). |
forbidden (403) | The role of the user is not allowed on this route. | Ask a tenant_admin or an ai_platform_engineer. |