CI(zizmor): Add per-repo zizmor security audit workflow#289
Open
ModeSevenIndustrialSolutions wants to merge 4 commits into
Open
CI(zizmor): Add per-repo zizmor security audit workflow#289ModeSevenIndustrialSolutions wants to merge 4 commits into
ModeSevenIndustrialSolutions wants to merge 4 commits into
Conversation
6b95c7e to
097a092
Compare
097a092 to
6534493
Compare
6534493 to
d0434bd
Compare
d0434bd to
585f856
Compare
585f856 to
1340d06
Compare
Adds the zizmor SARIF audit workflow developed in lfreleng-actions/.github to dependamerge so PRs and pushes get static analysis of every workflow file in this repository without relying on the org-wide required-workflow ruleset having been deployed. Self-contained behaviour (no further modifications needed): * harden-runner runs in audit-only mode, so the workflow does not depend on CONNECTION_WHITELIST being exposed and runs cleanly on fork PRs. * The Python summary parser is embedded as base64 in the workflow file itself; the upstream source script in lfreleng-actions/.github remains the source of truth for regenerating the embedded copy. * The zizmor version pin is vendored locally at .github/dependabot/zizmor-requirements.txt and maintained by Dependabot's pip ecosystem (added in dependabot.yml), so the pin is always reviewed via a PR in this repo and never silently changes between runs. Deployment mode is detected from GITHUB_WORKFLOW_REF so a PR that deletes both files from its head commit still fails closed. * Only secrets.GITHUB_TOKEN is required (always available). * SARIF upload to GitHub code scanning is gated to default-branch pushes, so PR runs never request the elevated security-events: write permission. PR runs are advisory only and write a markdown summary to the run page plus inline annotations on the changed lines. * The push trigger is scoped to the default branch (main) so feature-branch and tag pushes do not create no-op runs. Address Copilot review feedback: * Vendor zizmor pin file locally and add pip ecosystem entry to dependabot.yml so the version is reviewed and tracked in-repo, removing the supply-chain dependency on the unpinned upstream main branch fetch in normal operation. * Reword pin comment block to reflect per-repo context. * Reword embedded-parser maintenance comment to point at the upstream source of truth in lfreleng-actions/.github. * Scope the push trigger to the main branch instead of all refs. * Remove the stale reference to a README section that lived in the upstream .github org profile and does not exist in this repository. * Restructure the workflow header comment so it leads with the per-repo deployment context (which is what readers of this file primarily need to understand) and only mentions the upstream org-wide-ruleset deployment mode as background. * Detect per-repo deployment from GITHUB_WORKFLOW_REF rather than workspace file presence. A PR head cannot tamper with GITHUB_WORKFLOW_REF, so a PR that deletes both the workflow file and the pin file still fails closed instead of silently pivoting onto the mutable upstream main branch copy of the pin. * Correct the inaccurate comment on the download-artifact step that claimed the action would extract under a subdirectory named after the artifact without an explicit path. v4+ extracts a named single-artifact download to the workspace root by default; the explicit `path: '.'` is kept as a belt-and-braces hint of where the file lands. Validation: * actionlint clean. * yamllint clean. * All applicable pre-commit hooks pass on the changed files (yamllint, actionlint, GitHub Actions Workflow Linter, Validate GitHub Workflows, Check GitHub Workflows set timeout-minutes, reuse, codespell, ...). Co-authored-by: Claude <claude@anthropic.com> Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
1340d06 to
a083f0a
Compare
Add a 7-day cooldown window to each Dependabot updates entry so that new releases must age for a week before Dependabot opens a PR against them. This narrows the window in which a freshly-published-but-yet-to-be-discovered malicious release can land in this repository, and was flagged by the new zizmor dependabot-cooldown audit (workflow added in the previous commit). The 7-day default applies uniformly to: * github-actions * uv * pip (the zizmor pin file) Co-authored-by: Claude <claude@anthropic.com> Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
The autolabeler workflow uses pull_request_target so it can label PRs raised from forks. The new zizmor audit (added in this branch) flags pull_request_target generically under the dangerous-triggers rule, but the conditions the rule warns about cannot occur in this workflow: * The workflow performs no checkout of PR code (no actions/checkout step). * The workflow body is loaded from the base branch (pull_request_target semantics), not from the PR head. * The only step is release-drafter/autolabeler, pinned to a commit SHA, which is a pure GitHub-API consumer and never executes PR-provided content. * Permissions are scoped to pull-requests: write and contents: read; no secrets are exposed to the job. * The runner is hardened with an egress block. Suppress the audit on the pull_request_target trigger with an inline zizmor: ignore[dangerous-triggers] directive and add a header comment documenting the rationale, so future readers can see at a glance why the trigger is safe here and why the generic warning has been silenced. Co-authored-by: Claude <claude@anthropic.com> Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
Two hardening fixes surfaced by Copilot's review of the preceding three commits on this branch: * zizmor.yaml: strictly validate the extracted zizmor pin before passing it to `uvx --from`. Without this check, a PR that edits .github/dependabot/zizmor-requirements.txt could feed uvx an arbitrary pip requirement spec (VCS/URL refs, --index-url and other options, environment markers, multiple lines, or additional packages), resulting in untrusted code execution on the runner under the base repository's GITHUB_TOKEN. The check now accepts exactly one line matching ^zizmor==<version>$ where <version> is a conservative subset of PEP 440, and rejects anything else. * autolabeler.yaml: reword the safety rationale's permissions bullet to clarify that the default GITHUB_TOKEN is still passed to the job (with the scoped pull-requests: write and contents: read permissions) and only the absence of additional repository secrets is being claimed. The previous wording "no secrets are exposed" understated the privileges and could mislead future readers. Co-authored-by: Claude <claude@anthropic.com> Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
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.
Summary
Adds the zizmor SARIF audit workflow developed in
lfreleng-actions/.githubto
dependamergeso PRs and pushes get static securityanalysis of every workflow file in this repository — without
relying on the org-wide required-workflow ruleset having been
deployed at the org level.
The workflow file itself is functionally identical to upstream;
only the leading documentation block has been adapted to reflect
the per-repo deployment context (and to fix references to docs
that live upstream rather than in this repo).
What this PR adds
.github/workflows/zizmor.yaml.github/dependabot/zizmor-requirements.txtzizmor==1.24.1) consumed by the workflow at runtime.github/dependabot.yml(edit)pipecosystem entry targeting/.github/dependabot/so Dependabot keeps the pin file current via PRsThe pin file is vendored locally so the effective zizmor version
is reviewed via a PR in this repo and never silently changes
between runs. The upstream-fetch fallback in the workflow is
retained for drop-in compatibility with repositories that have
not vendored the pin, but is unreachable in this repo by design.
How I verified it runs cleanly here
The workflow is designed to be deployed at the org level as a
"required workflow" against many repositories that don't
contain the file or any companion scripts, so it is already
fully self-contained:
harden-runneregress policyauditmode — noCONNECTION_WHITELISTneeded → fork PRs work out of the boxlfreleng-actions/.github/.github/scripts/zizmor_summary.py.github/dependabot/zizmor-requirements.txt; Dependabot'spipecosystem keeps it currentsecrets.GITHUB_TOKEN(always available)contents: readonly — the elevatedsecurity-events: writejob is gated to default-branch pushes, so fork PRs never request it# Do NOT use tag object SHAsrule)push:triggerbranches: [main]so feature-branch and tag pushes do not create no-op runsBehaviour
embedded Python parser writes a markdown summary to the run
page, and findings appear as inline annotations on the
changed lines. Advisory only — never blocks merges.
artifact is uploaded to GitHub code scanning where alerts
are tracked.
Validation
All checks clean:
actionlint✅yamllint✅ (the upstream's slightly strictercomments: min-spaces-from-content: 1, level: errorrule isalready satisfied, so dependamerge's looser config is
guaranteed to pass)
(yamllint, actionlint, GitHub Actions Workflow Linter,
Validate GitHub Workflows, Check GitHub Workflows set
timeout-minutes, reuse, codespell, …)
Notes
will get a zizmor scan against its workflow files. Initial
runs may surface pre-existing findings; those are
informational and do not block merges (advisory only).