fix: normalize auth profile inline secrets

This commit is contained in:
Peter Steinberger
2026-05-07 13:46:11 +01:00
parent 347b51be4b
commit 6ce1c98b61
3 changed files with 27 additions and 1 deletions

View File

@@ -167,6 +167,7 @@ Docs: https://docs.openclaw.ai
- OpenAI-compatible providers: honor `compat.supportsTools=false` by stripping tool payload fields before dispatch to chat-only endpoints. Fixes #74664.
- OpenAI-compatible providers: apply model-declared unsupported tool-schema keyword stripping to native OpenAI transport payloads and mark Fireworks Kimi K2.5 as rejecting `not` schemas. Fixes #75467.
- OpenAI-compatible gateway: sanitize images supplied through request content even when the prompt text contains no image file references, preventing oversized attachment payloads from bypassing the resize/drop pipeline. Fixes #59913.
- Auth profiles: normalize inline API keys and tokens loaded from `auth-profiles.json` so masked or rich-text credential artifacts fail as auth errors instead of crashing HTTP header construction. Fixes #77624.
- llm-task: resolve configured model aliases before embedded dispatch so `model="gemini-flash"` and other aliases route to the intended provider instead of the agent default. Fixes #54166.
- Media generation: resolve slash-containing model-only overrides like `fal-ai/flux/dev` through registered provider model metadata so FAL image/video models do not get misparsed as provider `fal-ai`. Fixes #77444.
- Commands/BTW: show the `/btw` missing-question usage placeholder with brackets so outbound channel sanitization keeps it visible. Fixes #62877. Thanks @RajvardhanPatil07.

View File

@@ -357,6 +357,30 @@ describe("resolveApiKeyForProfile secret refs", () => {
}
});
it("normalizes inline api_key values from auth profiles before header use", async () => {
const profileId = "openrouter:masked";
const result = await resolveApiKeyForProfile({
cfg: cfgFor(profileId, "openrouter", "api_key"),
store: {
version: 1,
profiles: {
[profileId]: {
type: "api_key",
provider: "openrouter",
key: " sk-or-\u202650ec ",
},
},
},
profileId,
});
expect(result).toEqual({
apiKey: "sk-or-50ec", // pragma: allowlist secret
provider: "openrouter",
email: undefined,
});
});
it("resolves token tokenRef from env", async () => {
const profileId = "github-copilot:default";
await withEnvVar("GITHUB_TOKEN", "gh-ref-token", async () => {

View File

@@ -14,6 +14,7 @@ import {
} from "../../plugins/provider-runtime.runtime.js";
import { resolveSecretRefString, type SecretRefResolveCache } from "../../secrets/resolve.js";
import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js";
import { normalizeOptionalSecretInput } from "../../utils/normalize-secret-input.js";
import { refreshChutesTokens } from "../chutes-oauth.js";
import { log } from "./constants.js";
import { resolveTokenExpiryState } from "./credential-state.js";
@@ -260,7 +261,7 @@ async function resolveProfileSecretString(params: {
}
}
return resolvedValue;
return normalizeOptionalSecretInput(resolvedValue);
}
export async function resolveApiKeyForProfile(