From 1d6771355cba970a2f92ff3423a0ac54fd55f86c Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Sun, 22 Mar 2026 20:01:09 +0100 Subject: [PATCH 1/6] fix(ci): pin GitHub Actions to SHA digests for supply chain security Pin all external GitHub Action references to commit SHA digests instead of mutable version tags to prevent supply chain attacks via tag reassignment. Signed-off-by: Miguel Martinez Trivino --- .../workflows/build_external_container_images.yaml | 14 +++++++------- .github/workflows/package_chart.yaml | 2 +- .github/workflows/scm_configuration_check.yaml | 4 ++-- .github/workflows/secrets-scan-daily.yml | 2 +- .github/workflows/sync_contracts.yml | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build_external_container_images.yaml b/.github/workflows/build_external_container_images.yaml index 92ebe19c8..7876dbfcb 100644 --- a/.github/workflows/build_external_container_images.yaml +++ b/.github/workflows/build_external_container_images.yaml @@ -77,10 +77,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Checkout Bitnami containers repository - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: repository: bitnami/containers path: ${{ env.BITNAMI_PATH }} @@ -100,10 +100,10 @@ jobs: echo "Extracted ${{ matrix.image.name }} version: $VERSION" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Log in to the Container registry - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -111,7 +111,7 @@ jobs: - name: Extract metadata id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | @@ -121,7 +121,7 @@ jobs: - name: Build and push Docker image id: build - uses: docker/build-push-action@v5 + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5 with: context: ${{ env.BITNAMI_PATH }}/${{ matrix.image.path }} platforms: linux/amd64,linux/arm64 @@ -130,7 +130,7 @@ jobs: labels: ${{ steps.meta.outputs.labels }} - name: Install Cosign - uses: sigstore/cosign-installer@v3 + uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3 with: cosign-release: "v2.4.1" diff --git a/.github/workflows/package_chart.yaml b/.github/workflows/package_chart.yaml index 7cf5b0e67..3cfa8c146 100644 --- a/.github/workflows/package_chart.yaml +++ b/.github/workflows/package_chart.yaml @@ -36,7 +36,7 @@ jobs: uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5 - name: Install Cosign - uses: sigstore/cosign-installer@v3.7.0 + uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 with: cosign-release: "v2.4.1" diff --git a/.github/workflows/scm_configuration_check.yaml b/.github/workflows/scm_configuration_check.yaml index f8101ff7e..9cd4e9949 100644 --- a/.github/workflows/scm_configuration_check.yaml +++ b/.github/workflows/scm_configuration_check.yaml @@ -21,7 +21,7 @@ jobs: GITHUB_TOKEN: ${{ github.token }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Install Chainloop run: | @@ -33,7 +33,7 @@ jobs: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2 with: app-id: ${{ vars.CHAINLOOP_GATHERER_APP_ID }} private-key: ${{ secrets.GATHERER_APP_PRIVATE_KEY }} diff --git a/.github/workflows/secrets-scan-daily.yml b/.github/workflows/secrets-scan-daily.yml index 601a0a5ed..60ba52b99 100644 --- a/.github/workflows/secrets-scan-daily.yml +++ b/.github/workflows/secrets-scan-daily.yml @@ -20,7 +20,7 @@ jobs: CHAINLOOP_PROJECT_NAME: "chainloop" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Install Chainloop run: | diff --git a/.github/workflows/sync_contracts.yml b/.github/workflows/sync_contracts.yml index e4090ec64..da218bce8 100644 --- a/.github/workflows/sync_contracts.yml +++ b/.github/workflows/sync_contracts.yml @@ -18,7 +18,7 @@ jobs: CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_TOKEN }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Install Chainloop run: | curl -sfL https://dl.chainloop.dev/cli/install.sh | bash -s From 07050ebdca7f4ca2dac5adfad7d0d9e8b911696f Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Sun, 22 Mar 2026 20:20:31 +0100 Subject: [PATCH 2/6] chore: remove chainloop-chainloop-github-release contract Signed-off-by: Miguel Martinez Trivino --- .../chainloop-chainloop-github-release.yaml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/contracts/chainloop-chainloop-github-release.yaml diff --git a/.github/workflows/contracts/chainloop-chainloop-github-release.yaml b/.github/workflows/contracts/chainloop-chainloop-github-release.yaml deleted file mode 100644 index 67c0fb725..000000000 --- a/.github/workflows/contracts/chainloop-chainloop-github-release.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# contract used in release workflow -apiVersion: chainloop.dev/v1 -kind: Contract -metadata: - name: chainloop-chainloop-github-release - description: Contract for Chainloop GitHub release workflow -spec: - policies: - attestation: - - ref: source-commit - with: - check_signature: yes - policyGroups: - - ref: slsa-checks - with: - runner: GITHUB_ACTION - - ref: vulnerability-management - with: - severity: "HIGH" From fc85a31fe00964e3c92c22d5cb2b0c720c3a0658 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Sun, 22 Mar 2026 20:27:45 +0100 Subject: [PATCH 3/6] feat(ci): add PR validation contract and workflow Add Chainloop contract and GitHub Actions workflow for PR attestation on the chainloop-platform project. Enforces commit signatures, PR description quality, and GitHub issue linking. Signed-off-by: Miguel Martinez Trivino --- .../workflows/contracts/pr-validation.yaml | 22 +++++++ .github/workflows/pr_validation.yaml | 61 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 .github/workflows/contracts/pr-validation.yaml create mode 100644 .github/workflows/pr_validation.yaml diff --git a/.github/workflows/contracts/pr-validation.yaml b/.github/workflows/contracts/pr-validation.yaml new file mode 100644 index 000000000..77710c493 --- /dev/null +++ b/.github/workflows/contracts/pr-validation.yaml @@ -0,0 +1,22 @@ +apiVersion: chainloop.dev/v1 +kind: Contract +metadata: + name: pr-validation + description: Contract for Chainloop Platform PR Validation Workflow +spec: + policies: + attestation: + - ref: source-commit + with: + check_signature: "true" + check_author_verified: "true" + gate: true + materials: + - ref: pr-description-required + gate: true + with: + min_length: "10" + - ref: pr-user-story-linked + gate: true + with: + patterns: "#[0-9]+,gh-[0-9]+" diff --git a/.github/workflows/pr_validation.yaml b/.github/workflows/pr_validation.yaml new file mode 100644 index 000000000..8f5587edd --- /dev/null +++ b/.github/workflows/pr_validation.yaml @@ -0,0 +1,61 @@ +name: PR Attestation + +on: + pull_request: + # Trigger on the following PR events: + # - opened: when PR is created + # - synchronize: when new commits are pushed to the PR + # - reopened: when a closed PR is reopened + # - edited: when PR title/description is updated + # - closed: when PR is closed or merged + # - ready_for_review: when a draft PR is marked as ready for review + types: [opened, synchronize, reopened, edited, closed, ready_for_review] + branches: + - main + +permissions: + contents: read + id-token: write # Required for GitHub keyless attestation via OIDC + pull-requests: read # Required to fetch PR reviews + +jobs: + # Create and push a Chainloop attestation for this PR event + attestation: + if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.user.login != 'github-actions[bot]' && github.event.pull_request.draft == false }} + name: Perform PR Validation + runs-on: ubuntu-latest + env: + CHAINLOOP_WORKFLOW_NAME: pr-validation + CHAINLOOP_PROJECT_NAME: chainloop-platform + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + # Install Chainloop Enterprise Edition CLI + - name: Install Chainloop + run: | + curl -sfL https://dl.chainloop.dev/cli/install.sh | bash -s -- --ee + + # Initialize a new attestation for this PR event + - name: Initialize Attestation + run: | + chainloop attestation init --workflow ${CHAINLOOP_WORKFLOW_NAME} --project ${CHAINLOOP_PROJECT_NAME} --collectors aiconfig + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Push the attestation to Chainloop if all steps succeeded + - name: Finish and Push Attestation + if: ${{ success() }} + run: | + chainloop attestation push + + # Mark attestation as failed if any step failed + - name: Mark attestation as failed + if: ${{ failure() }} + run: | + chainloop attestation reset + + # Mark attestation as cancelled if workflow was cancelled + - name: Mark attestation as cancelled + if: ${{ cancelled() }} + run: | + chainloop attestation reset --trigger cancellation From a311dc8140e00ca536e793bdaeadb5744e590ec7 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Sun, 22 Mar 2026 20:40:19 +0100 Subject: [PATCH 4/6] fix(ci): fix PR validation workflow permissions and config Move permissions to job level with read-all at workflow level, remove --collectors aiconfig flag, and fix project name to chainloop. Signed-off-by: Miguel Martinez Trivino --- .github/workflows/pr_validation.yaml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pr_validation.yaml b/.github/workflows/pr_validation.yaml index 8f5587edd..9891b1c50 100644 --- a/.github/workflows/pr_validation.yaml +++ b/.github/workflows/pr_validation.yaml @@ -13,10 +13,7 @@ on: branches: - main -permissions: - contents: read - id-token: write # Required for GitHub keyless attestation via OIDC - pull-requests: read # Required to fetch PR reviews +permissions: read-all jobs: # Create and push a Chainloop attestation for this PR event @@ -24,9 +21,13 @@ jobs: if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.user.login != 'github-actions[bot]' && github.event.pull_request.draft == false }} name: Perform PR Validation runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + pull-requests: read env: CHAINLOOP_WORKFLOW_NAME: pr-validation - CHAINLOOP_PROJECT_NAME: chainloop-platform + CHAINLOOP_PROJECT_NAME: chainloop steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 @@ -38,7 +39,7 @@ jobs: # Initialize a new attestation for this PR event - name: Initialize Attestation run: | - chainloop attestation init --workflow ${CHAINLOOP_WORKFLOW_NAME} --project ${CHAINLOOP_PROJECT_NAME} --collectors aiconfig + chainloop attestation init --workflow ${CHAINLOOP_WORKFLOW_NAME} --project ${CHAINLOOP_PROJECT_NAME} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From e6db74a0e4e0ecf65e55942d7a8bd03359f6abab Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Sun, 22 Mar 2026 20:41:29 +0100 Subject: [PATCH 5/6] chore(ci): add debug flag to PR validation attestation init Signed-off-by: Miguel Martinez Trivino --- .github/workflows/pr_validation.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_validation.yaml b/.github/workflows/pr_validation.yaml index 9891b1c50..d42dcdaf9 100644 --- a/.github/workflows/pr_validation.yaml +++ b/.github/workflows/pr_validation.yaml @@ -39,7 +39,7 @@ jobs: # Initialize a new attestation for this PR event - name: Initialize Attestation run: | - chainloop attestation init --workflow ${CHAINLOOP_WORKFLOW_NAME} --project ${CHAINLOOP_PROJECT_NAME} + chainloop attestation init --workflow ${CHAINLOOP_WORKFLOW_NAME} --project ${CHAINLOOP_PROJECT_NAME} --debug env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 7d491d09e643fd5daa43f536ea461d0194ac8c09 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Sun, 22 Mar 2026 20:46:00 +0100 Subject: [PATCH 6/6] revert(ci): remove PR validation workflow and contract OIDC id-token is not available for fork PRs, making keyless attestation impossible for external contributions. Signed-off-by: Miguel Martinez Trivino --- .../workflows/contracts/pr-validation.yaml | 22 ------- .github/workflows/pr_validation.yaml | 62 ------------------- 2 files changed, 84 deletions(-) delete mode 100644 .github/workflows/contracts/pr-validation.yaml delete mode 100644 .github/workflows/pr_validation.yaml diff --git a/.github/workflows/contracts/pr-validation.yaml b/.github/workflows/contracts/pr-validation.yaml deleted file mode 100644 index 77710c493..000000000 --- a/.github/workflows/contracts/pr-validation.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: chainloop.dev/v1 -kind: Contract -metadata: - name: pr-validation - description: Contract for Chainloop Platform PR Validation Workflow -spec: - policies: - attestation: - - ref: source-commit - with: - check_signature: "true" - check_author_verified: "true" - gate: true - materials: - - ref: pr-description-required - gate: true - with: - min_length: "10" - - ref: pr-user-story-linked - gate: true - with: - patterns: "#[0-9]+,gh-[0-9]+" diff --git a/.github/workflows/pr_validation.yaml b/.github/workflows/pr_validation.yaml deleted file mode 100644 index d42dcdaf9..000000000 --- a/.github/workflows/pr_validation.yaml +++ /dev/null @@ -1,62 +0,0 @@ -name: PR Attestation - -on: - pull_request: - # Trigger on the following PR events: - # - opened: when PR is created - # - synchronize: when new commits are pushed to the PR - # - reopened: when a closed PR is reopened - # - edited: when PR title/description is updated - # - closed: when PR is closed or merged - # - ready_for_review: when a draft PR is marked as ready for review - types: [opened, synchronize, reopened, edited, closed, ready_for_review] - branches: - - main - -permissions: read-all - -jobs: - # Create and push a Chainloop attestation for this PR event - attestation: - if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.user.login != 'github-actions[bot]' && github.event.pull_request.draft == false }} - name: Perform PR Validation - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - pull-requests: read - env: - CHAINLOOP_WORKFLOW_NAME: pr-validation - CHAINLOOP_PROJECT_NAME: chainloop - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - # Install Chainloop Enterprise Edition CLI - - name: Install Chainloop - run: | - curl -sfL https://dl.chainloop.dev/cli/install.sh | bash -s -- --ee - - # Initialize a new attestation for this PR event - - name: Initialize Attestation - run: | - chainloop attestation init --workflow ${CHAINLOOP_WORKFLOW_NAME} --project ${CHAINLOOP_PROJECT_NAME} --debug - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # Push the attestation to Chainloop if all steps succeeded - - name: Finish and Push Attestation - if: ${{ success() }} - run: | - chainloop attestation push - - # Mark attestation as failed if any step failed - - name: Mark attestation as failed - if: ${{ failure() }} - run: | - chainloop attestation reset - - # Mark attestation as cancelled if workflow was cancelled - - name: Mark attestation as cancelled - if: ${{ cancelled() }} - run: | - chainloop attestation reset --trigger cancellation