From cf129d8dcb49063806d69a68323dfd5a647c3fcb Mon Sep 17 00:00:00 2001 From: nscuro Date: Wed, 23 Sep 2026 14:10:48 +0200 Subject: [PATCH 1/8] chore: disable credential persistence for actions/checkout Addresses zizmor `artipacked` findings. Signed-off-by: nscuro --- .github/workflows/lint_go.yml | 2 ++ .github/workflows/release.yml | 2 ++ .github/workflows/release_containers.yml | 2 ++ .github/workflows/security_analysis.yml | 2 ++ .github/workflows/test_acceptance.yml | 1 + .github/workflows/test_unit.yml | 2 ++ 6 files changed, 11 insertions(+) diff --git a/.github/workflows/lint_go.yml b/.github/workflows/lint_go.yml index 091cc07..f6d04af 100644 --- a/.github/workflows/lint_go.yml +++ b/.github/workflows/lint_go.yml @@ -23,6 +23,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v5 + with: + persist-credentials: false - name: Run golangci-lint uses: reviewdog/action-golangci-lint@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b8ae46..6fbcf35 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,6 +13,8 @@ jobs: steps: - name: Check out code uses: actions/checkout@v5 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@v6 diff --git a/.github/workflows/release_containers.yml b/.github/workflows/release_containers.yml index 60145a9..0cd738a 100644 --- a/.github/workflows/release_containers.yml +++ b/.github/workflows/release_containers.yml @@ -31,6 +31,8 @@ jobs: - name: Checkout uses: actions/checkout@v5 + with: + persist-credentials: false - name: Generate container tags and labels id: docker_meta diff --git a/.github/workflows/security_analysis.yml b/.github/workflows/security_analysis.yml index b2e5d4c..9b085b8 100644 --- a/.github/workflows/security_analysis.yml +++ b/.github/workflows/security_analysis.yml @@ -28,6 +28,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v5 + with: + persist-credentials: false - name: Initialize CodeQL uses: github/codeql-action/init@v3 diff --git a/.github/workflows/test_acceptance.yml b/.github/workflows/test_acceptance.yml index fbebf5f..591643b 100644 --- a/.github/workflows/test_acceptance.yml +++ b/.github/workflows/test_acceptance.yml @@ -28,6 +28,7 @@ jobs: - name: Checkout code uses: actions/checkout@v5 with: + persist-credentials: false # needed for bats tests submodules: true diff --git a/.github/workflows/test_unit.yml b/.github/workflows/test_unit.yml index d4b9536..6a65bf3 100644 --- a/.github/workflows/test_unit.yml +++ b/.github/workflows/test_unit.yml @@ -23,6 +23,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v5 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@v6 From 6f8ea61009040d4da19cb42eb5f25315d53833a9 Mon Sep 17 00:00:00 2001 From: nscuro Date: Wed, 23 Sep 2026 14:21:16 +0200 Subject: [PATCH 2/8] chore: pin github actions by digest Addresses zizmor `unpinned-uses` findings. Applied via: ``` GH_TOKEN="$(gh auth token)" zizmor --fix=all .github ``` Signed-off-by: nscuro --- .github/workflows/lint_go.yml | 4 ++-- .github/workflows/release.yml | 6 +++--- .github/workflows/release_containers.yml | 14 +++++++------- .github/workflows/security_analysis.yml | 14 ++++++++------ .github/workflows/test_acceptance.yml | 4 ++-- .github/workflows/test_unit.yml | 4 ++-- 6 files changed, 24 insertions(+), 22 deletions(-) diff --git a/.github/workflows/lint_go.yml b/.github/workflows/lint_go.yml index f6d04af..37362ad 100644 --- a/.github/workflows/lint_go.yml +++ b/.github/workflows/lint_go.yml @@ -22,9 +22,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 with: persist-credentials: false - name: Run golangci-lint - uses: reviewdog/action-golangci-lint@v2 + uses: reviewdog/action-golangci-lint@c76cceaaab89abe74e649d2e34c6c9adc26662d2 # v2.10.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6fbcf35..b781aa9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,17 +12,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 with: persist-credentials: false - name: Set up Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version-file: go.mod - name: Launch goreleaser - uses: goreleaser/goreleaser-action@v6.4.0 + uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0 with: args: release env: diff --git a/.github/workflows/release_containers.yml b/.github/workflows/release_containers.yml index 0cd738a..105b872 100644 --- a/.github/workflows/release_containers.yml +++ b/.github/workflows/release_containers.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Cache container layers - uses: actions/cache@v4.3.0 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: /tmp/.buildx-cache key: ${{ runner.os }}${{ matrix.containers.suffix }}-buildx-${{ github.sha }} @@ -30,13 +30,13 @@ jobs: ${{ runner.os }}${{ matrix.containers.suffix }}-buildx- - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 with: persist-credentials: false - name: Generate container tags and labels id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: controlplane/badrobot tags: | @@ -49,7 +49,7 @@ jobs: org.opencontainers.image.vendor=controlplane - name: Login to Docker Hub Registry - uses: docker/login-action@v3.6.0 + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: registry: docker.io username: ${{ secrets.DOCKERHUB_USERNAME }} @@ -63,13 +63,13 @@ jobs: # password: ${{ secrets.CR_PAT }} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - name: Set up Docker buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Build container and push tags - uses: docker/build-push-action@v6 + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 with: context: . platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/security_analysis.yml b/.github/workflows/security_analysis.yml index 9b085b8..f0e42c1 100644 --- a/.github/workflows/security_analysis.yml +++ b/.github/workflows/security_analysis.yml @@ -27,18 +27,18 @@ jobs: security-events: write steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 with: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@3ea06614dafe36dec890db3446326e0d40ce53d4 # v3.38.1 with: languages: go # analyzes + uploads sarif - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@3ea06614dafe36dec890db3446326e0d40ce53d4 # v3.38.1 govulncheck: name: govulncheck @@ -48,10 +48,12 @@ jobs: security-events: write steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + with: + persist-credentials: false - name: Vulnerability Scan Go Code - uses: golang/govulncheck-action@v1 + uses: golang/govulncheck-action@032d45514ae346b1db93c04b0c90b841c370344f # v1.1.0 with: go-version-file: go.mod repo-checkout: false @@ -67,7 +69,7 @@ jobs: cat <<< $(jq '(.runs[] | select(.results == null) | .results) |= []' govulncheck.sarif) > govulncheck.sarif - name: Upload Scan SARIF file - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@3ea06614dafe36dec890db3446326e0d40ce53d4 # v3.38.1 with: sarif_file: govulncheck.sarif category: govulncheck diff --git a/.github/workflows/test_acceptance.yml b/.github/workflows/test_acceptance.yml index 591643b..27453a4 100644 --- a/.github/workflows/test_acceptance.yml +++ b/.github/workflows/test_acceptance.yml @@ -26,14 +26,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 with: persist-credentials: false # needed for bats tests submodules: true - name: Set up Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 id: go with: go-version-file: go.mod diff --git a/.github/workflows/test_unit.yml b/.github/workflows/test_unit.yml index 6a65bf3..70342a1 100644 --- a/.github/workflows/test_unit.yml +++ b/.github/workflows/test_unit.yml @@ -22,12 +22,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 with: persist-credentials: false - name: Set up Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version-file: go.mod From ff5a6f92e88cd1909ed28d46fd26b1ea4498a903 Mon Sep 17 00:00:00 2001 From: nscuro Date: Wed, 23 Sep 2026 14:29:00 +0200 Subject: [PATCH 3/8] chore: downscope github actions permissions Addresses zizmor's `excessive-permissions` findings by scoping permissions to jobs, and explicitly dropping permissions at the workflow-level. Signed-off-by: nscuro --- .github/workflows/lint_go.yml | 1 + .github/workflows/release.yml | 3 +++ .github/workflows/release_containers.yml | 1 + .github/workflows/security_analysis.yml | 2 +- .github/workflows/test_acceptance.yml | 1 + .github/workflows/test_unit.yml | 1 + 6 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint_go.yml b/.github/workflows/lint_go.yml index 37362ad..3c78b0c 100644 --- a/.github/workflows/lint_go.yml +++ b/.github/workflows/lint_go.yml @@ -1,5 +1,6 @@ --- name: Linting - Go +permissions: {} # Split until path filtering for jobs added # https://github.community/t/path-filtering-for-jobs-and-steps/16447 on: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b781aa9..2e41bd7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,5 +1,6 @@ --- name: Release +permissions: {} on: # https://github.com/actions/runner/issues/1007 push: @@ -10,6 +11,8 @@ jobs: release: name: Release on GitHub runs-on: ubuntu-latest + permissions: + contents: write # Required for GoReleaser to create releases and upload assets. steps: - name: Check out code uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 diff --git a/.github/workflows/release_containers.yml b/.github/workflows/release_containers.yml index 105b872..b120bed 100644 --- a/.github/workflows/release_containers.yml +++ b/.github/workflows/release_containers.yml @@ -1,5 +1,6 @@ --- name: Release Containers +permissions: {} on: # https://github.com/actions/runner/issues/1007 push: diff --git a/.github/workflows/security_analysis.yml b/.github/workflows/security_analysis.yml index f0e42c1..bad9a3f 100644 --- a/.github/workflows/security_analysis.yml +++ b/.github/workflows/security_analysis.yml @@ -1,6 +1,6 @@ --- name: Security Analysis - +permissions: {} on: push: branches: [master] diff --git a/.github/workflows/test_acceptance.yml b/.github/workflows/test_acceptance.yml index 27453a4..20a9c0f 100644 --- a/.github/workflows/test_acceptance.yml +++ b/.github/workflows/test_acceptance.yml @@ -1,5 +1,6 @@ --- name: Testing - Acceptance +permissions: {} # Split until path filtering for jobs added # https://github.community/t/path-filtering-for-jobs-and-steps/16447 on: diff --git a/.github/workflows/test_unit.yml b/.github/workflows/test_unit.yml index 70342a1..2e2de88 100644 --- a/.github/workflows/test_unit.yml +++ b/.github/workflows/test_unit.yml @@ -1,5 +1,6 @@ --- name: Testing - Unit +permissions: {} # Split until path filtering for jobs added # https://github.community/t/path-filtering-for-jobs-and-steps/16447 on: From 7c2b099f3bad28bda4221dd62f782dfb1f56bf09 Mon Sep 17 00:00:00 2001 From: nscuro Date: Wed, 23 Sep 2026 14:31:06 +0200 Subject: [PATCH 4/8] chore: remove layer caching in container release workflow zizmor flagged this step for cache poisoning risk and recommends configuring it as `lookup-only` (https://docs.zizmor.sh/audits/#remediation_5). However the step appears to be largely ineffective already since Actions cache is scoped to refs (in this case tags). A build for tag v0.1.5 thus wouldn't get cache hits from v0.1.4. A fallback to `master` doesn't exist since nothing writes to the configured cache key for that branch. Opted to remove the step altogether. Signed-off-by: nscuro --- .github/workflows/release_containers.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/release_containers.yml b/.github/workflows/release_containers.yml index b120bed..c2c55ed 100644 --- a/.github/workflows/release_containers.yml +++ b/.github/workflows/release_containers.yml @@ -22,14 +22,6 @@ jobs: suffix: -alpine steps: - - name: Cache container layers - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}${{ matrix.containers.suffix }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}${{ matrix.containers.suffix }}-buildx- - - name: Checkout uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 with: @@ -76,8 +68,6 @@ jobs: platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} file: ${{ matrix.containers.file }} - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: mode=max,type=local,dest=/tmp/.buildx-cache tags: ${{ steps.docker_meta.outputs.tags }} labels: ${{ steps.docker_meta.outputs.labels }} build-args: | From ba4e942941e85b693ff76d6211cb78ca25ab3564 Mon Sep 17 00:00:00 2001 From: nscuro Date: Wed, 23 Sep 2026 14:36:34 +0200 Subject: [PATCH 5/8] chore: disable cache for actions/setup-go in release workflow Addresses zizmor's `cache-poisoning` finding. The cache gets populated from builds on `master`, thus posing a real poisoning risk for release builds. Release builds will be slower but that should be fine given they're super infrequent. Signed-off-by: nscuro --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2e41bd7..05707d7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,6 +23,7 @@ jobs: uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version-file: go.mod + cache: false - name: Launch goreleaser uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0 From 5f8fdf200e2cf662a8f3e8f1bcdad183ed5fe9ce Mon Sep 17 00:00:00 2001 From: nscuro Date: Wed, 23 Sep 2026 14:38:07 +0200 Subject: [PATCH 6/8] chore: configure dependabot cooldown of 7 days Addresses zizmor `dependabot-cooldown` findings. Signed-off-by: nscuro --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 03ae7e6..591367c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -16,6 +16,8 @@ updates: gha: patterns: - "*" + cooldown: + default-days: 7 - package-ecosystem: gomod directory: / schedule: @@ -33,6 +35,8 @@ updates: gomod: patterns: - "*" + cooldown: + default-days: 7 - package-ecosystem: docker directory: / schedule: @@ -47,3 +51,5 @@ updates: docker: patterns: - "*" + cooldown: + default-days: 7 From 1e05fbb36dc100fb15739ee8102de2d86888677f Mon Sep 17 00:00:00 2001 From: nscuro Date: Wed, 23 Sep 2026 14:39:44 +0200 Subject: [PATCH 7/8] chore: add lint workflow for github actions Signed-off-by: nscuro --- .github/workflows/lint_gha.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/lint_gha.yml diff --git a/.github/workflows/lint_gha.yml b/.github/workflows/lint_gha.yml new file mode 100644 index 0000000..9d6ece3 --- /dev/null +++ b/.github/workflows/lint_gha.yml @@ -0,0 +1,30 @@ +--- +name: Linting - GitHub Actions +permissions: {} +on: + push: + branches: [master] + paths: + - ".github/workflows/*.yml" + - ".github/dependabot.yml" + pull_request: + branches: [master] + paths: + - ".github/workflows/*.yml" + - ".github/dependabot.yml" + +jobs: + lint-gha: + name: Lint GitHub Actions + timeout-minutes: 5 + runs-on: ubuntu-latest + permissions: + security-events: write + actions: read + steps: + - name: Checkout Repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # tag=v7.0.1 + with: + persist-credentials: false + - name: Run zizmor + uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.4 From b17de3b4b5a959e91c9e6ef1b3d6b7604451549c Mon Sep 17 00:00:00 2001 From: nscuro Date: Thu, 24 Sep 2026 17:31:06 +0200 Subject: [PATCH 8/8] chore: strip tag= prefix from actions digest comments To be consistent with existing comments. Signed-off-by: nscuro --- .github/workflows/lint_gha.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint_gha.yml b/.github/workflows/lint_gha.yml index 9d6ece3..3077ac9 100644 --- a/.github/workflows/lint_gha.yml +++ b/.github/workflows/lint_gha.yml @@ -23,7 +23,7 @@ jobs: actions: read steps: - name: Checkout Repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # tag=v7.0.1 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Run zizmor