From 34b76dc127dc6455a2ee68977ed6ed00f434e15f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C4=81ris=20Pop=C4=93ns?= Date: Thu, 24 Sep 2026 10:03:47 +0000 Subject: [PATCH] chore(ci): harden workflows, enforce zizmor - Explicit read-only `permissions:` on workflows that had none (the org default is read-only already; this makes it visible and drops read access to other scopes). - Checkouts that never push no longer leave the token in .git/config (`persist-credentials: false`); ones that push say so explicitly. - Third-party actions SHA-pinned at the commits their tags point to today; Dependabot keeps them current. - New zizmor job (reusable-actions zizmor.yml) gated by Required checks passed, so new findings block merges; accepted ones are in .github/zizmor.yml. --- .github/workflows/build.yml | 11 ++++++----- .github/workflows/validate.yml | 18 ++++++++++++++---- .github/zizmor.yml | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 .github/zizmor.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2799a4..8d3fbd6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,16 +32,17 @@ jobs: steps: - uses: actions/checkout@v7.0.1 + with: + persist-credentials: false - - uses: docker/setup-buildx-action@v4.4.1 - - - uses: docker/login-action@v4.6.0 + - uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 + - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - uses: docker/metadata-action@v6.2.0 + - uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 id: meta with: images: ghcr.io/drumandbytes/github-actions-runner-exporter @@ -51,7 +52,7 @@ jobs: type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} - - uses: docker/build-push-action@v7.4.0 + - uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 id: build with: context: . diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 049e0dd..199404c 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -17,6 +17,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# Read-only token; no job here writes to the repo or reads other scopes. +permissions: + contents: read + jobs: lint: uses: drumandbytes/reusable-actions/.github/workflows/go-ci.yml@v1 @@ -30,10 +34,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7.0.1 + with: + persist-credentials: false - - uses: docker/setup-buildx-action@v4.4.1 - - - uses: docker/build-push-action@v7.4.0 + - uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 + - uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 with: context: . load: true @@ -58,12 +63,17 @@ jobs: -sS -f -o /dev/null http://localhost:9222/healthz docker rm -f smoke-test + # Audit of this repo's own workflows; accepted findings are in + # .github/zizmor.yml. + zizmor: + uses: drumandbytes/reusable-actions/.github/workflows/zizmor.yml@v1 + # Single stable name for the org's required-status-check ruleset to point # at, regardless of how the real jobs above are split or renamed. required-checks-passed: name: Required checks passed runs-on: ubuntu-latest - needs: [lint, smoke-test] + needs: [lint, smoke-test, zizmor] if: always() steps: - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000..5455cb9 --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,18 @@ +# zizmor configuration, read by the zizmor job in validate.yml. Anything accepted +# here is accepted on purpose -- each entry says why. + +rules: + unpinned-uses: + config: + policies: + # GitHub's own and the org's actions stay on tags (Dependabot moves + # them); third-party actions are SHA-pinned. + "actions/*": ref-pin + "drumandbytes/*": ref-pin + "*": hash-pin + + dangerous-triggers: + ignore: + # workflow_run so Dependabot PRs get a token that can merge; never + # checks out PR code. + - auto-merge.yml