Skip to content

Commit a0fd6b5

Browse files
authored
feat: Generate SLSA provenance for operator images (#602)
* feat: generate SLSA provenance for operator images * chore: Bump stackabletech/actions to v0.16.0
1 parent b2fec12 commit a0fd6b5

4 files changed

Lines changed: 80 additions & 15 deletions

File tree

.github/workflows/pr_prek.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ jobs:
1717
with:
1818
persist-credentials: false
1919
fetch-depth: 0
20-
- uses: stackabletech/actions/run-prek@bb86a79a5ab73726d4f047f07452c3307ff0b300 # v0.15.0
20+
- uses: stackabletech/actions/run-prek@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
2121
with:
2222
hadolint: ${{ env.HADOLINT_VERSION }}

template/.github/workflows/build.yaml.j2

Lines changed: 76 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848

4949
- name: Check for changed files
5050
id: check
51-
uses: stackabletech/actions/detect-changes@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
51+
uses: stackabletech/actions/detect-changes@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
5252
with:
5353
patterns: |
5454
- '.github/workflows/build.yaml'
@@ -164,7 +164,7 @@ jobs:
164164

165165
- name: Build Container Image
166166
id: build
167-
uses: stackabletech/actions/build-container-image@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
167+
uses: stackabletech/actions/build-container-image@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
168168
with:
169169
image-name: ${{ env.OPERATOR_NAME }}
170170
image-index-manifest-tag: ${{ steps.version.outputs.OPERATOR_VERSION }}
@@ -173,7 +173,7 @@ jobs:
173173

174174
- name: Publish Container Image to oci.stackable.tech
175175
if: ${{ !github.event.pull_request.head.repo.fork }}
176-
uses: stackabletech/actions/publish-image@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
176+
uses: stackabletech/actions/publish-image@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
177177
with:
178178
image-registry-uri: oci.stackable.tech
179179
image-registry-username: robot$sdp+github-action-build
@@ -184,7 +184,7 @@ jobs:
184184

185185
- name: Publish Container Image to quay.io
186186
if: ${{ !github.event.pull_request.head.repo.fork }}
187-
uses: stackabletech/actions/publish-image@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
187+
uses: stackabletech/actions/publish-image@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
188188
with:
189189
image-registry-uri: quay.io
190190
image-registry-username: stackable+robot_sdp_github_action_build
@@ -205,14 +205,18 @@ 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
215-
uses: stackabletech/actions/publish-image-index-manifest@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
218+
id: publish-oci
219+
uses: stackabletech/actions/publish-image-index-manifest@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
216220
with:
217221
image-registry-uri: oci.stackable.tech
218222
image-registry-username: robot$sdp+github-action-build
@@ -221,14 +225,73 @@ jobs:
221225
image-index-manifest-tag: ${{ needs.build-container-image.outputs.operator-version }}
222226

223227
- name: Publish and Sign Image Index to quay.io
224-
uses: stackabletech/actions/publish-image-index-manifest@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
228+
id: publish-quay
229+
uses: stackabletech/actions/publish-image-index-manifest@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
225230
with:
226231
image-registry-uri: quay.io
227232
image-registry-username: stackable+robot_sdp_github_action_build
228233
image-registry-password: ${{ secrets.QUAY_ROBOT_SDP_GITHUB_ACTION_BUILD_SECRET }}
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: |
@@ -248,7 +311,7 @@ jobs:
248311
submodules: recursive
249312

250313
- name: Package, Publish, and Sign Helm Chart to oci.stackable.tech
251-
uses: stackabletech/actions/publish-helm-chart@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
314+
uses: stackabletech/actions/publish-helm-chart@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
252315
with:
253316
chart-registry-uri: oci.stackable.tech
254317
chart-registry-username: robot$sdp-charts+github-action-build
@@ -260,7 +323,7 @@ jobs:
260323
publish-and-sign: ${{ !github.event.pull_request.head.repo.fork }}
261324

262325
- name: Package, Publish, and Sign Helm Chart to quay.io
263-
uses: stackabletech/actions/publish-helm-chart@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
326+
uses: stackabletech/actions/publish-helm-chart@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
264327
with:
265328
chart-registry-uri: quay.io
266329
chart-registry-username: stackable+robot_sdp_charts_github_action_build
@@ -291,13 +354,13 @@ jobs:
291354
runs-on: ubuntu-latest
292355
steps:
293356
- name: Run OpenShift Preflight Check for oci.stackable.tech
294-
uses: stackabletech/actions/run-openshift-preflight@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
357+
uses: stackabletech/actions/run-openshift-preflight@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
295358
with:
296359
image-index-uri: oci.stackable.tech/sdp/${{ env.OPERATOR_NAME }}:${{ needs.build-container-image.outputs.operator-version }}
297360
image-architecture: ${{ matrix.arch }}
298361

299362
- name: Run OpenShift Preflight Check for quay.io
300-
uses: stackabletech/actions/run-openshift-preflight@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
363+
uses: stackabletech/actions/run-openshift-preflight@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
301364
with:
302365
image-index-uri: quay.io/stackable/sdp/${{ env.OPERATOR_NAME }}:${{ needs.build-container-image.outputs.operator-version }}
303366
image-architecture: ${{ matrix.arch }}
@@ -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:
@@ -337,7 +402,7 @@ jobs:
337402
persist-credentials: false
338403

339404
- name: Send Notification
340-
uses: stackabletech/actions/send-slack-notification@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
405+
uses: stackabletech/actions/send-slack-notification@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
341406
with:
342407
publish-helm-chart-result: ${{ needs.publish-helm-chart.result }}
343408
publish-manifests-result: ${{ needs.publish-index-manifest.result }}

template/.github/workflows/integration-test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
# TODO: Enable the scheduled runs which hard-code what profile to use
4444
- name: Run Integration Test
4545
id: test
46-
uses: stackabletech/actions/run-integration-test@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
46+
uses: stackabletech/actions/run-integration-test@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
4747
with:
4848
replicated-api-token: ${{ secrets.REPLICATED_API_TOKEN }}
4949
test-mode-input: ${{ inputs.test-mode-input }}
@@ -53,7 +53,7 @@ jobs:
5353

5454
- name: Send Notification
5555
if: ${{ failure() || github.run_attempt > 1 }}
56-
uses: stackabletech/actions/send-slack-notification@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
56+
uses: stackabletech/actions/send-slack-notification@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
5757
with:
5858
slack-token: ${{ secrets.SLACK_INTEGRATION_TEST_TOKEN }}
5959
failed-tests: ${{ steps.test.outputs.failed-tests }}

template/.github/workflows/pr_prek.yaml.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
persist-credentials: false
2929
submodules: recursive
3030
fetch-depth: 0
31-
- uses: stackabletech/actions/run-prek@a14cbd08d9e034e2361ea9205b32aff0491885db # v0.15.0
31+
- uses: stackabletech/actions/run-prek@a8af17a19bdcc3b5da0065f76e73827ba0c072ce # v0.16.0
3232
with:
3333
rust: ${{ env.RUST_TOOLCHAIN_VERSION }}
3434
hadolint: ${{ env.HADOLINT_VERSION }}

0 commit comments

Comments
 (0)