From 4ad54ece8b73229d6af3384835b58e31bd8399f1 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Fri, 3 Jul 2026 10:54:20 +0200 Subject: [PATCH 1/2] fix: harden GitHub Actions workflows against zizmor findings Fix all high-severity and artipacked findings from zizmor audit: - template-injection (6 high): route github.ref_name through env vars in release.yaml steps instead of inline interpolation in run blocks - github-app (1 high): scope create-github-app-token permissions with permission-contents/permission-metadata inputs, upgrade to v3.2.0 - cache-poisoning (1 high): disable setup-go cache in release job - artipacked (14 medium): add persist-credentials: false to all actions/checkout steps that don't need git push Assisted-by: Claude Code Signed-off-by: Miguel Martinez Trivino --- .github/workflows/author_verification.yml | 2 ++ .../build_external_container_images.yaml | 3 +++ .github/workflows/codeql.yml | 2 ++ .github/workflows/lint.yml | 6 +++++ .github/workflows/package_chart.yaml | 2 ++ .github/workflows/release.yaml | 24 ++++++++++++++----- .../workflows/scm_configuration_check.yaml | 6 ++++- .github/workflows/secrets-scan-daily.yml | 2 ++ .github/workflows/sync_contracts.yml | 2 ++ .github/workflows/test.yml | 2 ++ 10 files changed, 44 insertions(+), 7 deletions(-) diff --git a/.github/workflows/author_verification.yml b/.github/workflows/author_verification.yml index 714b2bd73..5657ec6ac 100644 --- a/.github/workflows/author_verification.yml +++ b/.github/workflows/author_verification.yml @@ -24,6 +24,8 @@ jobs: - name: Checkout repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - name: Initialize Attestation run: | diff --git a/.github/workflows/build_external_container_images.yaml b/.github/workflows/build_external_container_images.yaml index 8c90f59bf..b96b5c667 100644 --- a/.github/workflows/build_external_container_images.yaml +++ b/.github/workflows/build_external_container_images.yaml @@ -80,6 +80,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - name: Checkout Bitnami containers repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 @@ -89,6 +91,7 @@ jobs: ref: ${{ matrix.image.ref }} sparse-checkout: ${{ matrix.image.sparse_checkout }} sparse-checkout-cone-mode: false + persist-credentials: false - name: Extract version from Bitnami Dockerfile id: extract_version diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fec86ea7c..b68eed98a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,6 +38,8 @@ jobs: - name: Checkout repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - name: Initialize Attestation if: ${{ github.event_name != 'pull_request' }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b77d0c300..808fed635 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -25,6 +25,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 @@ -50,6 +52,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - uses: bufbuild/buf-action@5150a1eef5c10b6a5cf8a69fc872f24a09473195 # v1.1.1 with: version: 1.49.0 @@ -67,6 +71,8 @@ jobs: curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.19.11 sh - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 diff --git a/.github/workflows/package_chart.yaml b/.github/workflows/package_chart.yaml index 3cfa8c146..d451741c2 100644 --- a/.github/workflows/package_chart.yaml +++ b/.github/workflows/package_chart.yaml @@ -41,6 +41,8 @@ jobs: cosign-release: "v2.4.1" - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - name: Package Chart run: helm package deployment/chainloop/ diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 5a68ad4c8..c279b8d43 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,6 +17,8 @@ jobs: id-token: write # required for SLSA provenance steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - name: Install Chainloop run: | @@ -69,6 +71,8 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - name: Initialize Attestation id: init_attestation @@ -92,6 +96,7 @@ jobs: uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: go-version-file: 'go.mod' + cache: false # install qemu binaries for multiarch builds (needed by goreleaser/buildx) - name: Setup qemu @@ -125,6 +130,7 @@ jobs: env: SYFT_GOLANG_SEARCH_REMOTE_LICENSES: "true" ATTESTATION_ID: ${{ steps.init_attestation.outputs.attestation_id }} + RELEASE_TAG: ${{ github.ref_name }} run: | # goreleaser output resides in dist/artifacts.json # Attest all built containers and manifests @@ -162,7 +168,7 @@ jobs: chainloop attestation add --name $sbom_name --value /tmp/sbom-$material_name.cyclonedx.json --kind SBOM_CYCLONEDX_JSON --attestation-id ${{ env.ATTESTATION_ID }} # Upload the SBOM to the release - gh release upload ${{ github.ref_name }} /tmp/sbom-$material_name.cyclonedx.json --clobber + gh release upload $RELEASE_TAG /tmp/sbom-$material_name.cyclonedx.json --clobber # Run Grype vulnerability scan and attest result grype --only-fixed -o sarif --file ./vuln-${container_name}.json $entry @@ -188,10 +194,11 @@ jobs: - name: Include source code on attestation env: ATTESTATION_ID: ${{ steps.init_attestation.outputs.attestation_id }} + RELEASE_TAG: ${{ github.ref_name }} run: | # This needs to run AFTER goreleaser to make sure the source code is available - gh release download ${{ github.ref_name }} -A tar.gz -O /tmp/source-code.tar.gz + gh release download $RELEASE_TAG -A tar.gz -O /tmp/source-code.tar.gz chainloop attestation add --name source-code --value /tmp/source-code.tar.gz --kind ARTIFACT --attestation-id ${{ env.ATTESTATION_ID }} - name: Read current project version @@ -201,9 +208,13 @@ jobs: echo "current_version=$current_version" >> $GITHUB_OUTPUT - name: Bump Chart and Dagger Version - run: .github/workflows/utils/bump-chart-and-dagger-version.sh deployment/chainloop extras/dagger ${{ github.ref_name }} + env: + RELEASE_TAG: ${{ github.ref_name }} + run: .github/workflows/utils/bump-chart-and-dagger-version.sh deployment/chainloop extras/dagger $RELEASE_TAG - name: Bump Project Version - run: .github/workflows/utils/bump-project-version.sh ${{ github.ref_name }} + env: + RELEASE_TAG: ${{ github.ref_name }} + run: .github/workflows/utils/bump-project-version.sh $RELEASE_TAG - name: Create Pull Request uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 @@ -248,9 +259,10 @@ jobs: if: ${{ success() }} env: ATTESTATION_SHA: ${{ steps.attestation_push.outputs.attestation_sha }} + RELEASE_TAG: ${{ github.ref_name }} run: | chainloop_release_url="## Chainloop Attestation"$'\n'"[View the attestation of this release](https://app.chainloop.dev/attestation/${{ env.ATTESTATION_SHA }})" - current_notes=$(gh release view ${{github.ref_name}} --json body -q '.body') + current_notes=$(gh release view $RELEASE_TAG --json body -q '.body') if echo "$current_notes" | grep -q "## Chainloop Attestation"; then # Replace the existing Chainloop Attestation section with the new URL @@ -261,7 +273,7 @@ jobs: fi # Update the release notes and ignore if it fails since we might be lacking permissions to update the release notes - gh release edit ${{github.ref_name}} -n "$modified_notes" || echo -n "Not enough permissions to edit the release notes. Skipping..." + gh release edit $RELEASE_TAG -n "$modified_notes" || echo -n "Not enough permissions to edit the release notes. Skipping..." - name: Mark attestation as failed if: ${{ failure() }} diff --git a/.github/workflows/scm_configuration_check.yaml b/.github/workflows/scm_configuration_check.yaml index 6e46d589f..419c7fb27 100644 --- a/.github/workflows/scm_configuration_check.yaml +++ b/.github/workflows/scm_configuration_check.yaml @@ -22,6 +22,8 @@ jobs: steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - name: Install Chainloop run: | @@ -33,10 +35,12 @@ jobs: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2 + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 with: app-id: ${{ vars.CHAINLOOP_GATHERER_APP_ID }} private-key: ${{ secrets.GATHERER_APP_PRIVATE_KEY }} + permission-contents: read + permission-metadata: read - name: Gather runner context data run: | diff --git a/.github/workflows/secrets-scan-daily.yml b/.github/workflows/secrets-scan-daily.yml index 547033e4c..2e3a41a33 100644 --- a/.github/workflows/secrets-scan-daily.yml +++ b/.github/workflows/secrets-scan-daily.yml @@ -21,6 +21,8 @@ jobs: steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - name: Install Chainloop run: | diff --git a/.github/workflows/sync_contracts.yml b/.github/workflows/sync_contracts.yml index da218bce8..c641b5a6d 100644 --- a/.github/workflows/sync_contracts.yml +++ b/.github/workflows/sync_contracts.yml @@ -19,6 +19,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - name: Install Chainloop run: | curl -sfL https://dl.chainloop.dev/cli/install.sh | bash -s diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 723b3a68a..8834a3372 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,6 +25,8 @@ jobs: - artifact-cas steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: From 2288c85787ee7cb249dde3d9697c19b3e24ffcc1 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Fri, 3 Jul 2026 11:42:14 +0200 Subject: [PATCH 2/2] fix: correct hash-pin version comments in GitHub Actions workflows Fix all 7 ref-version-mismatch findings from zizmor audit: - lint.yml (3x): fix golangci-lint-action comment from 9.2.0 to v9.2.0 - scorecards.yml (2x): fix scorecard-action comment from v2.3.1 to v2.4.0 and upload-artifact comment from v3.1.3 to v4.3.3 (hashes were already correct, comments were stale) - release.yaml: re-pin cosign-installer from a main branch commit to v3.2.0 (the closest stable tag after the pinned commit from Sept 2023) - test.yml: re-pin ent/contrib/ci from a master branch commit to v0.5.0 (the closest stable tag after the pinned commit from Sept 2023) Assisted-by: Claude Code Signed-off-by: Miguel Martinez Trivino --- .github/workflows/lint.yml | 6 +++--- .github/workflows/release.yaml | 2 +- .github/workflows/scorecards.yml | 4 ++-- .github/workflows/test.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 808fed635..069c92c1c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -34,14 +34,14 @@ jobs: go-version-file: 'go.mod' - name: Lint main module - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # 9.2.0 + uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0 if: ${{ matrix.app == 'main-module' }} with: version: v2.9.0 only-new-issues: 'true' - name: Lint ${{ matrix.app }} - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # 9.2.0 + uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0 if: ${{ matrix.app != 'main-module' }} with: working-directory: app/${{ matrix.app }} @@ -84,7 +84,7 @@ jobs: make -C extras/dagger module-init - name: Lint - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # 9.2.0 + uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0 with: working-directory: extras/dagger version: v2.9.0 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c279b8d43..baf9472c0 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -61,7 +61,7 @@ jobs: steps: - name: Install Cosign - uses: sigstore/cosign-installer@ef6a6b364bbad08abd36a5f8af60b595d12702f8 # main + uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 # v3.2.0 with: cosign-release: "v2.2.3" diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index ee165ae31..ffffb9619 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -47,7 +47,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.3.1 + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: results.sarif results_format: sarif @@ -69,7 +69,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v3.1.3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: # When downloading if not name is set the artifact name will be "artifact" # We need to specify the name to download it later diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8834a3372..bae8fafb1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -53,7 +53,7 @@ jobs: # Check that the generated ent code is up to date # see https://entgo.io/docs/ci/ - - uses: ent/contrib/ci@e38dfb6484dfbe64b8bd060fe6a219a1aa5da770 # master + - uses: ent/contrib/ci@4ec197664a206890a44245f5c0cbcb8110d68cb5 # v0.5.0 name: "Check all ent generated code is checked in" if: ${{ matrix.app != 'main-module' }} with: