Skip to content

ci: add zizmor, fix found issues - #92

Open
kolyshkin wants to merge 6 commits into
opencontainers:mainfrom
kolyshkin:zizmor
Open

kolyshkin wants to merge 6 commits into
opencontainers:mainfrom
kolyshkin:zizmor

Conversation

@kolyshkin

Copy link
Copy Markdown
Contributor

This is the same as opencontainers/runc#5387: 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: add concurrency limits -- cancel superseded PR runs; keyed by PR number,
    so pushes to main/release-/v tags are never cancelled.
  • ci: fix up job permissions -- lint does not need pull-requests: read.

Differences from runc are due to local specifics:

  • there are no release artifacts here (this is a library), which is the
    reason for ignoring cache-poisoning;
  • there is no scheduled.yml, so nothing to narrow down there;
  • the pedantic template-injection finding for ${{ matrix.race }} in
    test.yml is left as is: the matrix is static, so this is a false positive,
    and moving it to an env var makes the script worse (an unquoted variable,
    since an empty quoted one breaks go test).

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.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Set persist-credentials: false for actions/checkout. 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.

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.

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.

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.

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 -- 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.

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

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.

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

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
@kolyshkin
kolyshkin requested a review from a team as a code owner October 19, 2026 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant