Skip to content

ci: add zizmor, fix found issues - #5387

Open
kolyshkin wants to merge 7 commits into
opencontainers:mainfrom
kolyshkin:add-zizmor
Open

ci: add zizmor, fix found issues#5387
kolyshkin wants to merge 7 commits into
opencontainers:mainfrom
kolyshkin:add-zizmor

Conversation

@kolyshkin

@kolyshkin kolyshkin commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Add a zizmor job to CI, and fix everything it finds (including a few
--persona=pedantic findings). See individual commits for details.

  • ci: pin actions to commit hashes -- version tags are mutable, hashes are
    not; dependabot already knows how to bump them.
  • ci: harden workflows as suggested by zizmor -- persist-credentials: false
    for actions/checkout. The remaining findings are all cache-poisoning, ignored
    via .github/zizmor.yml, which explains why they do not apply to us.
  • dependabot: add cooldown.
  • ci: add zizmor job -- pinned version, inline annotations only (so the job
    stays at contents: read).
  • ci: narrow down scheduled.yml permissions -- move actions: write to the
    only job that needs it.
  • ci: add concurrency limits -- cancel superseded PR runs; keyed by PR number,
    so pushes to main/release-/v tags are never cancelled. scheduled.yml does not
    cancel in progress runs, so a run is never killed halfway through its matrix.
  • ci: fix up job permissions -- lint does not need pull-requests: read;
    document why the commit job does.

@kolyshkin

Copy link
Copy Markdown
Contributor Author

Rebased; no longer a draft; PTAL @opencontainers/runc-maintainers

@kolyshkin
kolyshkin requested review from lifubang and rata and removed request for lifubang August 19, 2026 09:31
Comment thread .github/workflows/validate.yml Outdated
@kolyshkin kolyshkin added this to the 1.6.0 milestone Aug 25, 2026
@kolyshkin kolyshkin added the backport/1.5-todo A PR in main branch which needs to be backported to release-1.5 label Aug 25, 2026

@thaJeztah thaJeztah left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall looks good; left two questions

Comment thread .github/workflows/test.yml Outdated
Comment thread .github/workflows/scheduled.yml Outdated
Comment thread .github/workflows/scheduled.yml

- uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2
with:
version: 1.29.0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if we should omit the version here; or at least, it's easier to forget updating (dependabot can take care of updating the action, but probably won't update this version)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I mean, without the version a new zizmor will break CI. We already pin golangci-lint for the same reason.

Or should we treat golangci-lint and zizmor differently?

kolyshkin and others added 7 commits August 27, 2026 22:11
A version tag (even a "full" one like v7.0.1) is mutable: whoever
controls the action's repository can move it to point to any other
commit. Pinning to a full commit hash is the only way to get the exact
same action code on every run.

Found by zizmor's unpinned-uses audit. Dependabot is already enabled for
the github-actions ecosystem and knows how to update hash pins together
with their version comments, so this should not add maintenance burden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Set persist-credentials: false for actions/checkout, as applied by
"zizmor --fix". By default checkout leaves the credentials it used in
.git/config, where any later step (or anything that archives the
workspace) can pick them up. Nothing here pushes back to the repository,
so they are not needed.

The remaining findings are all cache-poisoning, and are ignored via
.github/zizmor.yml, which explains why they do not apply to us.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
As recommended by zizmor.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
zizmor is a static analysis tool for GitHub Actions workflows, focused
on security issues rather than correctness (which is what the separate
actionlint job is for).

Use the official action, which runs zizmor from a digest-pinned
container image. A few non-default settings:

 - version: pin it, so a new zizmor release adding new audits does not
   suddenly fail CI on an unrelated pull request. Bumping it is then a
   deliberate (and dependabot-able) change.

 - advanced-security: false + annotations: true. The default uploads
   SARIF to the repository's security tab, which needs the job to have
   security-events: write. Inline annotations are enough for us and
   keep the workflow at contents: read.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Move "actions: write" from the workflow level to the only job that needs
it, so a job added later won't silently inherit it.

Found by zizmor's excessive-permissions audit (--persona=pedantic).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Cancel CI runs that are already superseded, rather than letting them run
to completion and waste runner time. This is most of what our CI queue
is spent on when a pull request is force-pushed a few times in a row.

For the three workflows that run on pull requests, the concurrency group
is keyed by PR number, so only runs of the same pull request cancel each
other. For anything else -- in particular pushes to main, to release-*,
and to a v* tag, the latter also producing the release binaries -- there
is no PR number, so the group falls back to the unique run_id and no run
is ever cancelled. Keying by github.head_ref instead would be wrong, as
two pull requests from different forks can use the same branch name.

scheduled.yml only triggers other workflows, so a single group for the
whole workflow is enough there. It does not cancel in progress runs,
though: a workflow_dispatch arriving while a scheduled run is halfway
through its matrix would leave some of the branches untriggered.

Found by zizmor's concurrency-limits audit (--persona=pedantic).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
The lint job does not need pull-requests: read: golangci-lint-action only
uses it for its only-new-issues option, which we do not set.

The lint-extra step does its own "new code only" filtering with
--new-from-rev=HEAD~1, which is plain git against the fetch-depth: 2
checkout, and the PR annotations come from checks: write.

While at it, document why the commit job needs pull-requests: read.

Found by zizmor's undocumented-permissions audit (--persona=pedantic).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ci backport/1.5-todo A PR in main branch which needs to be backported to release-1.5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants