@@ -205,13 +205,17 @@ jobs:
205205 permissions:
206206 id-token: write
207207 runs-on: ubuntu-latest
208+ outputs:
209+ oci-index-digest: ${{ steps.publish-oci.outputs.image-index-manifest-digest }}
210+ quay-index-digest: ${{ steps.publish-quay.outputs.image-index-manifest-digest }}
208211 steps:
209212 - name: Checkout Repository
210213 uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
211214 with:
212215 persist-credentials: false
213216
214217 - name: Publish and Sign Image Index to oci.stackable.tech
218+ id: publish-oci
215219 uses: stackabletech/actions/publish-image-index-manifest@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
216220 with:
217221 image-registry-uri: oci.stackable.tech
@@ -221,6 +225,7 @@ jobs:
221225 image-index-manifest-tag: ${{ needs.build-container-image.outputs.operator-version }}
222226
223227 - name: Publish and Sign Image Index to quay.io
228+ id: publish-quay
224229 uses: stackabletech/actions/publish-image-index-manifest@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
225230 with:
226231 image-registry-uri: quay.io
@@ -229,6 +234,64 @@ jobs:
229234 image-repository: stackable/sdp/${{ env.OPERATOR_NAME }}
230235 image-index-manifest-tag: ${{ needs.build-container-image.outputs.operator-version }}
231236
237+ # Generate SLSA build provenance for the multi-arch image index and attach it
238+ # to the published image in each registry. The reusable workflow signs the
239+ # provenance with keyless signing (GitHub Actions as the OIDC identity) and
240+ # pushes the attestation next to the image.
241+ provenance-oci:
242+ name: Generate Provenance for ${{ needs.build-container-image.outputs.operator-version }} (oci.stackable.tech)
243+ if: |
244+ (github.event_name != 'merge_group')
245+ && needs.detect-changes.outputs.detected == 'true'
246+ && !github.event.pull_request.head.repo.fork
247+ needs:
248+ - detect-changes
249+ - build-container-image
250+ - publish-index-manifest
251+ permissions:
252+ actions: read # detect the build workflow that generated the image
253+ id-token: write # mint the OIDC token for keyless signing
254+ packages: write # needed until https://github.com/slsa-framework/slsa-github-generator/issues/1257 is resolved
255+ # MUST be referenced by a @vX.Y.Z tag (not a SHA), otherwise the reusable
256+ # workflow cannot verify its own provenance.
257+ uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
258+ with:
259+ # The 'env' context is not available in job-level 'with' inputs of
260+ # reusable workflow calls (unlike step-level 'with'), so OPERATOR_NAME
261+ # can't be used here and the operator name is templated in directly.
262+ image: oci.stackable.tech/sdp/{[ operator.name }]
263+ digest: ${{ needs.publish-index-manifest.outputs.oci-index-digest }}
264+ registry-username: robot$sdp+github-action-build
265+ secrets:
266+ registry-password: ${{ secrets.HARBOR_ROBOT_SDP_GITHUB_ACTION_BUILD_SECRET }}
267+
268+ provenance-quay:
269+ name: Generate Provenance for ${{ needs.build-container-image.outputs.operator-version }} (quay.io)
270+ if: |
271+ (github.event_name != 'merge_group')
272+ && needs.detect-changes.outputs.detected == 'true'
273+ && !github.event.pull_request.head.repo.fork
274+ needs:
275+ - detect-changes
276+ - build-container-image
277+ - publish-index-manifest
278+ permissions:
279+ actions: read # detect the build workflow that generated the image
280+ id-token: write # mint the OIDC token for keyless signing
281+ packages: write # needed until https://github.com/slsa-framework/slsa-github-generator/issues/1257 is resolved
282+ # MUST be referenced by a @vX.Y.Z tag (not a SHA), otherwise the reusable
283+ # workflow cannot verify its own provenance.
284+ uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
285+ with:
286+ # The 'env' context is not available in job-level 'with' inputs of
287+ # reusable workflow calls (unlike step-level 'with'), so OPERATOR_NAME
288+ # can't be used here and the operator name is templated in directly.
289+ image: quay.io/stackable/sdp/{[ operator.name }]
290+ digest: ${{ needs.publish-index-manifest.outputs.quay-index-digest }}
291+ registry-username: stackable+robot_sdp_github_action_build
292+ secrets:
293+ registry-password: ${{ secrets.QUAY_ROBOT_SDP_GITHUB_ACTION_BUILD_SECRET }}
294+
232295 publish-helm-chart:
233296 name: Package/Publish ${{ needs.build-container-image.outputs.operator-version }} Helm Chart
234297 if: |
@@ -328,6 +391,8 @@ jobs:
328391 - detect-changes
329392 - build-container-image
330393 - publish-index-manifest
394+ - provenance-oci
395+ - provenance-quay
331396 - publish-helm-chart
332397 runs-on: ubuntu-latest
333398 steps:
0 commit comments