fix(ci): harden release checks workflow inputs#66884
Conversation
Greptile SummaryThis PR hardens the reusable release-checks workflow by moving GitHub Actions expression interpolations ( The approach is correct: values in Confidence Score: 5/5Safe to merge — all changes are correct security hardening with no functional regressions. All findings are resolved or non-existent. The env-based variable passing correctly eliminates shell injection, the mode allowlist validation is sound, and the equivalence between No files require special attention. Reviews (1): Last reviewed commit: "fix(ci): harden release checks workflow ..." | Re-trigger Greptile |
|
Pushed follow-up commit What changed:
Why:
Validation:
|
zizmor v1.24.1 reports 8 template-injection findings across three workflow files where GitHub Actions ${{ ... }} expressions are interpolated directly into shell run: blocks. Applies the canonical fix pattern: hoist every dynamic value into a step-level env: block and reference it as a shell variable ("${VAR}") from the script.
Files changed:
- control-ui-locale-refresh.yml: move matrix.locale into env as LOCALE (1 site)
- docker-release.yml: hoist steps.tags.outputs.{value,slim} plus the four needs.build-{amd64,arm64}.outputs.{digest,slim-digest} values into env for both manifest-creation steps (6 sites)
- openclaw-npm-release.yml: hoist steps.publish_tarball.outputs.path into env as PUBLISH_TARBALL_PATH in the Publish step (1 site)
Verified locally with zizmor --persona regular on the three files: 'No findings to report. Good job!'. pnpm format:check and pnpm lint pass.
Refs #68428. Complements #66884, which covers the remaining 12 sites in openclaw-cross-os-release-checks-reusable.yml.
visionik
left a comment
There was a problem hiding this comment.
LGTM. Clean env-var substitution for every dynamic expression in the hardened steps, plus an inputs.mode allowlist check as a defensive bonus. zizmor verified clean locally. The one-line ci.yml install-deps change is orthogonal but trivial and in-scope. Together with #68431 this resolves all template-injection findings in #68428.
zizmor v1.24.1 reports 8 template-injection findings across three workflow files where GitHub Actions ${{ ... }} expressions are interpolated directly into shell run: blocks. Applies the canonical fix pattern: hoist every dynamic value into a step-level env: block and reference it as a shell variable ("${VAR}") from the script.
Files changed:
- control-ui-locale-refresh.yml: move matrix.locale into env as LOCALE (1 site)
- docker-release.yml: hoist steps.tags.outputs.{value,slim} plus the four needs.build-{amd64,arm64}.outputs.{digest,slim-digest} values into env for both manifest-creation steps (6 sites)
- openclaw-npm-release.yml: hoist steps.publish_tarball.outputs.path into env as PUBLISH_TARBALL_PATH in the Publish step (1 site)
Verified locally with zizmor --persona regular on the three files: 'No findings to report. Good job!'. pnpm format:check and pnpm lint pass.
Refs #68428. Complements #66884, which covers the remaining 12 sites in openclaw-cross-os-release-checks-reusable.yml.
|
Approved and ready to merge, but a rebase is needed — this PR is now showing mergeStateStatus: DIRTY / CONFLICTING against main after #68431 landed with the sibling template-injection fixes. The conflict should be trivial (both PRs only add step-level env: blocks around adjacent workflow steps). Could you rebase on origin/main and force-push? Happy to re-approve immediately after. |
|
Yup let me do that today.Kind regards,AlexOn 18 Apr 2026, at 08:06, Viz ***@***.***> wrote:Approved and ready to merge, but a rebase is needed — this PR is now showing mergeStateStatus: DIRTY / CONFLICTING against main after #68431 landed with the sibling template-injection fixes. The conflict should be trivial (both PRs only add step-level env: blocks around adjacent workflow steps). Could you rebase on origin/main and force-push? Happy to re-approve immediately after.
|
8093185 to
d8f3c50
Compare
|
Done, lmk if any edits are required. Kind regards,AlexOn 18 Apr 2026, at 12:17, Aleksandar Lomtatidze ***@***.***> wrote:Yup let me do that today.Kind regards,AlexOn 18 Apr 2026, at 08:06, Viz ***@***.***> wrote:Approved and ready to merge, but a rebase is needed — this PR is now showing mergeStateStatus: DIRTY / CONFLICTING against main after #68431 landed with the sibling template-injection fixes. The conflict should be trivial (both PRs only add step-level env: blocks around adjacent workflow steps). Could you rebase on origin/main and force-push? Happy to re-approve immediately after.
|
…law#68431) zizmor v1.24.1 reports 8 template-injection findings across three workflow files where GitHub Actions ${{ ... }} expressions are interpolated directly into shell run: blocks. Applies the canonical fix pattern: hoist every dynamic value into a step-level env: block and reference it as a shell variable ("${VAR}") from the script. Files changed: - control-ui-locale-refresh.yml: move matrix.locale into env as LOCALE (1 site) - docker-release.yml: hoist steps.tags.outputs.{value,slim} plus the four needs.build-{amd64,arm64}.outputs.{digest,slim-digest} values into env for both manifest-creation steps (6 sites) - openclaw-npm-release.yml: hoist steps.publish_tarball.outputs.path into env as PUBLISH_TARBALL_PATH in the Publish step (1 site) Verified locally with zizmor --persona regular on the three files: 'No findings to report. Good job!'. pnpm format:check and pnpm lint pass. Refs openclaw#68428. Complements openclaw#66884, which covers the remaining 12 sites in openclaw-cross-os-release-checks-reusable.yml.
…law#68431) zizmor v1.24.1 reports 8 template-injection findings across three workflow files where GitHub Actions ${{ ... }} expressions are interpolated directly into shell run: blocks. Applies the canonical fix pattern: hoist every dynamic value into a step-level env: block and reference it as a shell variable ("${VAR}") from the script. Files changed: - control-ui-locale-refresh.yml: move matrix.locale into env as LOCALE (1 site) - docker-release.yml: hoist steps.tags.outputs.{value,slim} plus the four needs.build-{amd64,arm64}.outputs.{digest,slim-digest} values into env for both manifest-creation steps (6 sites) - openclaw-npm-release.yml: hoist steps.publish_tarball.outputs.path into env as PUBLISH_TARBALL_PATH in the Publish step (1 site) Verified locally with zizmor --persona regular on the three files: 'No findings to report. Good job!'. pnpm format:check and pnpm lint pass. Refs openclaw#68428. Complements openclaw#66884, which covers the remaining 12 sites in openclaw-cross-os-release-checks-reusable.yml.
|
Security/CI hardening: this removes direct shell interpolation of reusable workflow inputs / matrix values and validates |
|
Verified the env-var handoff works end-to-end by triggering a https://github.com/openclaw/openclaw/actions/runs/24922625301 All steps up through the shell-invocation boundary passed cleanly — The Ready to land. |
d8f3c50 to
d4e0097
Compare
|
Merged via squash.
Thanks @alexlomt! |
Three external-contributor commits from the last day landed without CHANGELOG entries: - Alex Fries (#68286, @ajfonthemove): hybrid memory search component scores. Added under Unreleased > Changes (feat). - Charles Dusek (#51267, @cgdusek): malformed tool-result text-block guard. Added under Unreleased > Fixes. - Jerome Benoit (#59935, @jerome-benoit): Nix Home Manager daemon PATH support. Added under Unreleased > Fixes. Also drop a duplicate raw-subject changelog line for #66884 that restated alexlomt's already-formatted entry one line above.
Three external-contributor commits from the last day landed without CHANGELOG entries: - Alex Fries (openclaw#68286, @ajfonthemove): hybrid memory search component scores. Added under Unreleased > Changes (feat). - Charles Dusek (openclaw#51267, @cgdusek): malformed tool-result text-block guard. Added under Unreleased > Fixes. - Jerome Benoit (openclaw#59935, @jerome-benoit): Nix Home Manager daemon PATH support. Added under Unreleased > Fixes. Also drop a duplicate raw-subject changelog line for openclaw#66884 that restated alexlomt's already-formatted entry one line above.
- Remove duplicate openclaw#66884 alexlomt entry from top Unreleased > Fixes; the canonical entry already lives under 2026.4.24 (Unreleased) per Mason Huang's earlier 'move openclaw#66884 entry to 2026.4.24' commit. - Reflow the wrapped 3-line Tool Access bullet (openclaw#71405) onto a single line so it matches every other bullet in the section.
Three external-contributor commits from the last day landed without CHANGELOG entries: - Alex Fries (openclaw#68286, @ajfonthemove): hybrid memory search component scores. Added under Unreleased > Changes (feat). - Charles Dusek (openclaw#51267, @cgdusek): malformed tool-result text-block guard. Added under Unreleased > Fixes. - Jerome Benoit (openclaw#59935, @jerome-benoit): Nix Home Manager daemon PATH support. Added under Unreleased > Fixes. Also drop a duplicate raw-subject changelog line for openclaw#66884 that restated alexlomt's already-formatted entry one line above.
- Remove duplicate openclaw#66884 alexlomt entry from top Unreleased > Fixes; the canonical entry already lives under 2026.4.24 (Unreleased) per Mason Huang's earlier 'move openclaw#66884 entry to 2026.4.24' commit. - Reflow the wrapped 3-line Tool Access bullet (openclaw#71405) onto a single line so it matches every other bullet in the section.
Three external-contributor commits from the last day landed without CHANGELOG entries: - Alex Fries (openclaw#68286, @ajfonthemove): hybrid memory search component scores. Added under Unreleased > Changes (feat). - Charles Dusek (openclaw#51267, @cgdusek): malformed tool-result text-block guard. Added under Unreleased > Fixes. - Jerome Benoit (openclaw#59935, @jerome-benoit): Nix Home Manager daemon PATH support. Added under Unreleased > Fixes. Also drop a duplicate raw-subject changelog line for openclaw#66884 that restated alexlomt's already-formatted entry one line above.
- Remove duplicate openclaw#66884 alexlomt entry from top Unreleased > Fixes; the canonical entry already lives under 2026.4.24 (Unreleased) per Mason Huang's earlier 'move openclaw#66884 entry to 2026.4.24' commit. - Reflow the wrapped 3-line Tool Access bullet (openclaw#71405) onto a single line so it matches every other bullet in the section.
…law#68431) zizmor v1.24.1 reports 8 template-injection findings across three workflow files where GitHub Actions ${{ ... }} expressions are interpolated directly into shell run: blocks. Applies the canonical fix pattern: hoist every dynamic value into a step-level env: block and reference it as a shell variable ("${VAR}") from the script. Files changed: - control-ui-locale-refresh.yml: move matrix.locale into env as LOCALE (1 site) - docker-release.yml: hoist steps.tags.outputs.{value,slim} plus the four needs.build-{amd64,arm64}.outputs.{digest,slim-digest} values into env for both manifest-creation steps (6 sites) - openclaw-npm-release.yml: hoist steps.publish_tarball.outputs.path into env as PUBLISH_TARBALL_PATH in the Publish step (1 site) Verified locally with zizmor --persona regular on the three files: 'No findings to report. Good job!'. pnpm format:check and pnpm lint pass. Refs openclaw#68428. Complements openclaw#66884, which covers the remaining 12 sites in openclaw-cross-os-release-checks-reusable.yml.
…law#68431) zizmor v1.24.1 reports 8 template-injection findings across three workflow files where GitHub Actions ${{ ... }} expressions are interpolated directly into shell run: blocks. Applies the canonical fix pattern: hoist every dynamic value into a step-level env: block and reference it as a shell variable ("${VAR}") from the script. Files changed: - control-ui-locale-refresh.yml: move matrix.locale into env as LOCALE (1 site) - docker-release.yml: hoist steps.tags.outputs.{value,slim} plus the four needs.build-{amd64,arm64}.outputs.{digest,slim-digest} values into env for both manifest-creation steps (6 sites) - openclaw-npm-release.yml: hoist steps.publish_tarball.outputs.path into env as PUBLISH_TARBALL_PATH in the Publish step (1 site) Verified locally with zizmor --persona regular on the three files: 'No findings to report. Good job!'. pnpm format:check and pnpm lint pass. Refs openclaw#68428. Complements openclaw#66884, which covers the remaining 12 sites in openclaw-cross-os-release-checks-reusable.yml.
Three external-contributor commits from the last day landed without CHANGELOG entries: - Alex Fries (openclaw#68286, @ajfonthemove): hybrid memory search component scores. Added under Unreleased > Changes (feat). - Charles Dusek (openclaw#51267, @cgdusek): malformed tool-result text-block guard. Added under Unreleased > Fixes. - Jerome Benoit (openclaw#59935, @jerome-benoit): Nix Home Manager daemon PATH support. Added under Unreleased > Fixes. Also drop a duplicate raw-subject changelog line for openclaw#66884 that restated alexlomt's already-formatted entry one line above.
- Remove duplicate openclaw#66884 alexlomt entry from top Unreleased > Fixes; the canonical entry already lives under 2026.4.24 (Unreleased) per Mason Huang's earlier 'move openclaw#66884 entry to 2026.4.24' commit. - Reflow the wrapped 3-line Tool Access bullet (openclaw#71405) onto a single line so it matches every other bullet in the section.
…law#68431) zizmor v1.24.1 reports 8 template-injection findings across three workflow files where GitHub Actions ${{ ... }} expressions are interpolated directly into shell run: blocks. Applies the canonical fix pattern: hoist every dynamic value into a step-level env: block and reference it as a shell variable ("${VAR}") from the script. Files changed: - control-ui-locale-refresh.yml: move matrix.locale into env as LOCALE (1 site) - docker-release.yml: hoist steps.tags.outputs.{value,slim} plus the four needs.build-{amd64,arm64}.outputs.{digest,slim-digest} values into env for both manifest-creation steps (6 sites) - openclaw-npm-release.yml: hoist steps.publish_tarball.outputs.path into env as PUBLISH_TARBALL_PATH in the Publish step (1 site) Verified locally with zizmor --persona regular on the three files: 'No findings to report. Good job!'. pnpm format:check and pnpm lint pass. Refs openclaw#68428. Complements openclaw#66884, which covers the remaining 12 sites in openclaw-cross-os-release-checks-reusable.yml.
Three external-contributor commits from the last day landed without CHANGELOG entries: - Alex Fries (openclaw#68286, @ajfonthemove): hybrid memory search component scores. Added under Unreleased > Changes (feat). - Charles Dusek (openclaw#51267, @cgdusek): malformed tool-result text-block guard. Added under Unreleased > Fixes. - Jerome Benoit (openclaw#59935, @jerome-benoit): Nix Home Manager daemon PATH support. Added under Unreleased > Fixes. Also drop a duplicate raw-subject changelog line for openclaw#66884 that restated alexlomt's already-formatted entry one line above.
- Remove duplicate openclaw#66884 alexlomt entry from top Unreleased > Fixes; the canonical entry already lives under 2026.4.24 (Unreleased) per Mason Huang's earlier 'move openclaw#66884 entry to 2026.4.24' commit. - Reflow the wrapped 3-line Tool Access bullet (openclaw#71405) onto a single line so it matches every other bullet in the section.
Summary
openclaw-cross-os-release-checks-reusable.ymlinputs.modebefore expanding the runner matrixValidation
pre-commit run zizmor --files .github/workflows/openclaw-cross-os-release-checks-reusable.ymlContext
This is split out from #66735 because the failing
security-fastflag is unrelated to the daemon change and comes from a newer workflow on main.Why it matters
inputs.modefail before the runner matrix expands.Root Cause
run:block instead of being passed through quoted step environment variablesScope Boundary
Review Focus
.github/workflows/openclaw-cross-os-release-checks-reusable.ymlinputs.modeSecurity Impact
Yes, explain risk + mitigation: this narrows the shell execution surface by moving interpolated inputs into quoted env variables and validatinginputs.modebefore matrix expansion.Human Verification
zizmor) and repo commit-hook checksmodehandling