Skip to content

fix(cli): skip gateway secrets.resolve for exec-backed command targets (#96653)#97460

Closed
ly-wang19 wants to merge 1 commit into
openclaw:mainfrom
ly-wang19:fix/exec-secret-ref-skip-96653
Closed

fix(cli): skip gateway secrets.resolve for exec-backed command targets (#96653)#97460
ly-wang19 wants to merge 1 commit into
openclaw:mainfrom
ly-wang19:fix/exec-secret-ref-skip-96653

Conversation

@ly-wang19

Copy link
Copy Markdown
Contributor

What Problem This Solves

On every agent reply turn, the gateway logs a noisy failure for secrets.resolve when a model-provider credential is an exec SecretRef, even though the gateway resolved that same secret fine at startup and the turn proceeds normally via local fallback (~1 line/turn; thousands over time):

[ws] ⇄ res ✗ secrets.resolve 6ms errorCode=UNAVAILABLE errorMessage=secrets.resolve failed conn=… id=…

Closes #96653.

Why This Change Was Made

The gateway's command-path resolver only reads pre-resolved values from the active snapshot; it cannot execute exec providers itself. For exec-backed agent-runtime/model-provider SecretRefs (e.g. models.providers.<name>.apiKey), the per-turn secrets.resolve RPC is therefore guaranteed to fail with UNAVAILABLE, after which the client falls back to local resolution and succeeds. The round-trip is pure overhead + noise, and the misleading ⚠️ UNAVAILABLE line drowns out real failures during debugging.

The existing skip in resolveCommandSecretRefsViaGateway only covers gateway-credential exec refs (gateway.auth.*/gateway.remote.*) because those would prevent gateway authentication. The agent-runtime/model-provider case has the same futility but was not covered.

User Impact

  • Operators using exec-backed model-provider credentials (e.g. models.providers.<name>.apiKey = { source: "exec", ... }) no longer get a misleading per-turn secrets.resolve UNAVAILABLE log entry on reply turns.
  • Reply-path secret resolution behavior is otherwise unchanged: the secret still resolves locally and the turn proceeds normally.
  • Diagnostics now include a single reply: skipped gateway secrets.resolve because command targets use exec SecretRefs at <paths> that the gateway cannot resolve from the active snapshot; resolving locally. line that makes the intent clear.

Evidence

  • pnpm test src/cli/command-secret-gateway.test.ts — 35/35 pass on local run (Node 22).
  • New regression test skips gateway resolution when agent-runtime targets use exec SecretRefs (#96653) asserts callGateway is NOT called, the exec provider resolves locally (exec-local-key), and the new skip diagnostic is emitted.
  • Updated keeps local exec SecretRef fallback enabled by default, skips local exec SecretRef fallback when the caller disallows exec providers, and can preserve unresolved SecretRefs when local exec fallback is disabled to reflect that the gateway RPC is now skipped; their core assertions (exec marker present/absent, resolved/unresolved state, local exec skip diagnostic) are preserved.
  • git diff --numstat: 40/-4 in command-secret-gateway.ts, 75/-9 in command-secret-gateway.test.ts. Non-test LOC growth ~36 from a new helper return field, a new skip branch, and inline comments explaining the gateway-snapshot invariant.

openclaw#96653)

Command-path resolution on the gateway only reads pre-resolved values
from the active snapshot; exec-backed agent-runtime/model-provider
SecretRefs surface as a per-turn UNAVAILABLE failure even though local
fallback succeeds. Extend the preflight classifier to surface active
exec-backed target paths and route them through the no-gateway path,
mirroring the existing skip for gateway-credential exec refs.

- collectConfiguredTargetRefPaths also exposes refsByPath
- classifyConfiguredTargetRefs returns activeExecBackedPaths
- resolveCommandSecretRefsViaGateway skips the RPC when exec-backed
  active targets are present and resolves locally instead

Updates three existing exec-ref tests now that the gateway round-trip
is correctly skipped, and adds a regression test for the issue's
model-provider exec-ref scenario.
@openclaw-barnacle openclaw-barnacle Bot added cli CLI command changes size: S labels Jun 28, 2026
@clawsweeper

clawsweeper Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Close: this PR targets a real SecretRef log-noise bug, but the same remaining work is already covered by the open, mergeable, proof-positive canonical PR with stronger active-target and no-local-exec safeguards.

Root-cause cluster
Relationship: superseded
Canonical: #96661
Summary: This PR is superseded by an open, proof-positive canonical PR for the same reply-path exec SecretRef gateway log-flood bug.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Canonical path: Close this PR and keep review focused on https://github.com/openclaw/openclaw/pull/96661; keep the linked issue open until that canonical fix lands or is rejected.

So I’m closing this here and keeping the remaining discussion on #96661.

Review details

Best possible solution:

Close this PR and keep review focused on https://github.com/openclaw/openclaw/pull/96661; keep the linked issue open until that canonical fix lands or is rejected.

Do we have a high-confidence way to reproduce the issue?

Yes at source level: queued replies call resolveCommandSecretRefsViaGateway, agent-runtime targets include models.providers.*.apiKey, and current main only pre-skips gateway credential exec refs. I did not run a live gateway reply turn in this read-only review.

Is this the best way to solve the issue?

No for this branch: it is a plausible fix, but https://github.com/openclaw/openclaw/pull/96661 is the better landing path because it preserves no-local-exec and inactive-target safeguards and includes real behavior proof.

Security review:

Security review cleared: No concrete supply-chain or security defect was found; the SecretRef execution-routing concern is captured as compatibility/auth-provider merge risk.

AGENTS.md: found and applied where relevant.

What I checked:

  • Repository policy read: Root AGENTS.md was read fully and applied; its review policy treats SecretRef/provider routing and fallback behavior as compatibility-sensitive. (AGENTS.md:1, 8d168c836af3)
  • Scoped gateway policy checked: Gateway scoped notes were checked because the review crosses the gateway secrets RPC boundary; no maintainer note matched this CLI-only PR beyond general gateway hot-path cautions. (src/gateway/AGENTS.md:1, 8d168c836af3)
  • Current reply entry point: Current main resolves queued replies through resolveCommandSecretRefsViaGateway with commandName: "reply" and the agent-runtime secret target set. (src/auto-reply/reply/agent-runner-utils.ts:77, 8d168c836af3)
  • Current model-provider target: Current main includes models.providers.*.apiKey in the static agent-runtime target ids, matching the linked report's exec-backed model-provider credential surface. (src/cli/command-secret-targets.ts:24, 8d168c836af3)
  • Current gateway fallback behavior: Current main only pre-skips gateway resolution for gateway credential exec refs; otherwise it attempts callGatewaySecretsResolve and falls back locally after a gateway failure. (src/cli/command-secret-gateway.ts:938, 8d168c836af3)
  • Generic gateway error payload: The gateway secrets.resolve handler logs detailed failures internally but responds with generic UNAVAILABLE / secrets.resolve failed, matching the noisy failure shape in the linked issue. (src/gateway/server-methods/secrets.ts:169, 8d168c836af3)

Likely related people:

  • giodl73-repo: Current local blame for the central resolver, reply utility, and gateway secrets handler lines points to the merged external-plugin catalog refactor in this shallow checkout. (role: current line blame / recent refactor author; confidence: medium; commits: 4010b81a77f4; files: src/cli/command-secret-gateway.ts, src/cli/command-secret-targets.ts, src/auto-reply/reply/agent-runner-utils.ts)
  • steipete: Live path history shows repeated recent work on command-secret gateway resolution, scoped web command SecretRefs, and gateway secrets error handling. (role: recent command-secret and gateway secrets contributor; confidence: high; commits: 9e67f53b913a, d66fe50a10e0, e3a248585e66; files: src/cli/command-secret-gateway.ts, src/cli/command-secret-targets.ts, src/gateway/server-methods/secrets.ts)
  • joshavant: History ties broad SecretRef credential coverage and doctor/channel SecretRef preview work to the same command-secret resolution boundary. (role: SecretRef coverage and doctor-preview contributor; confidence: medium; commits: 806803b7efe2, d9124c970085, 37169697d767; files: src/cli/command-secret-gateway.ts, src/cli/command-secret-gateway.test.ts, src/cli/command-secret-targets.ts)
  • vincentkoc: Recent path history shows several queued reply runtime changes, making this person relevant if maintainers need reply-path validation beyond the shared CLI resolver. (role: recent reply-runtime contributor; confidence: medium; commits: 190ca52882bf, efd3172662ce, 5abf4ce2e2a3; files: src/auto-reply/reply/agent-runner-utils.ts)

Codex review notes: model internal, reasoning high; reviewed against 8d168c836af3.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jun 28, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 28, 2026
@ly-wang19 ly-wang19 closed this Jun 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: reply-path secrets.resolve floods gateway log with UNAVAILABLE for model-provider exec SecretRefs (degrades correctly, ~1 line/turn)

1 participant