From 14897e8de73a0a95c5bcf172c652e560b28050cf Mon Sep 17 00:00:00 2001 From: joshavant <830519+joshavant@users.noreply.github.com> Date: Thu, 26 Feb 2026 00:54:14 -0600 Subject: [PATCH] docs(secrets): clarify partial migration guidance --- docs/cli/secrets.md | 8 ++++++++ docs/gateway/secrets.md | 6 ++++++ src/cli/secrets-cli.test.ts | 27 +++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/docs/cli/secrets.md b/docs/cli/secrets.md index a1a271c6ad1..397433aa68a 100644 --- a/docs/cli/secrets.md +++ b/docs/cli/secrets.md @@ -78,9 +78,15 @@ Flags: Notes: - `configure` targets secret-bearing fields in `openclaw.json`. +- Include all secret-bearing fields you intend to migrate (for example both `models.providers.*.apiKey` and `skills.entries.*.apiKey`) so audit can reach a clean state. - It performs preflight resolution before apply. - Apply path is one-way for migrated plaintext values. +Exec provider safety note: + +- Homebrew installs often expose symlinked binaries under `/opt/homebrew/bin/*`. +- Set `allowSymlinkCommand: true` only when needed for trusted package-manager paths, and pair it with `trustedDirs` (for example `["/opt/homebrew"]`). + ## Apply a saved plan Apply or preflight a plan generated previously: @@ -105,3 +111,5 @@ openclaw secrets audit --check openclaw secrets configure openclaw secrets audit --check ``` + +If `audit --check` still reports plaintext findings after a partial migration, verify you also migrated skill keys (`skills.entries.*.apiKey`) and any other reported target paths. diff --git a/docs/gateway/secrets.md b/docs/gateway/secrets.md index fef3ca339a2..6b44e23e899 100644 --- a/docs/gateway/secrets.md +++ b/docs/gateway/secrets.md @@ -128,6 +128,7 @@ Define providers under `secrets.providers`: - Runs configured absolute binary path, no shell. - By default, `command` must point to a regular file (not a symlink). - Set `allowSymlinkCommand: true` to allow symlink command paths (for example Homebrew shims). OpenClaw validates the resolved target path. +- Enable `allowSymlinkCommand` only when required for trusted package-manager paths, and pair it with `trustedDirs` (for example `["/opt/homebrew"]`). - When `trustedDirs` is set, checks apply to the resolved target path. - Supports timeout, no-output timeout, output byte limits, env allowlist, and trusted dirs. - Request payload (stdin): @@ -310,6 +311,11 @@ openclaw secrets configure openclaw secrets audit --check ``` +Migration completeness: + +- Include `skills.entries..apiKey` targets when those skills use API keys. +- If `audit --check` still reports plaintext findings after a partial migration, migrate the remaining reported paths and rerun audit. + ### `secrets audit` Findings include: diff --git a/src/cli/secrets-cli.test.ts b/src/cli/secrets-cli.test.ts index 6bf1364fa27..8f781e0d150 100644 --- a/src/cli/secrets-cli.test.ts +++ b/src/cli/secrets-cli.test.ts @@ -108,7 +108,18 @@ describe("secrets CLI", () => { protocolVersion: 1, generatedAt: "2026-02-26T00:00:00.000Z", generatedBy: "openclaw secrets configure", - targets: [], + targets: [ + { + type: "skills.entries.apiKey", + path: "skills.entries.qa-secret-test.apiKey", + pathSegments: ["skills", "entries", "qa-secret-test", "apiKey"], + ref: { + source: "env", + provider: "default", + id: "QA_SECRET_TEST_API_KEY", + }, + }, + ], }, preflight: { mode: "dry-run", @@ -129,7 +140,19 @@ describe("secrets CLI", () => { await createProgram().parseAsync(["secrets", "configure"], { from: "user" }); expect(runSecretsConfigureInteractive).toHaveBeenCalled(); - expect(runSecretsApply).toHaveBeenCalledWith(expect.objectContaining({ write: true })); + expect(runSecretsApply).toHaveBeenCalledWith( + expect.objectContaining({ + write: true, + plan: expect.objectContaining({ + targets: expect.arrayContaining([ + expect.objectContaining({ + type: "skills.entries.apiKey", + path: "skills.entries.qa-secret-test.apiKey", + }), + ]), + }), + }), + ); expect(runtimeLogs.at(-1)).toContain("Secrets applied"); }); });