fix(ci): GitHub Actions security hardening#703
Open
stevebeattie wants to merge 6 commits into
Open
Conversation
Route ${{ inputs.* }} and ${{ steps.*.outputs.* }} values used inside
composite-action and reusable-workflow run: blocks through env: aliases
and reference them as double-quoted shell variables, closing the
template-injection taint path flagged by zizmor in .ci-build.yml and the
build-and-publish-{osv,secdb,yaml} composite actions.
Refs: PSEC-923
Generated-By: claude-guard chain a10a64a4173b72462b30c8b026a89893
Skills-Applied: template-injection
Skills-Sha: d1a637a7f238e262da2698fbdbfd84d56a645e4cf4c63cdfcb3347544f7f2967
Image-Sha: sha256:3b5a6a2d7ac0edcd1da9473f63aef0922371ae7094a2583f4faa5bdef838bc1f
Both actions/checkout steps in the ci-build reusable workflow omitted persist-credentials, leaving the GITHUB_TOKEN in the local git config for every subsequent step (zizmor artipacked). No downstream step relies on the git credential store: git operations are limited to a read-only 'git config --global --add safe.directory' and the PR-comment step passes its token explicitly, so persist-credentials: false is the correct fix per the artipacked decision tree. Refs: PSEC-923 Generated-By: claude-guard chain a10a64a4173b72462b30c8b026a89893 Skills-Applied: artipacked Skills-Sha: d1a637a7f238e262da2698fbdbfd84d56a645e4cf4c63cdfcb3347544f7f2967 Image-Sha: sha256:3b5a6a2d7ac0edcd1da9473f63aef0922371ae7094a2583f4faa5bdef838bc1f
Extend .github/zizmor.yml to disable the cosmetic pedantic-only rules anonymous-definition and concurrency-limits (campaign convention; existing dependabot-cooldown config days:3 preserved). Companion fix for the dependabot-cooldown finding: add cooldown.default-days: 3 to the github-actions ecosystem in .github/dependabot.yml so the configured threshold and the actual cooldown agree. Refs: PSEC-923 Generated-By: claude-guard chain a10a64a4173b72462b30c8b026a89893 Skills-Applied: zizmor-config Skills-Sha: d1a637a7f238e262da2698fbdbfd84d56a645e4cf4c63cdfcb3347544f7f2967 Image-Sha: sha256:3b5a6a2d7ac0edcd1da9473f63aef0922371ae7094a2583f4faa5bdef838bc1f
The `enable_acl_public_read` input is an optional flag — empty, or a single
token like `--canned-acl=publicRead`. It was interpolated unquoted so it would
vanish when empty, which trips SC2086 (and quoting it would pass a spurious
empty argument when unset). Build it as a bash array instead: `"${acl_args[@]}"`
expands to zero args when empty and one quoted arg when set — shellcheck-clean
and no reliance on unquoted-empty behavior. Applied to build-and-publish-osv and
build-and-publish-secdb.
Generated-By: claude-guard
The install step left `$TMP` (a mktemp -d path) unquoted in `docker run -v
$TMP:/out` and the `$GITHUB_PATH` runner sink unquoted in `echo "$TMP" >>
$GITHUB_PATH`. Both are safe single-value paths; quote them ("$TMP", "$GITHUB_PATH")
to satisfy SC2086 and guard against a path containing spaces.
Generated-By: claude-guard
… ignore) zizmor flags `echo "$TMP" >> "$GITHUB_PATH"` as github-env (dangerous env-file write). Here it is a false positive: $TMP is a `mktemp -d` path (runner-owned, mode 0700) that holds only wolfictl copied from the pinned wolfi-dev/sdk image — no attacker-controlled value reaches $GITHUB_PATH, and the temp dir added to PATH is not attacker-writable. Add a scoped `# zizmor: ignore[github-env]` with the justification inline, rather than leave a recurring HIGH on a reviewed-benign line. Generated-By: claude-guard
egibs
approved these changes
Jul 2, 2026
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.
This PR applies GitHub Actions hardening fixes, surfaced by static analysis
(zizmor). The repo ships composite actions, so the sweep covered the
action.yml/action.yamlfiles as well as.github/workflows/.What this changes
run:blocks are moved into
env:and referenced as quoted shell variables.persist-credentials: falseon checkout steps that don't push back.dependabot-cooldownthreshold.build-and-publish-osv,build-and-publish-secdb). Theenable_acl_public_readinput is optional —empty, or a single token like
--canned-acl=publicRead. It was interpolatedunquoted so it would vanish when empty; that's fragile (a quoted-empty value
would pass a spurious empty argument). Build it as a bash array —
"${acl_args[@]}"expands to zero args when empty and one quoted arg whenset — which is robust and lint-clean.
install-wolfictl. Quote$TMPand$GITHUB_PATH(both safesingle-value paths —
$TMPfrommktemp -d,$GITHUB_PATHthe runner sink),and annotate the
$GITHUB_PATHwrite with a scoped# zizmor: ignore[github-env]plus rationale: the value written is a trusted
mktemp -dpath holding onlywolfictlfrom the pinned sdk image, so no attacker-controlled value reachesthe environment file.
Test plan
zizmor .github/(plus the compositeaction.ymlfiles) — clean after thesechanges for the auto-fixable rule classes.
actionlint— workflows still parse with no errors.Refs: PSEC-923