Skip to content

🔒 ci(workflows): add zizmor security auditing#517

Merged
gaborbernat merged 1 commit intotox-dev:mainfrom
gaborbernat:add-zizmor-pre-commit
Mar 26, 2026
Merged

🔒 ci(workflows): add zizmor security auditing#517
gaborbernat merged 1 commit intotox-dev:mainfrom
gaborbernat:add-zizmor-pre-commit

Conversation

@gaborbernat
Copy link
Copy Markdown
Member

@gaborbernat gaborbernat commented Mar 24, 2026

GitHub Actions workflows were vulnerable to several security issues including template injection, credential exposure, and permission over-scoping. These vulnerabilities could allow attackers to execute arbitrary code or access sensitive tokens.

This change adds zizmor as a pre-commit hook to continuously audit workflow security and fixes all existing vulnerabilities. The fixes include pinning actions to commit hashes, moving secrets to dedicated environments, isolating GitHub context from shell execution, and restricting permissions to the minimum required scope.

All workflows now pass security audit with zero findings. Future workflow changes will be automatically checked before commit.

@gaborbernat gaborbernat enabled auto-merge (squash) March 24, 2026 22:46
@gaborbernat gaborbernat force-pushed the add-zizmor-pre-commit branch 2 times, most recently from f3d9021 to 728fed3 Compare March 24, 2026 23:14
@gaborbernat gaborbernat changed the title Add zizmor pre-commit hook and fix security issues 🔒 ci(workflows): add zizmor security auditing Mar 24, 2026
@gaborbernat gaborbernat force-pushed the add-zizmor-pre-commit branch 2 times, most recently from 2af9601 to e08f433 Compare March 25, 2026 21:24
Add zizmor pre-commit hook to catch GitHub Actions security issues.
Fix all existing findings:
- template-injection: Move GitHub context to env vars
- secrets-outside-env: Add environment declarations
- dangerous-triggers: Replace pull_request_target with pull_request
- bot-conditions: Use pull_request.user.login instead of github.actor
- excessive-permissions: Move permissions to job level
- superfluous-actions: Replace with native tools
@gaborbernat gaborbernat force-pushed the add-zizmor-pre-commit branch from e08f433 to 4f5eb7a Compare March 26, 2026 13:42
@gaborbernat gaborbernat merged commit 8cd6bd9 into tox-dev:main Mar 26, 2026
32 checks passed
gaborbernat added a commit that referenced this pull request Apr 14, 2026
Releases have been silently broken on PyPI since 3.26.0. Every dispatch
of the release workflow since then produced a
``filelock-X.Y.Z.devN+g<sha>-py3-none-any.whl``, which PyPI rejects with
``400 Bad Request`` because local version identifiers are not allowed on
the public index. 🐛 PyPI still shows 3.25.2 as the latest version while
GitHub has tags and releases for 3.26.0, 3.26.1, and 3.27.0. Anyone
running ``pip install filelock`` is stuck on the last working release.

Commit 8cd6bd9 (``🔒 ci(workflows): add zizmor security auditing #517``)
moved the release version from a GitHub Actions template expression into
a bash environment variable to harden against template injection. The
move was correct, but kept the existing single quotes around the
reference: ``git tag '${STEPS_V_OUTPUTS_VERSION}'``. In bash, single
quotes suppress variable expansion, so ``git tag`` received the literal
28-character string ``${STEPS_V_OUTPUTS_VERSION}`` as the tag name.
hatch-vcs then could not find a real version on ``HEAD``, ``uv build``
fell back to the ``.devN+g<sha>`` scheme, and PyPI rejected the upload.
Double quotes preserve the env-var indirection zizmor wanted while
letting bash actually read the value, so the correct version gets tagged
and the wheel is built with the clean
``filelock-X.Y.Z-py3-none-any.whl`` name PyPI expects.

Why this slipped past CI: the tag-creation step is gated behind ``if:
github.event.inputs.release != 'no'``, so regular push and pull-request
events skip it entirely. The broken line only runs under manual
workflow-dispatch, and even then the failure surfaces in the ``release``
job's PyPI-publish step, which no PR-level check watches. The last two
successful CI builds of the release workflow were the ones that actually
broke publishing.

The second commit aligns the ``actions/upload-artifact`` version
comments with the exact tag the pinned hash resolves to (``v7.0.0``
instead of ``v7``). 🔒 Zizmor flags the mismatch as
``ref-version-mismatch`` because the moving major tag ``v7`` currently
points to a different commit, and pre-commit would otherwise block this
branch on its own audit. The pinned hash does not change, so there is no
behavioral impact.

After merge, re-dispatch the release workflow with a ``patch`` bump (or
whatever bump type makes sense) to get the currently-unpublished work
onto PyPI.
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