Skip to content

ci: adopt zizmor and harden GitHub Actions workflows - #39

Open
hasansezertasan wants to merge 3 commits into
mainfrom
ci/zizmor
Open

ci: adopt zizmor and harden GitHub Actions workflows#39
hasansezertasan wants to merge 3 commits into
mainfrom
ci/zizmor

Conversation

@hasansezertasan

@hasansezertasan hasansezertasan commented Jul 23, 2026

Copy link
Copy Markdown
Member

Description

Adopts zizmor to statically analyze our GitHub Actions, wired in as a pre-commit hook (zizmorcore/zizmor-pre-commit). Because the existing validate CI job already runs pre-commit run --all-files, this makes zizmor a required CI check with no new workflow and no extra action to pin.

Per maintainer direction, this uses the strict policy (SHA-pin everything) and resolves every finding to zero.

Findings resolved (23 high + 13 medium → 0)

Audit Fix
unpinned-uses (21) All actions pinned to full commit SHAs; version kept as a trailing # vX comment
artipacked (7) persist-credentials: false on every actions/checkout
excessive-permissions (5) Top-level permissions: {} on every workflow + least-privilege per-job grants
cache-poisoning (2) enable-cache: false on the release-triggered docs/publish workflows
archived-uses (1) Archived sonarsource/sonarcloud-github-action@master replaced
dependabot-cooldown (1) 7-day dependabot cooldown

Notable changes reviewers should sanity-check

  • Sonar migration. sonarsource/sonarcloud-github-action@master (archived) → SonarSource/sonarqube-scan-action, pinned to v6. v4–v5 are vulnerable to argument injection (GHSA-5xq9-5g24-4g6f); v6.0.0 is the first patched release. Added SONAR_HOST_URL: https://sonarcloud.io as required by the new action. Worth a live check that the Sonar scan still reports.
  • CodeQL bump. github/codeql-action v2 → v3 — v2 is retired, so pinning a v2 SHA would be a dead pin.
  • Dependabot cooldown mirrors the uv exclude-newer = "1 week" policy from build: pin uv resolver with exclude-newer #19.

Verification

  • zizmor .github/workflows/No findings to report (16 suppressed by default persona).
  • pre-commit run zizmor --all-filesPassed (also audits .github/dependabot.yaml).
  • All workflow YAML validated.

