diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index befc96b17..7a9004ee8 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -414,28 +414,18 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Install cosign - # cosign is used to sign and verify container images (key and keyless) + # cosign is used to sign container images using keyless (OIDC) signing uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 - - name: Dual-sign and verify (GHCR & Docker Hub) - # Sign each image by digest using keyless (OIDC) and key-based signing, - # then verify both the public key signature and the keyless OIDC signature. + - name: Sign (GHCR, keyless) + # Sign each GHCR image by digest using keyless (OIDC) signing via Sigstore/Rekor. + # Signatures are stored in the registry alongside the image. env: TAG: ${{ env.TAG }} - COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} - COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} - COSIGN_PUBLIC_KEY: ${{ secrets.COSIGN_PUBLIC_KEY }} COSIGN_YES: "true" run: | set -euo pipefail - issuer="https://token.actions.githubusercontent.com" - id_regex="^https://github.com/${{ github.repository }}/.+" # accept this repo (all workflows/refs) - - # Track failures - FAILED_TAGS=() - SUCCESSFUL_TAGS=() - # Determine if this is an RC release IS_RC="false" if [[ "$TAG" == *"-rc."* ]]; then @@ -463,95 +453,47 @@ jobs: ) fi - # Sign each image variant for both registries - for BASE_IMAGE in "${GHCR_IMAGE}" "${DOCKERHUB_IMAGE}"; do - for IMAGE_TAG in "${IMAGE_TAGS[@]}"; do - echo "Processing ${BASE_IMAGE}:${IMAGE_TAG}" - TAG_FAILED=false + FAILED_TAGS=() + SUCCESSFUL_TAGS=() - # Wrap the entire tag processing in error handling - ( - set -e - DIGEST="$(skopeo inspect --retry-times 3 docker://${BASE_IMAGE}:${IMAGE_TAG} | jq -r '.Digest')" - REF="${BASE_IMAGE}@${DIGEST}" - echo "Resolved digest: ${REF}" + for IMAGE_TAG in "${IMAGE_TAGS[@]}"; do + echo "Processing ${GHCR_IMAGE}:${IMAGE_TAG}" + TAG_FAILED=false - echo "==> cosign sign (keyless) --recursive ${REF}" - cosign sign --recursive "${REF}" + ( + set -e + DIGEST="$(skopeo inspect --retry-times 3 docker://${GHCR_IMAGE}:${IMAGE_TAG} | jq -r '.Digest')" + REF="${GHCR_IMAGE}@${DIGEST}" + echo "Resolved digest: ${REF}" - echo "==> cosign sign (key) --recursive ${REF}" - cosign sign --key env://COSIGN_PRIVATE_KEY --recursive "${REF}" + echo "==> cosign sign (keyless) --recursive ${REF}" + cosign sign --recursive "${REF}" + ) || TAG_FAILED=true - # Retry wrapper for verification to handle registry propagation delays - retry_verify() { - local cmd="$1" - local attempts=6 - local delay=5 - local i=1 - until eval "$cmd"; do - if [ $i -ge $attempts ]; then - echo "Verification failed after $attempts attempts" - return 1 - fi - echo "Verification not yet available. Retry $i/$attempts after ${delay}s..." - sleep $delay - i=$((i+1)) - delay=$((delay*2)) - # Cap the delay to avoid very long waits - if [ $delay -gt 60 ]; then delay=60; fi - done - return 0 - } - - echo "==> cosign verify (public key) ${REF}" - if retry_verify "cosign verify --key env://COSIGN_PUBLIC_KEY '${REF}' -o text"; then - VERIFIED_INDEX=true - else - VERIFIED_INDEX=false - fi - - echo "==> cosign verify (keyless policy) ${REF}" - if retry_verify "cosign verify --certificate-oidc-issuer '${issuer}' --certificate-identity-regexp '${id_regex}' '${REF}' -o text"; then - VERIFIED_INDEX_KEYLESS=true - else - VERIFIED_INDEX_KEYLESS=false - fi - - # Check if verification succeeded - if [ "${VERIFIED_INDEX}" != "true" ] && [ "${VERIFIED_INDEX_KEYLESS}" != "true" ]; then - echo "⚠️ WARNING: Verification not available for ${BASE_IMAGE}:${IMAGE_TAG}" - echo "This may be due to registry propagation delays. Continuing anyway." - fi - ) || TAG_FAILED=true - - if [ "$TAG_FAILED" = "true" ]; then - echo "⚠️ WARNING: Failed to sign/verify ${BASE_IMAGE}:${IMAGE_TAG}" - FAILED_TAGS+=("${BASE_IMAGE}:${IMAGE_TAG}") - else - echo "✓ Successfully signed and verified ${BASE_IMAGE}:${IMAGE_TAG}" - SUCCESSFUL_TAGS+=("${BASE_IMAGE}:${IMAGE_TAG}") - fi - done + if [ "$TAG_FAILED" = "true" ]; then + echo "⚠️ WARNING: Failed to sign ${GHCR_IMAGE}:${IMAGE_TAG}" + FAILED_TAGS+=("${GHCR_IMAGE}:${IMAGE_TAG}") + else + echo "✓ Successfully signed ${GHCR_IMAGE}:${IMAGE_TAG}" + SUCCESSFUL_TAGS+=("${GHCR_IMAGE}:${IMAGE_TAG}") + fi done - # Report summary echo "" echo "==========================================" - echo "Sign and Verify Summary" + echo "Sign Summary" echo "==========================================" echo "Successful: ${#SUCCESSFUL_TAGS[@]}" echo "Failed: ${#FAILED_TAGS[@]}" - echo "" if [ ${#FAILED_TAGS[@]} -gt 0 ]; then echo "Failed tags:" for tag in "${FAILED_TAGS[@]}"; do echo " - $tag" done - echo "" - echo "⚠️ WARNING: Some tags failed to sign/verify, but continuing anyway" + echo "⚠️ WARNING: Some tags failed to sign, but continuing anyway" else - echo "✓ All images signed and verified successfully!" + echo "✓ All images signed successfully!" fi shell: bash