Skip to content

CI: harden the workflows (zizmor) and add dependabot - #215

Merged
ThomasWaldmann merged 2 commits into
borgbackup:mainfrom
ThomasWaldmann:harden-workflows-zizmor
Aug 31, 2026
Merged

CI: harden the workflows (zizmor) and add dependabot#215
ThomasWaldmann merged 2 commits into
borgbackup:mainfrom
ThomasWaldmann:harden-workflows-zizmor

Conversation

@ThomasWaldmann

Copy link
Copy Markdown
Member

Ran zizmor 1.30 over .github/workflows/ and fixed everything it reported, plus a dependabot config modelled on the one in borg.

What zizmor found

audit severity where
unpinned-uses high (4x) actions/checkout@v7, actions/setup-python@v6, psf/black@stable
artipacked medium / low (3x) every actions/checkout step
template-injection (auditor) tox -e ${{ matrix.toxenv }} in ci.yml
concurrency-limits (auditor) ci.yml, black.yaml

What this changes

  • Hash-pin the actions, version in a trailing comment, the way release.yml already does it. The one that actually mattered is psf/black@stablestable is a branch of a third-party action. setup-python goes v6 → v7 on the way; v7 only drops the pip-install input, which we do not use, and borg already runs v7 on the same OS set.
  • persist-credentials: false on all checkouts. Nothing here pushes, so the token has no reason to sit in the workspace .git/config. In release.yml that is the medium finding: the token was in the workspace while the sdist artifact got uploaded. That job talks to GitHub via GH_TOKEN, not via git, so it does not care.
  • run: tox instead of tox -e ${{ matrix.toxenv }}. Not exploitable — the matrix values are literals in the workflow — but the job already exports TOXENV, so the expansion was redundant anyway.
  • A concurrency: group for CI and Lint, same expression as borg. Pushing twice to a PR branch now cancels the older run instead of stacking up. Not a security thing, just runner time.
  • .github/dependabot.yml, same shape as borg's: weekly grouped updates for the actions (they need something to bump them now that they are hashes) and for requirements.d, with a cooldown so a version that gets yanked right after release does not reach us. black is excluded because its version lives in two places (requirements.d/codestyle.txt and the psf/black step) and dependabot only sees one of them.

zizmor --offline .github/workflows/ is clean now. With --persona=auditor three things remain, deliberately:

  • concurrency-limits on release.yml — that one is tag-triggered, cancelling a release build in flight is not what we want.
  • anonymous-definition on the lint and ci_job jobs — adding a name: renames the check runs, which would break any required-status-check configuration. Left alone.

No functional change to what CI runs.

ThomasWaldmann and others added 2 commits August 31, 2026 22:26
zizmor (https://docs.zizmor.sh/) flagged these in .github/workflows/:

- unpinned-uses: actions/checkout@v7, actions/setup-python@v6 and
  psf/black@stable are all mutable refs - "stable" is a branch, so
  whatever it points at today is what runs tomorrow. Pin all of them
  to a commit hash with the version in a comment, like release.yml
  already does. setup-python goes from v6 to v7 on the way (v7 only
  drops the pip-install input, which we do not use).
- artipacked: actions/checkout leaves the credentials it used in
  .git/config of the workspace. Nothing here pushes, so turn that off
  via persist-credentials: false. In release.yml this also stops the
  token from being in the workspace while the sdist artifact is
  uploaded; the release job talks to GitHub via GH_TOKEN, not git.
- template-injection: "tox -e ${{ matrix.toxenv }}" expanded the
  matrix value into the shell command. The values are literals in this
  workflow, so it was not exploitable, but the job already exports
  TOXENV - so just run tox and let it pick that up.
- concurrency-limits: without a concurrency group, pushing to a pull
  request branch stacked up runs instead of cancelling the previous
  one. Same group expression as borg uses.

zizmor is clean on .github/workflows/ now (default persona).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Same setup as in borg: one weekly grouped update for the GitHub
Actions (now that they are pinned to hashes, they need something that
bumps them), one for requirements.d, and a cooldown so we do not run
into a version that gets yanked or hotfixed right after release.

black is excluded because its version is pinned in two places -
requirements.d/codestyle.txt and the psf/black step in black.yaml -
and dependabot only knows about the first one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ThomasWaldmann
ThomasWaldmann merged commit 6e8d2c4 into borgbackup:main Aug 31, 2026
9 checks passed
@ThomasWaldmann
ThomasWaldmann deleted the harden-workflows-zizmor branch August 31, 2026 20:38
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