Skip to content

ci: add zizmor for GitHub Actions security scanning#43

Draft
blimmer wants to merge 1 commit into
mainfrom
ci/add-zizmor
Draft

ci: add zizmor for GitHub Actions security scanning#43
blimmer wants to merge 1 commit into
mainfrom
ci/add-zizmor

Conversation

@blimmer
Copy link
Copy Markdown
Contributor

@blimmer blimmer commented May 13, 2026

Summary

Adds zizmor static analysis for .github/. Findings upload to GitHub code scanning (Security tab); the workflow's SARIF format keeps the job at exit 0 regardless of findings. The audit is gated on changes to .github/** or the root zizmor.yml so we don't burn the shared 5,000/hr GITHUB_TOKEN budget on every PR. Also addresses every finding zizmor reports on the existing workflows — final state is 0 findings at regular persona.

Review focus

  • SHA pinning gotcha. Three pins (github/codeql-action, Swatinem/rust-cache, release-plz/action) were initially set to annotated-tag-object SHAs returned by gh api .../git/refs/tags/<tag>. The runner accepts those, but zizmor's impostor-commit audit triggers a worst-case compare_commits loop on them — see zizmorcore/zizmor#1997. A single bad pin against a popular repo like codeql-action (~893 refs) burns ~3,500 API calls and exhausts the token. All 13 pins in this PR have been verified to point at commit SHAs, not tag-object SHAs.

  • release.yml excluded from audit. Generated by cargo-dist; any pins/perms fixes get clobbered on the next dist generate. The zizmor workflow uses find ... ! -path .github/workflows/release.yml to exclude it.

  • In-job paths-filter, not trigger-level paths:. If zizmor ever becomes a required status check, a trigger-level paths: filter would leave the check stuck in "Pending" and block merges on PRs that don't touch .github/. The in-job dorny/paths-filter gates the heavy steps while the job itself still always starts and reports.

  • dtolnay/rust-toolchain@stable keeps its branch ref. The action's documented usage; SHA-pinning defeats the "stable channel" semantics. Five usages carry inline # zizmor: ignore[unpinned-uses].

  • cache-poisoning on the SDK publish flow is inline-ignored, not fixed. Cache scoping in GitHub Actions prevents PR-scope caches from propagating up to tag/main builds, so an attacker would need a merged PR to poison the cache release-sdk reads — at which point caching is the least of the problems. The mise + pnpm build-time wins are worth keeping.

  • dependabot-cooldown is suppressed at 3 days, not raised to the audit's 7-day threshold. Matches planbridge's stance: fast bumps for low-risk updates, security advisories bypass cooldown anyway.

  • Workflow permissions narrowed where possible. ci.yml and release-plz.yml gain top-level contents: read. deploy-website.yml's workflow-level pages: write / id-token: write move down to the deploy job (the build job inherits read-only).

  • Built-in GITHUB_TOKEN, no app token. Aether's workflows don't reference any private actions, so the default token has the access it needs. With the SHA fixes above, the rate-limit problem doesn't return.

Prereq before merge

GitHub code scanning must be enabled (Settings -> Code security) or the upload-sarif step will fail on the first run.

Commits

This is a single commit so the history reads as one cohesive change. Happy to split if you'd prefer per-concern commits.

  • 6326af6b — Add zizmor workflow + config; pin 13 actions to commit SHAs; fix one template-injection; add persist-credentials: false, narrow permissions, dependabot cooldown, inline-ignores with rationale.

Introduces zizmor static analysis for .github/. Findings upload to
GitHub code scanning (Security tab), and the workflow's SARIF format
keeps the job's exit at 0 regardless of findings. The audit is gated
on changes to .github/** or the root zizmor.yml so we don't burn the
shared 5,000/hr GITHUB_TOKEN budget on every PR.

Also address the findings on existing workflows:

- Fix template-injection in the fetch-release-secrets composite
  action by routing inputs.parameter-path through env-var indirection.

- Pin 13 actions to commit SHAs across ci.yml, release-sdk.yml,
  release-plz.yml, deploy-website.yml, fetch-release-secrets, and
  zizmor.yml. dtolnay/rust-toolchain@stable keeps its branch ref
  (the action's documented "stable channel" usage) with inline
  zizmor: ignore[unpinned-uses] comments.

  Important: SHAs come from the commit those tags point at, not the
  annotated-tag object SHA. Annotated tags are accepted by the runner
  but trigger a worst-case API loop in zizmor's impostor-commit audit
  (per zizmorcore/zizmor#1997 — ~3,500 calls for github/codeql-action
  alone). Use `gh api repos/X/git/refs/tags/Y` then dereference via
  `gh api repos/X/git/tags/<sha>` when .object.type is "tag".

- Bump aws-actions/configure-aws-credentials v6.1.0 -> v6.1.1.

- Add persist-credentials: false to all checkouts in ci.yml,
  release-sdk.yml, and deploy-website.yml.

- Add top-level permissions: contents: read to ci.yml and
  release-plz.yml. deploy-website.yml's workflow-level
  pages: write / id-token: write move down to the deploy job only.

- Add 3-day dependabot cooldown across all ecosystems with inline
  zizmor: ignore[dependabot-cooldown] (matches planbridge: fast bumps
  for low-risk updates; security advisories bypass cooldown anyway).

- Exclude .github/workflows/release.yml from audit. It is generated
  by cargo-dist, so any fixes there get clobbered on `dist generate`.

- The mise-action and setup-node steps in release-sdk.yml carry
  inline zizmor: ignore[cache-poisoning] with a rationale comment.
  GitHub Actions cache scoping prevents PR-scope caches from
  propagating up to tag/main builds, so poisoning this workflow's
  cache requires a merged PR (at which point caching is the least
  of the problems). The build-time win is worth keeping.

Heads up: GitHub code scanning must be enabled (Settings -> Code
security) for the SARIF upload step to succeed on first run.
@github-advanced-security
Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

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.

2 participants