Skip to content

CI: Add zizmor workflow audit for unpinned actions#15757

Closed
kevinjqliu wants to merge 3 commits intoapache:mainfrom
kevinjqliu:kevinjqliu/zizmor
Closed

CI: Add zizmor workflow audit for unpinned actions#15757
kevinjqliu wants to merge 3 commits intoapache:mainfrom
kevinjqliu:kevinjqliu/zizmor

Conversation

@kevinjqliu
Copy link
Copy Markdown
Contributor

@kevinjqliu kevinjqliu commented Mar 24, 2026

Part of #15742
We've already moved all references to pinned commit hash in #15753

This adds a CI workflow that uses zizmor to detect unpinned third-party GitHub Actions in workflow files.
Future violations will trigger this CI to fail.

Problem

Actions referenced by mutable tag (e.g. actions/checkout@v4) can be silently replaced by a compromised or force-pushed tag, allowing arbitrary code execution inside CI. All uses: references should be pinned to a full commit SHA to make them immutable and auditable.

Solution

Add a zizmor.yml workflow that:

  • Triggers on PRs that modify .github/workflows/**
  • Runs zizmor in offline mode to check for unpinned-uses findings
  • Reports the file, line, and action for each violation
  • Fails the check if any unpinned actions are found

Testing

Ran CI on forked repo w/ a tagged pin, kevinjqliu#14
Fails CI ✅ https://github.com/kevinjqliu/iceberg/actions/runs/23516762295/job/68450916216?pr=14

Error: Found unpinned GitHub Actions:
.github/workflows/open-api.yml:49:15	astral-sh/setup-uv@v7
Error: Process completed with exit code 1.

@github-actions github-actions bot added the INFRA label Mar 24, 2026
@kevinjqliu kevinjqliu marked this pull request as ready for review March 24, 2026 23:24
# compromised or force-pushed tag, allowing arbitrary code execution
# in CI. Pinning to a full commit SHA makes the reference immutable.
run: |
findings=$(uvx --from zizmor zizmor \
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.

This isn't the prettiest, but it does isolate the unpinned-use error

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.

why don't we want to do the "security-events" write ?

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.

we will eventually. This is just gate regression for 1 specific issue (unpinned-uses)

we already fixed it in #15707

@kevinjqliu
Copy link
Copy Markdown
Contributor Author

once we burn down the warnings from zizmor, we can enforce everything using the zizmor github action (https://github.com/marketplace/actions/zizmor-action)

@steveloughran
Copy link
Copy Markdown
Contributor

steveloughran commented Mar 25, 2026

the fact the zizmor found an unpinned reference is a successful test run: it shows it works

findings=$(uvx --from zizmor zizmor \
--offline \
--format json-v1 \
.github/workflows 2>/dev/null \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: 2>/dev/null hides errors, if zizmor fails to run, $findings will be empty and the check will silently pass. Maybe remove it or check the exit code first?

| jq -r '
[
.[]
| select(.ident == "unpinned-uses")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should we include all items with high severity and high confidence?

      "confidence": "High",
      "severity": "High",

Or is unpinned-uses just the first step?

@kevinjqliu
Copy link
Copy Markdown
Contributor Author

superseded by #15793

@kevinjqliu kevinjqliu closed this Mar 27, 2026
@kevinjqliu kevinjqliu deleted the kevinjqliu/zizmor branch March 27, 2026 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants