feat(ui/mcp): clarify base64 format for BYOK Basic auth keys
Some checks failed
LiteLLM Rust / rustfmt, clippy, test (push) Has been cancelled

The Basic auth hint described the wire header (Authorization: Basic {key})
but did not tell users the value must be a base64-encoded user:password
string, so a user pasting a raw token in the Connect modal could produce a
header the upstream silently rejects. Add a Basic-only note to the BYOK hint.
This commit is contained in:
Tin Chi Lo 2026-06-23 22:51:25 -07:00
parent 705a4a8e33
commit ca71c6166d
2 changed files with 30 additions and 0 deletions

View file

@ -20,6 +20,7 @@ const ByokFields: React.FC<ByokFieldsProps> = ({ form }) => {
const isByok = Form.useWatch("is_byok", form);
const authType = Form.useWatch("auth_type", form) as string | undefined;
const formatHint = authType ? BYOK_AUTH_FORMAT_HINT[authType] : undefined;
const isBasicAuth = authType === AUTH_TYPE.BASIC;
return (
<>
@ -45,6 +46,14 @@ const ByokFields: React.FC<ByokFieldsProps> = ({ form }) => {
<InfoCircleOutlined className="mt-0.5 flex-shrink-0" />
<span>
User keys will be sent as: <code className="font-mono bg-blue-100 px-1 rounded">{formatHint}</code>
{isBasicAuth && (
<>
{" "}
Each user&apos;s key must be a base64-encoded{" "}
<code className="font-mono bg-blue-100 px-1 rounded">user:password</code> string, or a raw token if
the server accepts one.
</>
)}
</span>
</div>
)}

View file

@ -868,6 +868,27 @@ describe("CreateMCPServer BYOK toggle", () => {
expect(payload.credentials).toBeUndefined();
});
it("shows a base64 clarification in the BYOK hint for Basic auth only", async () => {
await selectHttpTransport();
await selectAntOption("Authentication", "Basic Auth");
await waitFor(() => expect(screen.getByText(BYOK_LABEL)).toBeInTheDocument());
await act(async () => {
fireEvent.click(getByokSwitch()!);
});
await waitFor(() => expect(screen.getByText(/base64-encoded/)).toBeInTheDocument());
cleanup();
await selectHttpTransport();
await selectAntOption("Authentication", "Bearer Token");
await waitFor(() => expect(screen.getByText(BYOK_LABEL)).toBeInTheDocument());
await act(async () => {
fireEvent.click(getByokSwitch()!);
});
await waitFor(() => expect(screen.getByText("Access Description")).toBeInTheDocument());
expect(screen.queryByText(/base64-encoded/)).not.toBeInTheDocument();
});
it("blocks submit when the API Key Help URL is not a valid URL", async () => {
await selectHttpTransport();