fix(secrets): make apply idempotent and keep audit read-only

This commit is contained in:
joshavant
2026-02-25 22:19:21 -06:00
committed by Peter Steinberger
parent f413e314b9
commit ba2eb583c0
8 changed files with 218 additions and 72 deletions

View File

@@ -418,7 +418,8 @@ function loadAuthProfileStoreForAgent(
const mergedOAuth = mergeOAuthFileIntoStore(store);
// Keep external CLI credentials visible in runtime even during read-only loads.
const syncedCli = syncExternalCliCredentials(store);
const shouldWrite = !readOnly && (legacy !== null || mergedOAuth || syncedCli);
const forceReadOnly = process.env.OPENCLAW_AUTH_STORE_READONLY === "1";
const shouldWrite = !readOnly && !forceReadOnly && (legacy !== null || mergedOAuth || syncedCli);
if (shouldWrite) {
saveJsonFile(authPath, store);
}

View File

@@ -113,4 +113,49 @@ describe("discoverAuthStorage", () => {
await fs.rm(agentDir, { recursive: true, force: true });
}
});
it("preserves legacy auth.json when auth store is forced read-only", async () => {
const agentDir = await createAgentDir();
const previous = process.env.OPENCLAW_AUTH_STORE_READONLY;
process.env.OPENCLAW_AUTH_STORE_READONLY = "1";
try {
saveAuthProfileStore(
{
version: 1,
profiles: {
"openrouter:default": {
type: "api_key",
provider: "openrouter",
key: "sk-or-v1-runtime",
},
},
},
agentDir,
);
await fs.writeFile(
path.join(agentDir, "auth.json"),
JSON.stringify(
{
openrouter: { type: "api_key", key: "legacy-static-key" },
},
null,
2,
),
);
discoverAuthStorage(agentDir);
const parsed = JSON.parse(await fs.readFile(path.join(agentDir, "auth.json"), "utf8")) as {
[key: string]: unknown;
};
expect(parsed.openrouter).toMatchObject({ type: "api_key", key: "legacy-static-key" });
} finally {
if (previous === undefined) {
delete process.env.OPENCLAW_AUTH_STORE_READONLY;
} else {
process.env.OPENCLAW_AUTH_STORE_READONLY = previous;
}
await fs.rm(agentDir, { recursive: true, force: true });
}
});
});

View File

@@ -15,6 +15,9 @@ function isRecord(value: unknown): value is Record<string, unknown> {
}
function scrubLegacyStaticAuthJsonEntries(pathname: string): void {
if (process.env.OPENCLAW_AUTH_STORE_READONLY === "1") {
return;
}
if (!fs.existsSync(pathname)) {
return;
}