Skip to content

fix(compute): refuse a padded plugin secret input reference no binding sets - #4315

Merged
freeqaz merged 1 commit into
mainfrom
bughunt-1031i
Oct 31, 2026
Merged

freeqaz merged 1 commit into
mainfrom
bughunt-1031i

Conversation

@freeqaz

@freeqaz freeqaz commented Oct 31, 2026

Copy link
Copy Markdown
Collaborator

Problem

OpenClaw reads a whole ${NAME} at a plugin secret input as an environment SecretRef after it trims the value (parseEnvTemplateSecretRef at the pinned commit). The deployment admission rule from #4309/#4310 (requirePluginSecretInputs) matched the untrimmed value, so a padded reference such as " ${SEARCH_HEADER} " at plugins.entries.google.config.webSearch.headers.<name> passed admission with SEARCH_HEADER unbound. The Gateway then exited at every start ("required secrets are unavailable") and the deployment waited for its convergence deadline, the crash loop #4309 set out to refuse.

Configuration save accepts such a value at a header whose name marks no credential (for example X-Goog-User-Project under Google webSearch.headers, or a Codex appServer.headers entry). The $NAME shorthand was already trimmed, so only the ${NAME} form slipped through.

Change

  • secretInputVariable in apps/controller/src/drivers/compute/kubernetes/configuration-rules.ts trims the value before wholeEnvironmentReferenceName, as OpenClaw does. All topologies share this rule.
  • References inside other text, fallbacks, and the other exceptions are unchanged.

Verification

  • Runtime image probe (a remote test VM, the runtime image built from current main, embedded configuration): google webSearch.headers.X-Key: " ${SEARCH_HEADER} " with the variable unset exits at about 29 s with "Startup failed: required secrets are unavailable". In the same probe, "Bearer ${SEARCH_HEADER}" and an unset Google webSearch.apiKey (a capability owner) both serve, which confirms those exclusions.
  • Conformance (tests/conformance/kubernetes-compute.test.mjs): new row " ${RELAY_TOKEN}\n" in the unbound-name loop.
  • Integration (tests/integration/configuration-controller.test.mjs): the padded X-Goog-User-Project header saves with 200, and deployment now returns 400 with the unbound-binding refusal. On main the deployment returned 202.
  • Both new rows fail on main's product code and pass on this head.
  • Three mutants (no trim, trimStart, trimEnd) are each killed by both tests.
  • Pins: 20/20 at 2 CPUs for each touched test.
  • Typecheck, eslint and prettier pass on the touched files.

Risks

Low. The change can only refuse more: a padded whole ${NAME} that no binding, launch hook, Compute or the image sets. That value already stopped the Gateway, and the refusal names the binding to add.

…g sets

OpenClaw trims a secret-input value before it reads a whole ${NAME} as an
environment SecretRef (parseEnvTemplateSecretRef), so ' ${NAME} ' with
NAME unset stops the Gateway at every start ('required secrets are
unavailable'). Deployment admission compared the untrimmed value and let it
through; Configuration save accepts it at a header whose name marks no
credential. Trim before matching, as the $NAME shorthand already does
(finding 3046).
@freeqaz
freeqaz requested a review from a team as a code owner October 31, 2026 14:07
@clawsweeper

clawsweeper Bot commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@freeqaz
freeqaz merged commit 826554d into main Oct 31, 2026
38 checks passed
@freeqaz
freeqaz deleted the bughunt-1031i branch October 31, 2026 14:17
freeqaz added a commit that referenced this pull request Oct 31, 2026
…ts (#4317)

Test code only. Folds the plugin secret input admission cases added by #4308, #4309, #4310 and #4315 into shared helpers and one topology table; no assertion is dropped, and 26 mutants of the admission rule are killed exactly as before.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant