fix: stabilize secrets land + docs note (#26155) (thanks @joshavant)

This commit is contained in:
Peter Steinberger
2026-02-26 15:46:57 +01:00
parent 4380d74d49
commit 47fc6a0806
6 changed files with 39 additions and 19 deletions

View File

@@ -22,7 +22,6 @@ describe("secrets apply", () => {
authJsonPath = path.join(stateDir, "agents", "main", "agent", "auth.json");
envPath = path.join(stateDir, ".env");
env = {
...process.env,
OPENCLAW_STATE_DIR: stateDir,
OPENCLAW_CONFIG_PATH: configPath,
OPENAI_API_KEY: "sk-live-env",
@@ -170,6 +169,10 @@ describe("secrets apply", () => {
const first = await runSecretsApply({ plan, env, write: true });
expect(first.changed).toBe(true);
const configAfterFirst = await fs.readFile(configPath, "utf8");
const authStoreAfterFirst = await fs.readFile(authStorePath, "utf8");
const authJsonAfterFirst = await fs.readFile(authJsonPath, "utf8");
const envAfterFirst = await fs.readFile(envPath, "utf8");
// Second apply should be a true no-op and avoid file writes entirely.
await fs.chmod(configPath, 0o400);
@@ -177,8 +180,10 @@ describe("secrets apply", () => {
const second = await runSecretsApply({ plan, env, write: true });
expect(second.mode).toBe("write");
expect(second.changed).toBe(false);
expect(second.changedFiles).toEqual([]);
await expect(fs.readFile(configPath, "utf8")).resolves.toBe(configAfterFirst);
await expect(fs.readFile(authStorePath, "utf8")).resolves.toBe(authStoreAfterFirst);
await expect(fs.readFile(authJsonPath, "utf8")).resolves.toBe(authJsonAfterFirst);
await expect(fs.readFile(envPath, "utf8")).resolves.toBe(envAfterFirst);
});
it("applies targets safely when map keys contain dots", async () => {

View File

@@ -174,7 +174,9 @@ function scrubEnvRaw(
function collectAuthStorePaths(config: OpenClawConfig, stateDir: string): string[] {
const paths = new Set<string>();
paths.add(resolveUserPath(resolveAuthStorePath()));
// Scope default auth store discovery to the provided stateDir instead of
// ambient process env, so apply does not touch unrelated host-global stores.
paths.add(path.join(resolveUserPath(stateDir), "agents", "main", "agent", "auth-profiles.json"));
const agentsRoot = path.join(resolveUserPath(stateDir), "agents");
if (fs.existsSync(agentsRoot)) {
@@ -187,6 +189,12 @@ function collectAuthStorePaths(config: OpenClawConfig, stateDir: string): string
}
for (const agentId of listAgentIds(config)) {
if (agentId === "main") {
paths.add(
path.join(resolveUserPath(stateDir), "agents", "main", "agent", "auth-profiles.json"),
);
continue;
}
const agentDir = resolveAgentDir(config, agentId);
paths.add(resolveUserPath(resolveAuthStorePath(agentDir)));
}

View File

@@ -21,10 +21,12 @@ describe("secrets audit", () => {
authJsonPath = path.join(stateDir, "agents", "main", "agent", "auth.json");
envPath = path.join(stateDir, ".env");
env = {
...process.env,
OPENCLAW_STATE_DIR: stateDir,
OPENCLAW_CONFIG_PATH: configPath,
OPENAI_API_KEY: "env-openai-key",
...(typeof process.env.PATH === "string" && process.env.PATH.trim().length > 0
? { PATH: process.env.PATH }
: { PATH: "/usr/bin:/bin" }),
};
await fs.mkdir(path.dirname(configPath), { recursive: true });

View File

@@ -308,7 +308,9 @@ function collectConfigSecrets(params: {
function collectAuthStorePaths(config: OpenClawConfig, stateDir: string): string[] {
const paths = new Set<string>();
paths.add(resolveUserPath(resolveAuthStorePath()));
// Scope default auth store discovery to the provided stateDir instead of
// ambient process env, so audits do not include unrelated host-global stores.
paths.add(path.join(resolveUserPath(stateDir), "agents", "main", "agent", "auth-profiles.json"));
const agentsRoot = path.join(resolveUserPath(stateDir), "agents");
if (fs.existsSync(agentsRoot)) {
@@ -321,6 +323,12 @@ function collectAuthStorePaths(config: OpenClawConfig, stateDir: string): string
}
for (const agentId of listAgentIds(config)) {
if (agentId === "main") {
paths.add(
path.join(resolveUserPath(stateDir), "agents", "main", "agent", "auth-profiles.json"),
);
continue;
}
const agentDir = resolveAgentDir(config, agentId);
paths.add(resolveUserPath(resolveAuthStorePath(agentDir)));
}