feat(secrets): finalize external secrets runtime and migration hardening

This commit is contained in:
joshavant
2026-02-24 19:34:29 -06:00
committed by Peter Steinberger
parent c5b89fbaea
commit 0e69660c41
22 changed files with 442 additions and 38 deletions

View File

@@ -47,4 +47,30 @@ describe("resolveModelAuthLabel", () => {
expect(label).toContain("token ref(env:GITHUB_TOKEN)");
});
it("masks short api-key profile values", () => {
const shortSecret = "abc123";
ensureAuthProfileStoreMock.mockReturnValue({
version: 1,
profiles: {
"openai:default": {
type: "api_key",
provider: "openai",
key: shortSecret,
},
},
} as never);
resolveAuthProfileOrderMock.mockReturnValue(["openai:default"]);
resolveAuthProfileDisplayLabelMock.mockReturnValue("openai:default");
const label = resolveModelAuthLabel({
provider: "openai",
cfg: {},
sessionEntry: { authProfileOverride: "openai:default" } as never,
});
expect(label).toContain("api-key");
expect(label).toContain("...");
expect(label).not.toContain(shortSecret);
});
});

View File

@@ -1,5 +1,6 @@
import type { OpenClawConfig } from "../config/config.js";
import type { SessionEntry } from "../config/sessions.js";
import { maskApiKey } from "../utils/mask-api-key.js";
import {
ensureAuthProfileStore,
resolveAuthProfileDisplayLabel,
@@ -13,10 +14,7 @@ function formatApiKeySnippet(apiKey: string): string {
if (!compact) {
return "unknown";
}
const edge = compact.length >= 12 ? 6 : 4;
const head = compact.slice(0, edge);
const tail = compact.slice(-edge);
return `${head}${tail}`;
return maskApiKey(compact);
}
function formatCredentialSnippet(params: {