Repository: grafana/grafana-operator
Pull request #1977: ci: zizmor fixes
Author: login: theSuess
Labels: name: bugfix
description: this PR fixes a bug
name: chore
Created: 2025-04-28T12:09:54Z | Merged: 2025-04-30T05:27:37Z

This PR fixes potential security issues discovered using [zizmor](https://github.com/woodruffw/zizmor?tab=readme-ov-file).

It also pins _all_ actions used to a hash version to prevent any hostile takeovers of external dependencies.


Diff:
diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index 49bb2e2eb..7bd2e6233 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -9,19 +9,21 @@ env:
   NAME: grafana-operator
   NAMESPACE: grafana-operator-system
 
+permissions:
+  contents: read
+
 jobs:
   docs_only_check:
     name: Check for docs-only change
     runs-on: ubuntu-latest
-    permissions:
-      contents: read
     outputs:
       docs_only: ${{ steps.docs_only_check.outputs.docs_only }}
     steps:
       - name: Check out code
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
         with:
           fetch-depth: 0
+          persist-credentials: false
 
       - id: changed-files
         name: Get changed files
@@ -32,13 +34,6 @@ jobs:
             **/*.html
             hugo/**
 
-      - id: which_files
-        name: Which files was changed
-        run: |
-          echo "One or more files has changed."
-          echo "List all the files that have changed: ${{ steps.changed-files.outputs.all_changed_files }}"
-          echo "What is any changed ${{ steps.changed-files.outputs.any_changed }}"
-
       - id: docs_only_check
         if: steps.changed-files.outputs.any_changed != 'true'
         name: Check for docs-only changes
@@ -61,21 +56,23 @@ jobs:
           - v1.32.2
     steps:
       - name: Clone repo and checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
 
       - name: Install go
-        uses: actions/setup-go@v5
+        uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
         with:
           go-version-file: "go.mod"
           cache: true
 
       - name: Install ko
-        uses: ko-build/setup-ko@v0.9
+        uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
         with:
           version: v0.16.0
 
       - name: Install chainsaw
-        uses: kyverno/action-install-chainsaw@v0.2.12
+        uses: kyverno/action-install-chainsaw@f2b47b97dc889c12702113753d713f01ec268de5 # v0.2.12
 
       - name: Create KinD cluster ${{ matrix.version }}
         id: kind
@@ -83,7 +80,7 @@ jobs:
           kind --kubeconfig="${KUBECONFIG}" create cluster --image=kindest/node:${{ matrix.version }} --config tests/e2e/kind.yaml
 
       - name: Install kubectl
-        uses: azure/setup-kubectl@v4
+        uses: azure/setup-kubectl@3e0aec4d80787158d308d7b364cb1b702e7feb7f # v4
         with:
           version: ${{ matrix.version }}
 
diff --git a/.github/workflows/hugo.yaml b/.github/workflows/hugo.yaml
index 6875c2fe9..8146b031b 100644
--- a/.github/workflows/hugo.yaml
+++ b/.github/workflows/hugo.yaml
@@ -9,10 +9,6 @@ on:
   workflow_dispatch:
 
 # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
-permissions:
-  contents: read
-  pages: write
-  id-token: write
 
 # Allow one concurrent deployment
 concurrency:
@@ -27,6 +23,8 @@ defaults:
 jobs:
   # Build job
   build:
+    permissions:
+      contents: read
     runs-on: ubuntu-latest
     env:
       HUGO_VERSION: 0.134.3
@@ -42,15 +40,17 @@ jobs:
           && tar -xvf ${{ runner.temp }}/dart-sass.tar.gz -C ${{ runner.temp }}/ \
           && echo "${{ runner.temp }}/dart-sass" >> $GITHUB_PATH
       - name: Checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: true
       - name: Setup Pages
         id: pages
-        uses: actions/configure-pages@v5
+        uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
       - name: Install Node.js dependencies
         run: |
           cd hugo
           [[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true
-      - name: Build with Hugo
+      - name: Build with Hugo # zizmor: ignore[template-injection] configure-pages considered safe
         env:
           # For maximum backward compatibility with Hugo modules
           HUGO_ENVIRONMENT: production
@@ -62,12 +62,15 @@ jobs:
             --minify \
             --baseURL "${{ steps.pages.outputs.base_url }}/"
       - name: Upload artifact
-        uses: actions/upload-pages-artifact@v3
+        uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
         with:
           path: ./hugo/public
 
   # Deployment job
   deploy:
+    permissions:
+      pages: write
+      id-token: write
     environment:
       name: github-pages
       url: ${{ steps.deployment.outputs.page_url }}
@@ -76,4 +79,4 @@ jobs:
     steps:
       - name: Deploy to GitHub Pages
         id: deployment
-        uses: actions/deploy-pages@v4
+        uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
diff --git a/.github/workflows/labeler.yaml b/.github/workflows/labeler.yaml
index e57cd86e2..4d8a7506a 100644
--- a/.github/workflows/labeler.yaml
+++ b/.github/workflows/labeler.yaml
@@ -1,5 +1,5 @@
 name: "Pull Request Labeler"
-on:
+on: # zizmor: ignore[dangerous-triggers] pull_request target used here as per recommendation from GitHub in actions/labeler
 - pull_request_target
 
 jobs:
@@ -9,4 +9,4 @@ jobs:
       pull-requests: write
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/labeler@v5
+    - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5
diff --git a/.github/workflows/pr-hugo.yaml b/.github/workflows/pr-hugo.yaml
index 0c2815c4a..72d5a79b0 100644
--- a/.github/workflows/pr-hugo.yaml
+++ b/.github/workflows/pr-hugo.yaml
@@ -7,6 +7,9 @@ defaults:
   run:
     shell: bash
 
+permissions:
+  contents: read
+
 jobs:
   # Build job
   build:
@@ -25,15 +28,17 @@ jobs:
           && tar -xvf ${{ runner.temp }}/dart-sass.tar.gz -C ${{ runner.temp }}/ \
           && echo "${{ runner.temp }}/dart-sass" >> $GITHUB_PATH
       - name: Checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
       - name: Setup Pages
         id: pages
-        uses: actions/configure-pages@v5
+        uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
       - name: Install Node.js dependencies
         run: |
           cd hugo
           [[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true
-      - name: Build with Hugo
+      - name: Build with Hugo # zizmor: ignore[template-injection] configure-pages considered safe
         env:
           # For maximum backward compatibility with Hugo modules
           HUGO_ENVIRONMENT: production
diff --git a/.github/workflows/pr-validation.yaml b/.github/workflows/pr-validation.yaml
index 1cc69648a..0b2956b96 100644
--- a/.github/workflows/pr-validation.yaml
+++ b/.github/workflows/pr-validation.yaml
@@ -11,32 +11,36 @@ jobs:
   pre-commit:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
 
-      - uses: actions/setup-python@v5
+      - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
         with:
           python-version: "3.13"
 
-      - uses: pre-commit/action@v3.0.1
+      - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
 
   go-lint:
     runs-on: ubuntu-latest
     steps:
       - name: Clone repo
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
 
       - name: Setup go
-        uses: actions/setup-go@v5
+        uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
         with:
           go-version-file: "go.mod"
 
       - name: golangci-lint (root module)
-        uses: golangci/golangci-lint-action@v7.0.0
+        uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd # v7.0.0
         with:
           version: v2.0.2
 
       - name: golangci-lint (api module)
-        uses: golangci/golangci-lint-action@v7.0.0
+        uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd # v7.0.0
         with:
           install-mode: none
           working-directory: api
@@ -49,10 +53,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Clone repo
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
 
       - name: Setup go
-        uses: actions/setup-go@v5
+        uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
         with:
           go-version-file: "go.mod"
 
@@ -72,10 +78,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Clone repo
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
 
       - name: Setup go
-        uses: actions/setup-go@v5
+        uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
         with:
           go-version-file: "go.mod"
 
@@ -102,10 +110,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Clone repo
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
 
       - name: Setup go
-        uses: actions/setup-go@v5
+        uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
         with:
           go-version-file: "go.mod"
 
@@ -123,10 +133,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Clone repo
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
 
       - name: Run Trivy vulnerability scanner
-        uses: aquasecurity/trivy-action@master
+        uses: aquasecurity/trivy-action@99baf0d8b4e787c3cfd7b602664c8ce60a43cd38 # master
         with:
           scan-type: "fs"
           scan-ref: "."
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 11ade54c2..fdcc64682 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -6,24 +6,25 @@ on:
       - v5.*
 
 permissions:
-  contents: write
-  packages: write
+  packages: write # zizmor: ignore[excessive-permissions] needed by all jobs as they publish OCI packages to ghcr.io
 
 env:
   CR_INDEX_PATH: "${{ github.workspace }}/.cr-index"
   CR_TOOL_PATH: "${{ github.workspace }}/.cr-tool"
+  RELEASE_NAME: ${{ github.ref_name }}
 
 jobs:
   helm:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
         with:
           path: source
+          persist-credentials: false
 
       - name: Install Helm
-        uses: azure/setup-helm@v4
+        uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 # v4
         with:
           version: v3.16.2
 
@@ -36,13 +37,15 @@ jobs:
           echo "HELM_REPO=$HELM_REPO" >> $GITHUB_ENV
 
       - name: Publish Helm charts
+        env:
+          RELEASE_ACTOR: ${{ github.actor }}
         run: |
           cd source/deploy/helm
           yq -i '.image.repository = "${{ env.GHCR_REPO }}"' grafana-operator/values.yaml
-          helm registry login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io
-          helm package --app-version ${{ github.ref_name }} --version ${{ github.ref_name }} grafana-operator
+          helm registry login -u "${RELEASE_ACTOR}" -p ${{ secrets.GITHUB_TOKEN }} ghcr.io
+          helm package --app-version ${RELEASE_NAME} --version ${RELEASE_NAME} grafana-operator
 
-          helm push grafana-operator-${{ github.ref_name }}.tgz ${{ env.HELM_REPO }}
+          helm push "grafana-operator-${RELEASE_NAME}.tgz" ${{ env.HELM_REPO }}
 
       - name: Install CR tool
         run: |
@@ -53,18 +56,18 @@ jobs:
           rm -f cr.tar.gz
 
       - name: Create a GitHub App installation access token
-        uses: tibdex/github-app-token@v2
+        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2
         id: app-token
         with:
           app_id: ${{ secrets.GRAFANA_OPERATOR_HELM_RELEASE_APP_ID }}
           private_key: ${{ secrets.GRAFANA_OPERATOR_HELM_RELEASE_PEM_KEY }}
 
-      - name: Set the correct token (Github App or PAT)
+      - name: Set the correct token (Github App or PAT) # zizmor: ignore[template-injection] app token considered safe
         run: |
           echo "AUTHTOKEN=${{ steps.app-token.outputs.token }}" >> $GITHUB_ENV
 
       - name: Make github release
-        uses: softprops/action-gh-release@v2
+        uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2
         with:
           body: |
             Helm chart for the [grafana-operator](https://github.com/${{ github.repository }}
@@ -76,8 +79,8 @@ jobs:
           tag_name: grafana-operator-${{ github.ref_name }}
           token: ${{ env.AUTHTOKEN }}
 
-      - name: Checkout helm-charts
-        uses: actions/checkout@v4
+      - name: Checkout helm-charts # zizmor: ignore[artipacked] required to push using chart releaser in last step
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
         with:
           fetch-depth: 0
           repository: grafana/helm-charts
@@ -97,11 +100,15 @@ jobs:
 
   kustomize:
     runs-on: ubuntu-latest
+    permissions:
+      contents: write
     steps:
       - name: install flux
-        uses: fluxcd/flux2/action@v2.5.1
+        uses: fluxcd/flux2/action@8d5f40dca5aa5d3c0fc3414457dda15a0ac92fa4 # v2.5.1
       - name: Clone repo
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
       - name: Prepare
         run: |
           # OCI standard enforces lower-case paths
@@ -115,19 +122,21 @@ jobs:
           make kustomize
           # Update image to match the new image and tag
           cd deploy/kustomize/base
-          kustomize edit set image ghcr.io/${{ github.repository }}=${{ env.GHCR_REPO }}:${{ github.ref_name }}
+          kustomize edit set image ghcr.io/${{ github.repository }}=${{ env.GHCR_REPO }}:${RELEASE_NAME}
       - name: Login to GitHub Container Registry
-        uses: docker/login-action@v3
+        uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
           password: ${{ secrets.GITHUB_TOKEN }}
       - name: Publish Kustomize OCI artifact to GHCR
+        env:
+          PUBLISH_SOURCE: ${{ github.event.repository.html_url }}
         run: |
-          flux push artifact ${{ env.KUSTOMIZE_REPO }}:${{ github.ref_name }} \
+          flux push artifact ${{ env.KUSTOMIZE_REPO }}:${RELEASE_NAME} \
             --path="./deploy/kustomize" \
-            --source="${{ github.event.repository.html_url }}" \
-            --revision="${GITHUB_REF_NAME}/${GITHUB_SHA}"
+            --source="${PUBLISH_SOURCE}" \
+            --revision="${RELEASE_NAME}/${GITHUB_SHA}"
       - name: update-kustomize-assert
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -136,39 +145,40 @@ jobs:
             kustomize build "$d" --load-restrictor LoadRestrictionsNone > kustomize-$(basename "$d").yaml
           done
           kustomize build config/crd > crds.yaml
-          gh release upload "${{ github.ref_name }}" kustomize-*.yaml crds.yaml
+          gh release upload "${RELEASE_NAME}" kustomize-*.yaml crds.yaml
 
   image:
     runs-on: ubuntu-latest
     steps:
       - name: Clone repo
-        uses: actions/checkout@v4
-
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
       - name: Login to GitHub Container Registry
-        uses: docker/login-action@v3
+        uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
           password: ${{ secrets.GITHUB_TOKEN }}
 
       - name: Login to Quay.io
-        uses: docker/login-action@v3
+        uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
         with:
           registry: quay.io
           username: ${{ secrets.QUAY_USERNAME }}
           password: ${{ secrets.QUAY_PASSWORD }}
 
-      - uses: actions/setup-go@v5
+      - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
         with:
           go-version-file: "go.mod"
-          cache: true
+          cache: false
 
-      - uses: ko-build/setup-ko@v0.9
+      - uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
         with:
           version: v0.16.0
 
       - name: Install cosign
-        uses: sigstore/cosign-installer@v3.8.1
+        uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
         with:
           cosign-release: "v2.2.2"
 
@@ -178,16 +188,18 @@ jobs:
           echo "REPOS"="quay.io/grafana-operator/grafana-operator" "ghcr.io/${{ github.repository }}" >> $GITHUB_ENV
 
       - name: Build and push
+        env:
+          IMAGE_VERSION: ${{ github.ref_name }}
         run: |
           for i in ${{ env.REPOS }}
           do
             export KO_DOCKER_REPO=${i}
-            ko build --sbom=spdx --image-refs ./image-digest-${i%.*} --bare --platform linux/arm64,linux/arm/v7,linux/amd64,linux/ppc64le -t ${{ github.ref_name }} \
+            ko build --sbom=spdx --image-refs ./image-digest-${i%.*} --bare --platform linux/arm64,linux/arm/v7,linux/amd64,linux/ppc64le -t ${IMAGE_VERSION} \
             --image-label org.opencontainers.image.title=grafana-operator \
             --image-label org.opencontainers.image.description="An operator for Grafana that installs and manages Grafana instances & Dashboards & Datasources through Kubernetes/OpenShift CRs" \
             --image-label org.opencontainers.image.url=${{ github.server_url }}/${{ github.repository }} \
             --image-label org.opencontainers.image.revision=${{ github.sha }} \
-            --image-label org.opencontainers.image.version=${{ github.ref_name }} \
+            --image-label org.opencontainers.image.version=${IMAGE_VERSION} \
             --image-label org.opencontainers.image.created=${{ env.BUILD_DATE }}
           done
 
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 64795f0eb..260932be2 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -17,7 +17,7 @@ jobs:
       pull-requests: write
 
     steps:
-      - uses: actions/stale@v9
+      - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9
         with:
           repo-token: ${{ secrets.GITHUB_TOKEN }}
           stale-issue-message: "This issue hasn't been updated for a while, marking as stale, please respond within the next 7 days to remove this label"


Reviews:
user: login: theSuess
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-28T12:21:35Z
user: login: weisdd
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-04-28T14:13:18Z
user: login: Baarsgaard
body: There's less changes than I expected!
Is it possible to run the actions before we merge?
Even if it just verifies that all the commit hashes are valid?
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-28T14:49:47Z
user: login: theSuess
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-29T08:07:20Z
user: login: theSuess
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-29T08:08:19Z
user: login: weisdd
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-29T08:18:40Z
user: login: weisdd
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-29T08:18:59Z

Review comments:
diff_hunk: @@ -32,13 +34,6 @@ jobs:
             **/*.html
             hugo/**
 
-      - id: which_files
-        name: Which files was changed
-        run: |
-          echo "One or more files has changed."
-          echo "List all the files that have changed: ${{ steps.changed-files.outputs.all_changed_files }}"
-          echo "What is any changed ${{ steps.changed-files.outputs.any_changed }}"
-
path: .github/workflows/e2e.yaml
user: login: theSuess
body: Hard to properly escape this here and since we usually don't need this debug step, I just removed it
created_at: 2025-04-28T12:21:31Z
author_association: COLLABORATOR
diff_hunk: @@ -136,39 +145,40 @@ jobs:
             kustomize build "$d" --load-restrictor LoadRestrictionsNone > kustomize-$(basename "$d").yaml
           done
           kustomize build config/crd > crds.yaml
-          gh release upload "${{ github.ref_name }}" kustomize-*.yaml crds.yaml
+          gh release upload "${RELEASE_NAME}" kustomize-*.yaml crds.yaml
 
   image:
     runs-on: ubuntu-latest
     steps:
       - name: Clone repo
-        uses: actions/checkout@v4
-
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
       - name: Login to GitHub Container Registry
-        uses: docker/login-action@v3
+        uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
           password: ${{ secrets.GITHUB_TOKEN }}
 
       - name: Login to Quay.io
-        uses: docker/login-action@v3
+        uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
         with:
           registry: quay.io
           username: ${{ secrets.QUAY_USERNAME }}
           password: ${{ secrets.QUAY_PASSWORD }}
 
-      - uses: actions/setup-go@v5
+      - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
         with:
           go-version-file: "go.mod"
-          cache: true
+          cache: false
path: .github/workflows/release.yaml
user: login: weisdd
body: Any reason to disable cache here?
created_at: 2025-04-28T14:11:36Z
author_association: COLLABORATOR
diff_hunk: @@ -36,13 +37,15 @@ jobs:
           echo "HELM_REPO=$HELM_REPO" >> $GITHUB_ENV
 
       - name: Publish Helm charts
+        env:
+          RELEASE_ACTOR: ${{ github.actor }}
         run: |
           cd source/deploy/helm
           yq -i '.image.repository = "${{ env.GHCR_REPO }}"' grafana-operator/values.yaml
-          helm registry login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io
-          helm package --app-version ${{ github.ref_name }} --version ${{ github.ref_name }} grafana-operator
+          helm registry login -u "${RELEASE_ACTOR}" -p ${{ secrets.GITHUB_TOKEN }} ghcr.io
path: .github/workflows/release.yaml
user: login: weisdd
body: For such things, you can already rely on the set of environment variables that GitHub provides (`GITHUB_ACTOR`,  `GITHUB_REF_NAME`, etc). Not saying that you necessarily have to change this and in other workflows, just wanted to mention that.
created_at: 2025-04-28T14:13:15Z
author_association: COLLABORATOR
diff_hunk: @@ -136,39 +145,40 @@ jobs:
             kustomize build "$d" --load-restrictor LoadRestrictionsNone > kustomize-$(basename "$d").yaml
           done
           kustomize build config/crd > crds.yaml
-          gh release upload "${{ github.ref_name }}" kustomize-*.yaml crds.yaml
+          gh release upload "${RELEASE_NAME}" kustomize-*.yaml crds.yaml
 
   image:
     runs-on: ubuntu-latest
     steps:
       - name: Clone repo
-        uses: actions/checkout@v4
-
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          persist-credentials: false
       - name: Login to GitHub Container Registry
-        uses: docker/login-action@v3
+        uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
           password: ${{ secrets.GITHUB_TOKEN }}
 
       - name: Login to Quay.io
-        uses: docker/login-action@v3
+        uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
         with:
           registry: quay.io
           username: ${{ secrets.QUAY_USERNAME }}
           password: ${{ secrets.QUAY_PASSWORD }}
 
-      - uses: actions/setup-go@v5
+      - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
         with:
           go-version-file: "go.mod"
-          cache: true
+          cache: false
path: .github/workflows/release.yaml
user: login: theSuess
body: It's possible to perform cache poisoning attacks by poisoning the cache in unprivileged workflows and then using the elevated permissions of the release workflow: https://woodruffw.github.io/zizmor/audits/#cache-poisoning
created_at: 2025-04-29T08:07:20Z
author_association: COLLABORATOR
diff_hunk: @@ -36,13 +37,15 @@ jobs:
           echo "HELM_REPO=$HELM_REPO" >> $GITHUB_ENV
 
       - name: Publish Helm charts
+        env:
+          RELEASE_ACTOR: ${{ github.actor }}
         run: |
           cd source/deploy/helm
           yq -i '.image.repository = "${{ env.GHCR_REPO }}"' grafana-operator/values.yaml
-          helm registry login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io
-          helm package --app-version ${{ github.ref_name }} --version ${{ github.ref_name }} grafana-operator
+          helm registry login -u "${RELEASE_ACTOR}" -p ${{ secrets.GITHUB_TOKEN }} ghcr.io
path: .github/workflows/release.yaml
user: login: theSuess
body: I like explicitly setting the env vars to show the underlying structure (and just really dislike "magic" env vars)
created_at: 2025-04-29T08:08:18Z
author_association: COLLABORATOR
diff_hunk: @@ -36,13 +37,15 @@ jobs:
           echo "HELM_REPO=$HELM_REPO" >> $GITHUB_ENV
 
       - name: Publish Helm charts
+        env:
+          RELEASE_ACTOR: ${{ github.actor }}
         run: |
           cd source/deploy/helm
           yq -i '.image.repository = "${{ env.GHCR_REPO }}"' grafana-operator/values.yaml
-          helm registry login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io
-          helm package --app-version ${{ github.ref_name }} --version ${{ github.ref_name }} grafana-operator
+          helm registry login -u "${RELEASE_ACTOR}" -p ${{ secrets.GITHUB_TOKEN }} ghcr.io
path: .github/workflows/release.yaml
user: login: weisdd
body: Well, `github` context is the same kind of magic, because there's 1:1 mapping between the two :)
created_at: 2025-04-29T08:18:40Z
author_association: COLLABORATOR

PR comments:
user: login: theSuess
created_at: 2025-04-29T08:15:31Z
body: I've manually cross-referenced all commit hashes so they should be good. When the security team comes around to reviewing our repo, they'll re-enable actions and they'll run for this PR before merging
author_association: COLLABORATOR
user: login: theSuess
created_at: 2025-04-30T05:19:24Z
body: thanks for fixing the outstanding issue @Baarsgaard !
author_association: COLLABORATOR