Browse Source

fix: cosign compatibility issues (#5959)

* fix: attempt to fix ci pipeline

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: e2e tests with old docker buildx

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: coderabbit issues -- thanks coderabbit

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: force old bundle format for verify-attestation

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: typo

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: use-signing-config to false

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: verify attestation does not use signing config

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: readd arm64 for -ubi-boringssl

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: remove bundle format from verify attestation

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: cosign regression on 3.0.4 prevents old pipelines from working (despite flags)

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: ci bloat and provenance version

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

* fix: replace slsa-provenance-action with custom bash

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>

---------

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>
Gustavo Fernandes de Carvalho 1 month ago
parent
commit
09741b0c54

+ 2 - 3
.github/actions/e2e/action.yml

@@ -47,10 +47,9 @@ runs:
         name: external-secrets
 
     - name: Setup Docker Buildx
-      # https://github.com/docker/setup-buildx-action/releases/tag/v2.10.0
-      uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v2.10.0
+      # https://github.com/docker/setup-buildx-action/releases/tag/v3.12.0
+      uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
       with:
-        version: ${{ env.DOCKER_BUILDX_VERSION }}
         install: true
 
     - name: Run e2e Tests

+ 56 - 20
.github/actions/sign/action.yml

@@ -21,7 +21,7 @@ runs:
       # https://github.com/sigstore/cosign-installer/releases/tag/v4.0.0
       uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
       with:
-        cosign-release: 'v3.0.3'
+        cosign-release: 'v3.0.2'
 
     - name: Install Syft
       # https://github.com/anchore/sbom-action/releases/tag/v0.22.2
@@ -55,7 +55,13 @@ runs:
       env:
         IMAGE_NAME: ${{ inputs.image-name }}
         IMAGE_TAG: ${{ inputs.image-tag }}
-      run: echo "digest=$(crane digest ${IMAGE_NAME}:${IMAGE_TAG})" >> $GITHUB_OUTPUT
+      run: |
+        echo "::group::Crane digest lookup"
+        echo "Looking up digest for ${IMAGE_NAME}:${IMAGE_TAG}"
+        DIGEST=$(crane digest ${IMAGE_NAME}:${IMAGE_TAG})
+        echo "Found digest: ${DIGEST}"
+        echo "digest=${DIGEST}" >> $GITHUB_OUTPUT
+        echo "::endgroup::"
 
     - name: Sign image
       shell: bash
@@ -63,7 +69,11 @@ runs:
         IMAGE_NAME: ${{ inputs.image-name }}
         CONTAINER_DIGEST: ${{ steps.container_info.outputs.digest }}
         GITHUB_TRIGGERING_ACTOR: ${{ github.triggering_actor }}
-      run: cosign sign --yes -a GITHUB_ACTOR=${GITHUB_TRIGGERING_ACTOR} "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+      run: |
+        echo "::group::Cosign sign"
+        echo "Signing ${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        cosign sign --yes --new-bundle-format=false --use-signing-config=false -a GITHUB_ACTOR=${GITHUB_TRIGGERING_ACTOR} "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        echo "::endgroup::"
 
     - name: Attach SBOM to image
       shell: bash
@@ -73,33 +83,53 @@ runs:
         IMAGE_TAG: ${{ inputs.image-tag }}
         CONTAINER_DIGEST: ${{ steps.container_info.outputs.digest }}
       run: |
+        echo "::group::Image SBOM generation"
         # Image SBOM (OS + application libs contained in the image)
+        echo "Generating image SBOM for ${IMAGE_NAME}@${CONTAINER_DIGEST}"
         syft "${IMAGE_NAME}@${CONTAINER_DIGEST}" -o spdx-json=sbom.${IMAGE_TAG}.spdx.json
-        # cosign attest --predicate sbom.${IMAGE_TAG}.spdx.json --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
-        cosign attest --yes --predicate sbom.${IMAGE_TAG}.spdx.json --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
-        # cosign verify-attestation --type spdx ${IMAGE_NAME}@${CONTAINER_DIGEST} | jq '.payload |= @base64d | .payload | fromjson'
+        echo "::endgroup::"
+
+        echo "::group::Attest image SBOM"
+        cosign attest --yes --new-bundle-format=false --use-signing-config=false --predicate sbom.${IMAGE_TAG}.spdx.json --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        echo "::endgroup::"
+
+        echo "::group::Verify image SBOM attestation"
+        echo "Using certificate-identity-regexp: https://github.com/$GITHUB_REPOSITORY/.*"
         cosign verify-attestation --type spdx ${IMAGE_NAME}@${CONTAINER_DIGEST} \
             --certificate-identity-regexp "https://github.com/$GITHUB_REPOSITORY/.*" \
             --certificate-oidc-issuer https://token.actions.githubusercontent.com | jq '.payload |= @base64d | .payload | fromjson'
+        echo "::endgroup::"
+
+        echo "::group::Go modules SBOM generation"
         # Go modules SBOM (dependencies from the source tree)
         # Requires repository to be checked out before this composite action runs.
         syft dir:. -o spdx-json=sbom.gomod.${IMAGE_TAG}.spdx.json
-        # cosign attest --predicate sbom.gomod.${IMAGE_TAG}.spdx.json --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
-        cosign attest --yes --predicate sbom.gomod.${IMAGE_TAG}.spdx.json --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        echo "::endgroup::"
+
+        echo "::group::Attest Go modules SBOM"
+        cosign attest --yes --new-bundle-format=false --use-signing-config=false --predicate sbom.gomod.${IMAGE_TAG}.spdx.json --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        echo "::endgroup::"
+
+        echo "::group::Verify Go modules SBOM attestation"
         cosign verify-attestation --type spdx ${IMAGE_NAME}@${CONTAINER_DIGEST} \
             --certificate-identity-regexp "https://github.com/$GITHUB_REPOSITORY/.*" \
-            --certificate-oidc-issuer https://token.actions.githubusercontent.com | jq '.payload |= @base64d | .payload | fromjson'
+            --certificate-oidc-issuer https://token.actions.githubusercontent.com | jq ' .payload |= @base64d | .payload | fromjson | .subject'
+        echo "::endgroup::"
 
     - name: Generate provenance
-      # https://github.com/philips-labs/slsa-provenance-action/releases/tag/v0.7.2
-      uses: philips-labs/slsa-provenance-action@dddb40e199ae28d4cd2f17bad7f31545556fdd3d # v0.7.2
-      with:
-        command: generate
-        subcommand: container
-        arguments: --repository "${{ inputs.image-name }}" --output-path provenance.${{ inputs.image-tag }}.intoto.jsonl --digest "${{ steps.container_info.outputs.digest }}" --tags "${{ inputs.image-tag }}"
+      shell: bash
       env:
-        COSIGN_EXPERIMENTAL: "0"
-        GITHUB_TOKEN: "${{ github.token }}"
+        IMAGE_NAME: ${{ inputs.image-name }}
+        IMAGE_TAG: ${{ inputs.image-tag }}
+        CONTAINER_DIGEST: ${{ steps.container_info.outputs.digest }}
+      run: |
+        echo "::group::Generate provenance"
+        ./hack/generate-provenance.sh \
+          --repository "${IMAGE_NAME}" \
+          --digest "${CONTAINER_DIGEST}" \
+          --tags "${IMAGE_TAG}" \
+          --output-path "provenance.${IMAGE_TAG}.intoto.jsonl"
+        echo "::endgroup::"
 
     - name: Attach provenance
       shell: bash
@@ -109,10 +139,16 @@ runs:
         IMAGE_TAG: ${{ inputs.image-tag }}
         CONTAINER_DIGEST: ${{ steps.container_info.outputs.digest }}
       run: |
+        echo "::group::Prepare provenance predicate"
         jq '.predicate' provenance.${IMAGE_TAG}.intoto.jsonl > provenance-predicate.att
-        # cosign attest --predicate provenance-predicate.att --type slsaprovenance "${IMAGE_NAME}@${CONTAINER_DIGEST}"
-        cosign attest --yes --predicate provenance-predicate.att --type slsaprovenance "${IMAGE_NAME}@${CONTAINER_DIGEST}"
-        # cosign verify-attestation --type slsaprovenance ${IMAGE_NAME}@${CONTAINER_DIGEST}
+        echo "::endgroup::"
+
+        echo "::group::Attest provenance"
+        cosign attest --yes --new-bundle-format=false --use-signing-config=false --predicate provenance-predicate.att --type slsaprovenance "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        echo "::endgroup::"
+
+        echo "::group::Verify provenance attestation"
         cosign verify-attestation --type slsaprovenance ${IMAGE_NAME}@${CONTAINER_DIGEST} \
             --certificate-identity-regexp "https://github.com/$GITHUB_REPOSITORY/.*" \
             --certificate-oidc-issuer https://token.actions.githubusercontent.com
+        echo "::endgroup::"

+ 2 - 2
.github/workflows/ci.yml

@@ -156,8 +156,8 @@ jobs:
           tag-suffix: "-ubi"
         - dockerfile: "Dockerfile.ubi"
           build-args: "CGO_ENABLED=0 GOEXPERIMENT=boringcrypto"
-          build-arch: "amd64 ppc64le"
-          build-platform: "linux/amd64,linux/ppc64le"
+          build-arch: "amd64 arm64 ppc64le"
+          build-platform: "linux/amd64,linux/arm64,linux/ppc64le"
           tag-suffix: "-ubi-boringssl"
     with:
       dockerfile: ${{ matrix.dockerfile }}

+ 0 - 1
.github/workflows/e2e.yml

@@ -10,7 +10,6 @@ name: e2e tests
 
 env:
   # Common versions
-  DOCKER_BUILDX_VERSION: 'v0.4.2'
   KIND_VERSION: 'v0.30.0'
   KIND_IMAGE: 'kindest/node:v1.33.4'
 

+ 4 - 4
.github/workflows/helm.yml

@@ -132,7 +132,7 @@ jobs:
       - name: Install cosign
         uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
         with:
-          cosign-release: 'v3.0.3'
+          cosign-release: 'v3.0.2'
 
       - name: Push chart to GHCR
         id: push_chart
@@ -157,9 +157,9 @@ jobs:
             echo "$helm_push_output"
 
             artifact_digest_uri="${chart_registry}/${chart_name}@${digest}"
-            cosign sign --yes "$artifact_digest_uri"
-            cosign verify "$artifact_digest_uri" \
-                --certificate-identity-regexp "https://github.com/$GITHUB_REPOSITORY/*" \
+            cosign sign --yes --new-bundle-format=false --use-signing-config=false "$artifact_digest_uri"
+            cosign verify --new-bundle-format=false --use-signing-config=false "$artifact_digest_uri" \
+                --certificate-identity-regexp "https://github.com/$GITHUB_REPOSITORY/.*" \
                 --certificate-oidc-issuer https://token.actions.githubusercontent.com
 
             echo "digest=${digest}" >> "$GITHUB_OUTPUT"

+ 110 - 0
hack/generate-provenance.sh

@@ -0,0 +1,110 @@
+#!/usr/bin/env bash
+# generate-provenance.sh - Generate SLSA Provenance v0.2 in-toto statement for container images.
+# Drop-in replacement for philips-labs/slsa-provenance-action (container subcommand).
+#
+# Required environment variables (set automatically in GitHub Actions):
+#   GITHUB_REPOSITORY    - owner/repo
+#   GITHUB_SHA           - commit SHA
+#   GITHUB_RUN_ID        - workflow run ID
+#   GITHUB_WORKFLOW      - workflow name
+#
+# Usage:
+#   ./hack/generate-provenance.sh \
+#     --repository <image-repo> \
+#     --digest <sha256:...> \
+#     --tags <tag> \
+#     --output-path <output.intoto.jsonl>
+
+set -euo pipefail
+
+REPOSITORY=""
+DIGEST=""
+TAGS=""
+OUTPUT_PATH=""
+
+while [[ $# -gt 0 ]]; do
+  case "$1" in
+    --repository) REPOSITORY="$2"; shift 2 ;;
+    --digest)     DIGEST="$2"; shift 2 ;;
+    --tags)       TAGS="$2"; shift 2 ;;
+    --output-path) OUTPUT_PATH="$2"; shift 2 ;;
+    *) echo "Unknown argument: $1" >&2; exit 1 ;;
+  esac
+done
+
+if [[ -z "$REPOSITORY" || -z "$DIGEST" || -z "$OUTPUT_PATH" ]]; then
+  echo "Error: --repository, --digest, and --output-path are required" >&2
+  exit 1
+fi
+
+# Strip the sha256: prefix for the digest value
+DIGEST_VALUE="${DIGEST#sha256:}"
+
+REPO_URL="https://github.com/${GITHUB_REPOSITORY}"
+BUILD_INVOCATION_ID="${REPO_URL}/actions/runs/${GITHUB_RUN_ID}"
+BUILD_FINISHED_ON="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
+
+# Build subject name: repo:tag if tags provided, otherwise repo
+if [[ -n "$TAGS" ]]; then
+  SUBJECT_NAME="${REPOSITORY}:${TAGS}"
+else
+  SUBJECT_NAME="${REPOSITORY}"
+fi
+
+jq -n \
+  --arg type "https://in-toto.io/Statement/v0.1" \
+  --arg predicateType "https://slsa.dev/provenance/v0.2" \
+  --arg subjectName "$SUBJECT_NAME" \
+  --arg digestValue "$DIGEST_VALUE" \
+  --arg builderId "${REPO_URL}/Attestations/GitHubHostedActions@v1" \
+  --arg buildType "https://github.com/Attestations/GitHubActionsWorkflow@v1" \
+  --arg entryPoint "${GITHUB_WORKFLOW:-}" \
+  --arg buildInvocationId "$BUILD_INVOCATION_ID" \
+  --arg buildFinishedOn "$BUILD_FINISHED_ON" \
+  --arg materialUri "git+${REPO_URL}" \
+  --arg materialSha "${GITHUB_SHA}" \
+  '{
+    "_type": $type,
+    "subject": [
+      {
+        "name": $subjectName,
+        "digest": {
+          "sha256": $digestValue
+        }
+      }
+    ],
+    "predicateType": $predicateType,
+    "predicate": {
+      "builder": {
+        "id": $builderId
+      },
+      "buildType": $buildType,
+      "invocation": {
+        "configSource": {
+          "entryPoint": $entryPoint
+        },
+        "parameters": null,
+        "environment": null
+      },
+      "metadata": {
+        "buildInvocationId": $buildInvocationId,
+        "buildFinishedOn": $buildFinishedOn,
+        "completeness": {
+          "parameters": false,
+          "environment": false,
+          "materials": false
+        },
+        "reproducible": false
+      },
+      "materials": [
+        {
+          "uri": $materialUri,
+          "digest": {
+            "sha1": $materialSha
+          }
+        }
+      ]
+    }
+  }' > "$OUTPUT_PATH"
+
+echo "Provenance saved to ${OUTPUT_PATH}"