Harden CI: read the ref from the runner env instead of expanding it into run: blocks - #5295
Merged
Merged
Conversation
A `${{ ... }}` expression inside a `run:` block is substituted into the
script before the shell parses it, so the value becomes shell source text
rather than data. desktop-artifacts.yml had four such expansions of
`github.ref_name` / `github.ref_type` across three steps.
This file already established the right pattern: the macOS and Linux
"Stamp bundle version" steps read `${GITHUB_REF_TYPE}` and
`${GITHUB_REF_NAME}` straight from the runner environment, with no
template expansion at all. The Windows job and the two signing gates were
the outliers. They now follow the same convention:
- macOS "Require signing on release tags": ${GITHUB_REF_NAME} in the
::error:: message.
- Windows "Require signing on release tags": likewise.
- Windows "Stamp bundle version" (pwsh): $Env:GITHUB_REF_NAME and
$Env:GITHUB_REF_TYPE, matching what its macOS and Linux siblings do.
GITHUB_REF_NAME and GITHUB_REF_TYPE are default Actions environment
variables present on every runner, so no `env:` block is needed and the
resolved values are identical.
Verified: zizmor 1.29.0 over .github/workflows/, main vs branch --
High-severity template-injection 4 -> 0, every other rule count unchanged
(unpinned-uses 30, artipacked 48/13, informational template-injection 29,
adhoc-packages 5, misfeature 3, dangerous-triggers 2, excessive-permissions
2, cache-poisoning 1). actionlint 1.7.7 exits 0 on both. All 34 workflow
files re-parsed as YAML; scripts/check_action_refs.py passes.
Six lines, all inside `run:` blocks. No permission, trigger, step or
action version changed -- desktop-artifacts keeps the write scopes it
needs to publish releases.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UYeD7Hs9edpH86kLibimqS
✅ Drift Bot (ClawMetry): no drift detectedDrift Bot analyzed the changed files against this project's blueprints and requirements and found no drift. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A
${{ ... }}expression inside arun:block is substituted into the script before the shell parses it, so whatever it holds becomes shell source text rather than a value.desktop-artifacts.ymlhad four such expansions ofgithub.ref_name/github.ref_type, across three steps. All four now read the value from the runner environment instead.${{ github.ref_name }}${GITHUB_REF_NAME}${{ github.ref_name }}${GITHUB_REF_NAME}${{ github.ref_name }}$Env:GITHUB_REF_NAME${{ github.ref_type }}$Env:GITHUB_REF_TYPEWhy this shape
This file had already established the right pattern — it just wasn't applied consistently. The macOS and Linux
Stamp bundle versionsteps read${GITHUB_REF_TYPE}and${GITHUB_REF_NAME}straight from the runner environment, with no template expansion at all. The Windows job and the two signing gates were the outliers, so this PR converges them on the convention already in the file rather than introducing newenv:bindings.GITHUB_REF_NAMEandGITHUB_REF_TYPEare default GitHub Actions environment variables, set on every runner including Windows. So noenv:block is required, and the resolved values are identical to what the expansions produced.The
if:conditions at lines 49, 276 and 679 usegithub.refin a conditional, not arun:block. Those are evaluated by the Actions expression engine and never reach a shell, so they are correct as-is and are untouched.Verification
.github/workflows/,mainvs branch, same binary and invocation:template-injection: 4 → 0unpinned-uses30,artipacked48 Medium / 13 Low, informationaltemplate-injection29,adhoc-packages5,misfeature3,dangerous-triggers2,excessive-permissions2,cache-poisoning1, Mediumtemplate-injection1. Total 140 → 136.run:block): exit 0 on bothmainand this branch.yaml.safe_loadafter the edit.python3 scripts/check_action_refs.pypasses (23 distinct action references).Scope / safety
run:block.permissions:block is touched.desktop-artifactsis one of the workflows that needs write scopes to publish release assets, and it keeps exactly the scopes it has today — this PR is expression-binding only, one concern.Coordination
No overlap with open hardening PR #5294, which pins actions across 11 other workflow files and does not touch
desktop-artifacts.yml. This file'suses:references are already SHA-pinned from an earlier batch.Not in this PR
Left for their own batches, one concern per PR:
unpinned-uses(30) — covered by Harden CI: pin the remaining first-party actions to commit SHAs #5294, currently open and green.artipacked(61) —actions/checkoutwithoutpersist-credentials: false.template-injection(29) — these expandsteps.*.outputs.*, an internally-derived value, and are a separate concern from ref-derived input.excessive-permissions(2),dangerous-triggers(2),cache-poisoning(1)..github/is exempt from the product-record gate, so no Factory record is cited.Generated by Claude Code