Repository navigation
feat(ui): configure OpenAI workload identity federation from the LLM Credentials and Add Model forms - #45528
Conversation
…Credentials and Add Model forms
|
…hen the proxy env provides it
| <ProviderSpecificFields | ||
| selectedProvider={selectedProvider} | ||
| hiddenFieldKeys={selection.authMethod === "federation" ? API_KEY_FIELDS : NO_HIDDEN_FIELDS} | ||
| fieldValidators={providerFieldValidators(selection)} |
There was a problem hiding this comment.
The PR describes pending QA, not completed results. Repository rules require live, unmocked UI testing against a real proxy. Supply that proof before merging
Rule Used: Flag if the PR has no proof of e2e testing (if e2e testing is applicable here. If it's like an AGENTS.md change or something then probably no need to have e2e test proof) that either doesn't exist, claims that the box that it was trying to run in doe... (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
…the credential to an API key
|
bugbot run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: API Base check misses leading whitespace
- The OpenAI federation API Base validator now rejects leading-whitespace URLs so a pasted padded value cannot save while the proxy skips keyless auth.
Or push these changes by commenting:
@cursor push 1f708f385b
Preview (1f708f385b)
diff --git a/ui/litellm-dashboard/src/components/model_add/openai_federation.test.ts b/ui/litellm-dashboard/src/components/model_add/openai_federation.test.ts
--- a/ui/litellm-dashboard/src/components/model_add/openai_federation.test.ts
+++ b/ui/litellm-dashboard/src/components/model_add/openai_federation.test.ts
@@ -30,6 +30,7 @@
"https://evilapi.openai.com/v1",
"https://openai.com/v1",
"https://gateway.example.com/v1",
+ " https://api.openai.com/v1",
"api.openai.com/v1",
"not a url",
])("refuses %s, which the proxy rejects for workload identity federation", (apiBase) => {
diff --git a/ui/litellm-dashboard/src/components/model_add/openai_federation.ts b/ui/litellm-dashboard/src/components/model_add/openai_federation.ts
--- a/ui/litellm-dashboard/src/components/model_add/openai_federation.ts
+++ b/ui/litellm-dashboard/src/components/model_add/openai_federation.ts
@@ -36,7 +36,7 @@
hostname === OPENAI_API_HOST || hostname.endsWith(`.${OPENAI_API_HOST}`);
const targetsOpenAIApi = (apiBase: string): boolean => {
- const url = URL.canParse(apiBase) ? new URL(apiBase) : null;
+ const url = apiBase === apiBase.trimStart() && URL.canParse(apiBase) ? new URL(apiBase) : null;
return url?.protocol === "https:" && isOpenAIApiHost(url.hostname);
};You can send follow-ups to the cloud agent here.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit b179751. Configure here.
| export const validateOpenAIFederationApiBase = (value: unknown): string | true => | ||
| typeof value !== "string" || isBlank(value) || targetsOpenAIApi(value) | ||
| ? true | ||
| : `Workload identity federation only reaches the OpenAI API. Enter https://${OPENAI_API_HOST}/v1 or a regional *.${OPENAI_API_HOST} URL, or leave this empty`; |
There was a problem hiding this comment.
API Base check misses leading whitespace
Low Severity
validateOpenAIFederationApiBase treats a leading-whitespace OpenAI URL as valid because the URL parser strips that space, but api_base is stored untrimmed. The proxy parses the raw string and then skips federation, so a pasted URL with a leading space saves while keyless auth never runs.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit b179751. Configure here.
There was a problem hiding this comment.
The proxy still federates here: _targets_openai_api(' https://api.openai.com/v1') returns True since urlparse strips leading spaces. Untrimmed API Base is pre-existing for every auth method



TLDR
Problem this solves:
How it solves it:
*.api.openai.comhostUser Flow
Before: a proxy admin cannot set up a keyless OpenAI credential from the Admin UI, because every OpenAI form asks for an API key
After: the admin picks workload identity federation once, saves a keyless OpenAI credential, and attaches it to a model
api_key, and the row shows a "Workload identity federation" badgehttps://api.openai.comorhttps://*.api.openai.comis refused under federation, while the API key method still accepts any basePre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
uv run pytest tests/unit/<your_test_file>.py -v. Leave the suites (make test-unit-*,make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Each leg ran from its own worktree against a fresh Postgres DB, with no
OPENAI_*env vars set and throwaway admin creds. The UI screenshots are the ones under User FlowBefore (145d382)
Add a keyless OpenAI credential
qa-openai-wif, and pick Provider OpenAIhttps://api.openai.com/v1), OpenAI Organization ID and OpenAI API Key, with no Authentication selector (Before 1)API Base check under federation
Attach the credential on Add Model
gpt-6.1-soland Public Model Nameqa-gpt-wifEdit a federated credential
After (b179751)
Add a keyless OpenAI credential
qa-openai-wif, and pick Provider OpenAIOPENAI_API_KEYis unset in its environment (After 2)idp_qa_placeholder,svc_qa_placeholderand a token file path, then click Add Credential. The toast reads "Credential added successfully" and the browser sent:qa-openai-wif | OpenAI | Workload identity federation(After 3)API Base check under federation
qa-openai-apibase, pick OpenAI and "Workload identity federation", set API Base tohttps://gateway.example.com/v1and Service Account ID tosvc_qa_placeholder, then click Add Credentialsk-not-realand click Add Credential. The toast reads "Credential added successfully" and the browser sent no federation fields:Attach the credential on Add Model
gpt-6.1-soland Public Model Nameqa-gpt-wifqa-openai-wifunder Existing Credentials and click Add Model. The toast reads "Model qa-gpt-wif created successfully" and the browser sent:Edit a federated credential
qa-openai-wif: it opens on "Workload identity federation" with the saved values and the token file masked as/p****enSurprises:
.env(leaves it alone)PASS
Type
New Feature
Caveats (if any)
Medium
OPENAI_API_KEYenv varLow
https://api.openai.com/v1prefilled, but the prefill is only sent once edited (pre-existing)Final Attestation
Note
Medium Risk
Changes credential form payloads and auth-method inference for stored secrets; mistakes could mis-label credentials or send wrong federation fields, but scope is UI-only with broad integration tests.
Overview
Adds OpenAI workload identity federation to the Admin UI by generalizing the Anthropic-only federation flow into shared
credential_federationhelpers that cover Anthropic and OpenAI.LLM Credentials and Add Model now show the Authentication selector (API key vs workload identity federation) for OpenAI. Federation hides the API key and collects OpenAI-specific fields (identity provider ID, service account ID, identity token file), with copy explaining federation applies when
OPENAI_API_KEYis unset on the proxy. Under federation, API Base is validated tohttps://api.openai.com(or regional*.api.openai.com); API key mode still allows custom bases.AnthropicFederationFieldsbecomesFederationFieldswith provider-specific sections; patch/create logic and federated detection move intocredential_federation. The credentials table’s federated badge usesinferAuthMethodso only credentials without a stored API key count as federated (including OpenAI). Add Model’s “Use workload identity federation” entry point is gated withfederatedProviderOf(OpenAI/Anthropic only, not OpenAI Compatible).Reviewed by Cursor Bugbot for commit b179751. Bugbot is set up for automated code reviews on this repo. Configure here.