From 0f6f2482fda1b78592ffa536f71afba206ba54c1 Mon Sep 17 00:00:00 2001 From: joshavant <830519+joshavant@users.noreply.github.com> Date: Fri, 6 Mar 2026 20:09:19 -0600 Subject: [PATCH] Docs: align SecretRef model persistence semantics --- docs/cli/models.md | 1 + docs/cli/secrets.md | 3 ++- docs/concepts/models.md | 4 +++- docs/gateway/configuration-reference.md | 4 +++- docs/gateway/secrets.md | 3 ++- docs/reference/secretref-credential-surface.md | 1 + src/config/schema.help.ts | 2 +- 7 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/cli/models.md b/docs/cli/models.md index 700b562c353..68f5ac31def 100644 --- a/docs/cli/models.md +++ b/docs/cli/models.md @@ -38,6 +38,7 @@ Notes: - `models set ` accepts `provider/model` or an alias. - Model refs are parsed by splitting on the **first** `/`. If the model ID includes `/` (OpenRouter-style), include the provider prefix (example: `openrouter/moonshotai/kimi-k2`). - If you omit the provider, OpenClaw treats the input as an alias or a model for the **default provider** (only works when there is no `/` in the model ID). +- `models status` may show `marker()` in auth output for non-secret placeholders (for example `secretref-managed`, `minimax-oauth`, `qwen-oauth`, `ollama-local`) instead of masking them as secrets. ### `models status` diff --git a/docs/cli/secrets.md b/docs/cli/secrets.md index db5e9476c55..196f8e4878d 100644 --- a/docs/cli/secrets.md +++ b/docs/cli/secrets.md @@ -14,7 +14,7 @@ Use `openclaw secrets` to manage SecretRefs and keep the active runtime snapshot Command roles: - `reload`: gateway RPC (`secrets.reload`) that re-resolves refs and swaps runtime snapshot only on full success (no config writes). -- `audit`: read-only scan of configuration/auth stores and legacy residues for plaintext, unresolved refs, and precedence drift. +- `audit`: read-only scan of configuration/auth/generated-model stores and legacy residues for plaintext, unresolved refs, and precedence drift. - `configure`: interactive planner for provider setup, target mapping, and preflight (TTY required). - `apply`: execute a saved plan (`--dry-run` for validation only), then scrub targeted plaintext residues. @@ -62,6 +62,7 @@ Scan OpenClaw state for: - plaintext secret storage - unresolved refs - precedence drift (`auth-profiles.json` credentials shadowing `openclaw.json` refs) +- generated `agents/*/agent/models.json` residues (provider `apiKey` values and sensitive provider headers) - legacy residues (legacy auth store entries, OAuth reminders) ```bash diff --git a/docs/concepts/models.md b/docs/concepts/models.md index 981bd95086c..767e7309366 100644 --- a/docs/concepts/models.md +++ b/docs/concepts/models.md @@ -212,6 +212,8 @@ is merged by default unless `models.mode` is set to `replace`. Merge mode precedence for matching provider IDs: -- Non-empty `apiKey`/`baseUrl` already present in the agent `models.json` win. +- Non-empty `baseUrl` already present in the agent `models.json` wins. +- Non-empty `apiKey` in the agent `models.json` wins only when that provider is not SecretRef-managed in current config/auth-profile context. +- SecretRef-managed provider `apiKey` values are refreshed from source markers (`ENV_VAR_NAME` for env refs, `secretref-managed` for file/exec refs) instead of persisting resolved secrets. - Empty or missing agent `apiKey`/`baseUrl` fall back to config `models.providers`. - Other provider fields are refreshed from config and normalized catalog data. diff --git a/docs/gateway/configuration-reference.md b/docs/gateway/configuration-reference.md index 749b0d2b261..7388bdcafdd 100644 --- a/docs/gateway/configuration-reference.md +++ b/docs/gateway/configuration-reference.md @@ -2004,7 +2004,9 @@ OpenClaw uses the pi-coding-agent model catalog. Add custom providers via `model - Use `authHeader: true` + `headers` for custom auth needs. - Override agent config root with `OPENCLAW_AGENT_DIR` (or `PI_CODING_AGENT_DIR`). - Merge precedence for matching provider IDs: - - Non-empty agent `models.json` `apiKey`/`baseUrl` win. + - Non-empty agent `models.json` `baseUrl` values win. + - Non-empty agent `apiKey` values win only when that provider is not SecretRef-managed in current config/auth-profile context. + - SecretRef-managed provider `apiKey` values are refreshed from source markers (`ENV_VAR_NAME` for env refs, `secretref-managed` for file/exec refs) instead of persisting resolved secrets. - Empty or missing agent `apiKey`/`baseUrl` fall back to `models.providers` in config. - Matching model `contextWindow`/`maxTokens` use the higher value between explicit config and implicit catalog values. - Use `models.mode: "replace"` when you want config to fully rewrite `models.json`. diff --git a/docs/gateway/secrets.md b/docs/gateway/secrets.md index 2956d53133e..36dd89baa7f 100644 --- a/docs/gateway/secrets.md +++ b/docs/gateway/secrets.md @@ -372,7 +372,8 @@ openclaw secrets audit --check Findings include: -- plaintext values at rest (`openclaw.json`, `auth-profiles.json`, `.env`) +- plaintext values at rest (`openclaw.json`, `auth-profiles.json`, `.env`, and generated `agents/*/agent/models.json`) +- plaintext sensitive provider header residues in generated `models.json` entries - unresolved refs - precedence shadowing (`auth-profiles.json` taking priority over `openclaw.json` refs) - legacy residues (`auth.json`, OAuth reminders) diff --git a/docs/reference/secretref-credential-surface.md b/docs/reference/secretref-credential-surface.md index d3d56c032bc..dd1b5f1fd2f 100644 --- a/docs/reference/secretref-credential-surface.md +++ b/docs/reference/secretref-credential-surface.md @@ -99,6 +99,7 @@ Notes: - Auth-profile plan targets require `agentId`. - Plan entries target `profiles.*.key` / `profiles.*.token` and write sibling refs (`keyRef` / `tokenRef`). - Auth-profile refs are included in runtime resolution and audit coverage. +- For SecretRef-managed model providers, generated `agents/*/agent/models.json` entries persist non-secret markers (not resolved secret values) for `apiKey`/header surfaces. - For web search: - In explicit provider mode (`tools.web.search.provider` set), only the selected provider key is active. - In auto mode (`tools.web.search.provider` unset), `tools.web.search.apiKey` and provider-specific keys are active. diff --git a/src/config/schema.help.ts b/src/config/schema.help.ts index 0885aa0ea81..a69332acb13 100644 --- a/src/config/schema.help.ts +++ b/src/config/schema.help.ts @@ -688,7 +688,7 @@ export const FIELD_HELP: Record = { models: "Model catalog root for provider definitions, merge/replace behavior, and optional Bedrock discovery integration. Keep provider definitions explicit and validated before relying on production failover paths.", "models.mode": - 'Controls provider catalog behavior: "merge" keeps built-ins and overlays your custom providers, while "replace" uses only your configured providers. In "merge", matching provider IDs preserve non-empty agent models.json apiKey/baseUrl values only when the provider is not SecretRef-managed in current config/auth-profile context; SecretRef-managed providers refresh apiKey from current source markers while matching model contextWindow/maxTokens use the higher value between explicit and implicit entries.', + 'Controls provider catalog behavior: "merge" keeps built-ins and overlays your custom providers, while "replace" uses only your configured providers. In "merge", matching provider IDs preserve non-empty agent models.json baseUrl values, while apiKey values are preserved only when the provider is not SecretRef-managed in current config/auth-profile context; SecretRef-managed providers refresh apiKey from current source markers, and matching model contextWindow/maxTokens use the higher value between explicit and implicit entries.', "models.providers": "Provider map keyed by provider ID containing connection/auth settings and concrete model definitions. Use stable provider keys so references from agents and tooling remain portable across environments.", "models.providers.*.baseUrl":