Note: SHA pins want a bot (Dependabot/Renovate, see #21) to stay fresh — Dependabot's github-actions updater already covers them.

Closes

Summary by Sourcery

Harden GitHub Actions workflows and CI configuration, including adopting zizmor in pre-commit and tightening security posture across workflows.

Enhancements:

  • Adopt zizmor as a pre-commit hook so workflow security checks run as part of the existing validate job.
  • Pin all GitHub Actions used in CI, docs, publish, test, and CodeQL workflows to specific commit SHAs.
  • Restrict default and job-level GitHub Actions permissions to least-privilege, adding explicit contents read/write and security-events scopes where required.
  • Disable uv action caching in release-triggered docs and publish workflows to reduce cache-related risks.
  • Replace the deprecated SonarCloud GitHub Action with the maintained SonarQube scan action configured for sonarcloud.io.
  • Upgrade CodeQL workflows from v2 to v3 while retaining existing analysis behavior.
  • Configure Dependabot with a 7-day cooldown for GitHub Actions updates to align with the project’s release hygiene policy.

CI:

  • Strengthen CI workflows by enforcing pinned actions, strict permissions, and secure Sonar and CodeQL integrations.

Tests:

  • Ensure coverage artifact upload and related test workflow steps use pinned actions with constrained permissions.

Chores:

  • Update pre-commit configuration to include zizmor and keep CI security tooling consistent across the project.

Two layers of zizmor

Following the zizmor-action usage (modeled on Starlette's workflow):

Layer How Behavior
Blocking gate zizmor pre-commit hook (runs in the validate job + locally) Hard-fails on any finding; also gives local pre-commit feedback
Security dashboard .github/workflows/zizmor.ymlzizmorcore/zizmor-action (SHA-pinned v0.6.0) Uploads SARIF to the Security tab via GitHub Advanced Security (public repo) for stateful, incremental triage; non-blocking by design

The new workflow is itself SHA-pinned and least-privilege, so it passes the zizmor audit it runs.

Add zizmor (as a pre-commit hook, which runs in the existing validate
CI job) to statically analyze GitHub Actions, and resolve every
finding it reports:

- Pin all third-party and first-party actions to full commit SHAs
  (unpinned-uses), with the version tag kept as a trailing comment.
- Set persist-credentials: false on every checkout (artipacked).
- Add top-level 'permissions: {}' with least-privilege per-job grants
  (excessive-permissions).
- Disable uv caching on the release-triggered docs and publish
  workflows (cache-poisoning).
- Replace the archived sonarsource/sonarcloud-github-action@master
  with SonarSource/sonarqube-scan-action, pinned to v6 (v4-v5 are
  vulnerable to argument injection, GHSA-5xq9-5g24-4g6f) and add
  SONAR_HOST_URL for SonarQube Cloud.
- Bump github/codeql-action from the retired v2 to v3.
- Add a 7-day dependabot cooldown (dependabot-cooldown), mirroring the
  uv exclude-newer policy.

Closes #22
@hasansezertasan hasansezertasan added ci This is CI related infra This is Infrastructure related labels Jul 23, 2026
@sourcery-ai

sourcery-ai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

This PR integrates zizmor as a pre-commit hook to statically analyze GitHub Actions and remediates all reported issues by pinning actions to SHAs, tightening permissions, disabling unsafe caches, migrating Sonar scanning, bumping CodeQL, and adding a Dependabot cooldown, without introducing new workflows.

Sequence diagram for validate job running zizmor via pre-commit

sequenceDiagram
  actor Developer
  participant GitHub
  participant ci_validate_job
  participant pre_commit
  participant zizmor

  Developer->>GitHub: push or open_pull_request
  GitHub->>ci_validate_job: trigger ci.yaml validate
  ci_validate_job->>pre_commit: pre-commit run --all-files
  pre_commit->>zizmor: run zizmor
  zizmor-->>ci_validate_job: findings for workflows and dependabot
  ci_validate_job-->>GitHub: job status with zizmor as required check
Loading

File-Level Changes

Change Details Files
Integrate zizmor static analysis into the existing pre-commit/CI validate pipeline.
  • Add zizmor-pre-commit repository and hook configuration to pre-commit config
  • Rely on existing validate job’s pre-commit run --all-files to make zizmor a required CI check
.pre-commit-config.yaml
.github/workflows/ci.yaml
Harden all GitHub Actions workflows with least-privilege permissions and secure action usage.
  • Add top-level permissions: {} and per-job permissions blocks granting only required scopes
  • Pin all GitHub Actions and third-party actions to full commit SHAs while retaining version comments
  • Disable persist-credentials on all uses of actions/checkout to prevent credential leakage
  • Pin artifact upload/download, cache, deploy, and publish actions to SHAs
.github/workflows/ci.yaml
.github/workflows/docs.yaml
.github/workflows/publish.yaml
.github/workflows/test.yaml
.github/workflows/codeql.yml
Mitigate cache poisoning and other supply-chain risks in release-triggered workflows.
  • Set enable-cache: false for uv setup in docs and publish workflows triggered by releases
  • Ensure release workflows only use SHA-pinned actions and minimal permissions
.github/workflows/docs.yaml
.github/workflows/publish.yaml
Migrate Sonar scanning from deprecated sonarcloud action to the maintained SonarQube scan action.
  • Replace sonarsource/sonarcloud-github-action@master with SonarSource/sonarqube-scan-action pinned to a v6 SHA
  • Rename job step to SonarQube Cloud Scan and add required SONAR_HOST_URL environment variable
.github/workflows/ci.yaml
Upgrade CodeQL workflows from v2 to v3 while keeping configuration equivalent.
  • Change CodeQL init/analyze steps to use v3 SHA in both CI and scheduled CodeQL workflows
  • Retain existing language configuration and dependency setup behavior
.github/workflows/ci.yaml
.github/workflows/codeql.yml
Introduce a Dependabot cooldown window to align with uv’s exclude-newer policy.
  • Add a 7-day cooldown.default-days setting for the github-actions Dependabot updater to avoid very fresh releases
.github/dependabot.yaml

Assessment against linked issues

Issue Objective Addressed Explanation
#22 Integrate zizmor into the repository to scan .github/workflows/, either as a dedicated CI job or as a pre-commit hook.
#22 Triage and remediate zizmor’s initial findings (e.g., pin all GitHub Actions to SHAs, tighten workflow/job permissions, address caching and other security issues).
#22 Ensure zizmor runs in CI as a required check for the project.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

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.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Add .github/workflows/zizmor.yml using zizmorcore/zizmor-action to
upload zizmor findings as SARIF to the GitHub Security tab for
stateful, incremental triage. Complements the blocking pre-commit
hook, which provides the hard CI gate and local developer feedback.

Refs #22
@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.

@hasansezertasan
hasansezertasan requested a review from Copilot July 23, 2026 16:16
hasansezertasan added a commit that referenced this pull request Jul 23, 2026
Add a codecov job to the CI workflow that consumes the existing
coverage-xml artifact and uploads it via codecov/codecov-action, plus
a root codecov.yml (auto targets, patch coverage, PR comments) and a
coverage badge in the README. Adapted from #16.

Stacked on the zizmor hardening (#39): the codecov job uses SHA-pinned
actions, persist-credentials: false, and a least-privilege permissions
block so it passes the zizmor pre-commit gate.

Closes #24

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the repository’s GitHub Actions posture by introducing zizmor-based static analysis (both as a blocking pre-commit hook and as a SARIF-uploading workflow) and tightening workflow security across CI, release, docs, and CodeQL automation.

Changes:

  • Add zizmor as a pre-commit hook and introduce a dedicated zizmor workflow that uploads SARIF to the Security tab.
  • Harden workflows by setting default permissions: {}, adding least-privilege per-job permissions, SHA-pinning actions, and disabling persist-credentials on actions/checkout.
  • Update automation configuration: migrate Sonar scan action, bump CodeQL action to v3, disable uv caching in release-triggered workflows, and add a Dependabot cooldown window.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
.pre-commit-config.yaml Adds zizmor as a required pre-commit hook so workflow security checks run in existing CI validation.
.github/workflows/zizmor.yml New zizmor workflow to produce/upload SARIF results with pinned actions and reduced permissions.
.github/workflows/test.yaml Applies default-deny permissions and SHA-pins actions for the reusable test workflow.
.github/workflows/publish.yaml Applies default-deny permissions, SHA-pins actions, disables uv cache, and pins PyPI publish action.
.github/workflows/docs.yaml Applies default-deny permissions, SHA-pins actions, and disables uv cache for release-triggered docs deploy.
.github/workflows/codeql.yml Applies default-deny permissions, SHA-pins checkout, and bumps CodeQL action to v3 with pinned SHAs.
.github/workflows/ci.yaml Applies default-deny permissions, SHA-pins actions, tightens job permissions, and migrates Sonar action.
.github/dependabot.yaml Adds a 7-day cooldown before proposing newly published GitHub Actions updates.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/publish.yaml
# Conflicts:
#	.github/workflows/ci.yaml
#	.github/workflows/codeql.yml
#	.github/workflows/docs.yaml
#	.github/workflows/publish.yaml
#	.github/workflows/test.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci This is CI related infra This is Infrastructure related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: adopt zizmor for GitHub Actions security

3 participants