From dcedc113e8fccd88fe7190a8b4fd2ea92e78685b Mon Sep 17 00:00:00 2001 From: Mathias Beaulieu-Duncan Date: Mon, 2 Feb 2026 10:17:16 -0500 Subject: [PATCH] Fix provenance JSON: use jq instead of heredoc to avoid whitespace The heredoc with YAML indentation produced JSON with leading spaces, causing cosign to fail with "required field builder missing". Use jq -n with --arg to generate clean JSON. Co-Authored-By: Claude Opus 4.5 --- .gitea/workflows/publish.yaml | 62 +++++++++++++----------------- .gitea/workflows/rebuild.yaml | 61 +++++++++++++---------------- .gitea/workflows/update-check.yaml | 61 +++++++++++++---------------- 3 files changed, 78 insertions(+), 106 deletions(-) diff --git a/.gitea/workflows/publish.yaml b/.gitea/workflows/publish.yaml index 381a037..e4869d4 100644 --- a/.gitea/workflows/publish.yaml +++ b/.gitea/workflows/publish.yaml @@ -96,44 +96,34 @@ jobs: COSIGN_YES: "true" run: | IMAGE_DIGEST="${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}@${{ steps.publish.outputs.digest }}" - # Generate SLSA-style provenance - cat > /tmp/provenance.json << PROVEOF - { - "_type": "https://in-toto.io/Statement/v0.1", - "predicateType": "https://slsa.dev/provenance/v0.2", - "subject": [ - { - "name": "${{ steps.publish.outputs.image_ref }}", - "digest": { - "sha256": "$(echo '${{ steps.publish.outputs.digest }}' | sed 's/sha256://')" + DIGEST_SHA=$(echo '${{ steps.publish.outputs.digest }}' | sed 's/sha256://') + jq -n \ + --arg type "https://in-toto.io/Statement/v0.1" \ + --arg predType "https://slsa.dev/provenance/v0.2" \ + --arg name "${{ steps.publish.outputs.image_ref }}" \ + --arg sha "$DIGEST_SHA" \ + --arg builder "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ + --arg buildType "https://apko.dev/build/v1" \ + --arg uri "${{ github.server_url }}/${{ github.repository }}" \ + --arg sha1 "${{ github.sha }}" \ + --arg entry "${{ matrix.config }}" \ + --arg runId "${{ github.run_id }}" \ + '{ + "_type": $type, + "predicateType": $predType, + "subject": [{"name": $name, "digest": {"sha256": $sha}}], + "predicate": { + "builder": {"id": $builder}, + "buildType": $buildType, + "invocation": { + "configSource": {"uri": $uri, "digest": {"sha1": $sha1}, "entryPoint": $entry} + }, + "metadata": { + "buildInvocationID": $runId, + "completeness": {"parameters": true, "environment": true, "materials": true} } } - ], - "predicate": { - "buildType": "https://apko.dev/build/v1", - "builder": { - "id": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - }, - "invocation": { - "configSource": { - "uri": "${{ github.server_url }}/${{ github.repository }}", - "digest": { - "sha1": "${{ github.sha }}" - }, - "entryPoint": "${{ matrix.config }}" - } - }, - "metadata": { - "buildInvocationID": "${{ github.run_id }}", - "completeness": { - "parameters": true, - "environment": true, - "materials": true - } - } - } - } - PROVEOF + }' > /tmp/provenance.json cosign attest --predicate /tmp/provenance.json --type slsaprovenance "${IMAGE_DIGEST}" echo "Provenance attestation attached successfully" diff --git a/.gitea/workflows/rebuild.yaml b/.gitea/workflows/rebuild.yaml index 793119c..5102246 100644 --- a/.gitea/workflows/rebuild.yaml +++ b/.gitea/workflows/rebuild.yaml @@ -89,43 +89,34 @@ jobs: COSIGN_YES: "true" run: | IMAGE_DIGEST="${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}@${{ steps.publish.outputs.digest }}" - cat > /tmp/provenance.json << PROVEOF - { - "_type": "https://in-toto.io/Statement/v0.1", - "predicateType": "https://slsa.dev/provenance/v0.2", - "subject": [ - { - "name": "${{ steps.publish.outputs.image_ref }}", - "digest": { - "sha256": "$(echo '${{ steps.publish.outputs.digest }}' | sed 's/sha256://')" + DIGEST_SHA=$(echo '${{ steps.publish.outputs.digest }}' | sed 's/sha256://') + jq -n \ + --arg type "https://in-toto.io/Statement/v0.1" \ + --arg predType "https://slsa.dev/provenance/v0.2" \ + --arg name "${{ steps.publish.outputs.image_ref }}" \ + --arg sha "$DIGEST_SHA" \ + --arg builder "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ + --arg buildType "https://apko.dev/build/v1" \ + --arg uri "${{ github.server_url }}/${{ github.repository }}" \ + --arg sha1 "${{ github.sha }}" \ + --arg entry "${{ matrix.config }}" \ + --arg runId "${{ github.run_id }}" \ + '{ + "_type": $type, + "predicateType": $predType, + "subject": [{"name": $name, "digest": {"sha256": $sha}}], + "predicate": { + "builder": {"id": $builder}, + "buildType": $buildType, + "invocation": { + "configSource": {"uri": $uri, "digest": {"sha1": $sha1}, "entryPoint": $entry} + }, + "metadata": { + "buildInvocationID": $runId, + "completeness": {"parameters": true, "environment": true, "materials": true} } } - ], - "predicate": { - "buildType": "https://apko.dev/build/v1", - "builder": { - "id": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - }, - "invocation": { - "configSource": { - "uri": "${{ github.server_url }}/${{ github.repository }}", - "digest": { - "sha1": "${{ github.sha }}" - }, - "entryPoint": "${{ matrix.config }}" - } - }, - "metadata": { - "buildInvocationID": "${{ github.run_id }}", - "completeness": { - "parameters": true, - "environment": true, - "materials": true - } - } - } - } - PROVEOF + }' > /tmp/provenance.json cosign attest --predicate /tmp/provenance.json --type slsaprovenance "${IMAGE_DIGEST}" echo "Provenance attestation attached successfully" diff --git a/.gitea/workflows/update-check.yaml b/.gitea/workflows/update-check.yaml index f00c7ca..387e9cd 100644 --- a/.gitea/workflows/update-check.yaml +++ b/.gitea/workflows/update-check.yaml @@ -179,43 +179,34 @@ jobs: COSIGN_YES: "true" run: | IMAGE_DIGEST="${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}@${{ steps.publish.outputs.digest }}" - cat > /tmp/provenance.json << PROVEOF - { - "_type": "https://in-toto.io/Statement/v0.1", - "predicateType": "https://slsa.dev/provenance/v0.2", - "subject": [ - { - "name": "${{ steps.publish.outputs.image_ref }}", - "digest": { - "sha256": "$(echo '${{ steps.publish.outputs.digest }}' | sed 's/sha256://')" + DIGEST_SHA=$(echo '${{ steps.publish.outputs.digest }}' | sed 's/sha256://') + jq -n \ + --arg type "https://in-toto.io/Statement/v0.1" \ + --arg predType "https://slsa.dev/provenance/v0.2" \ + --arg name "${{ steps.publish.outputs.image_ref }}" \ + --arg sha "$DIGEST_SHA" \ + --arg builder "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ + --arg buildType "https://apko.dev/build/v1" \ + --arg uri "${{ github.server_url }}/${{ github.repository }}" \ + --arg sha1 "${{ github.sha }}" \ + --arg entry "${{ matrix.config }}" \ + --arg runId "${{ github.run_id }}" \ + '{ + "_type": $type, + "predicateType": $predType, + "subject": [{"name": $name, "digest": {"sha256": $sha}}], + "predicate": { + "builder": {"id": $builder}, + "buildType": $buildType, + "invocation": { + "configSource": {"uri": $uri, "digest": {"sha1": $sha1}, "entryPoint": $entry} + }, + "metadata": { + "buildInvocationID": $runId, + "completeness": {"parameters": true, "environment": true, "materials": true} } } - ], - "predicate": { - "buildType": "https://apko.dev/build/v1", - "builder": { - "id": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - }, - "invocation": { - "configSource": { - "uri": "${{ github.server_url }}/${{ github.repository }}", - "digest": { - "sha1": "${{ github.sha }}" - }, - "entryPoint": "${{ matrix.config }}" - } - }, - "metadata": { - "buildInvocationID": "${{ github.run_id }}", - "completeness": { - "parameters": true, - "environment": true, - "materials": true - } - } - } - } - PROVEOF + }' > /tmp/provenance.json cosign attest --predicate /tmp/provenance.json --type slsaprovenance "${IMAGE_DIGEST}" echo "Provenance attestation attached successfully"