From e3a46522f60d482dd74d1fcd17fd01b0baf24cd7 Mon Sep 17 00:00:00 2001 From: "Jens L." Date: Fri, 19 Jul 2024 16:48:50 +0200 Subject: [PATCH] ci: add container image attestation (#10478) Signed-off-by: Jens Langhammer --- .../actions/docker-push-variables/action.yml | 6 +++++ .../docker-push-variables/push_vars.py | 5 +++- .github/workflows/ci-main.yml | 12 +++++++++- .github/workflows/ci-outpost.yml | 10 ++++++++ .github/workflows/release-publish.yml | 24 +++++++++++++++++-- 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/.github/actions/docker-push-variables/action.yml b/.github/actions/docker-push-variables/action.yml index f322c2ab66..741a96ac30 100644 --- a/.github/actions/docker-push-variables/action.yml +++ b/.github/actions/docker-push-variables/action.yml @@ -29,9 +29,15 @@ outputs: imageTags: description: "Docker image tags" value: ${{ steps.ev.outputs.imageTags }} + imageNames: + description: "Docker image names" + value: ${{ steps.ev.outputs.imageNames }} imageMainTag: description: "Docker image main tag" value: ${{ steps.ev.outputs.imageMainTag }} + imageMainName: + description: "Docker image main name" + value: ${{ steps.ev.outputs.imageMainName }} runs: using: "composite" diff --git a/.github/actions/docker-push-variables/push_vars.py b/.github/actions/docker-push-variables/push_vars.py index 28572b8ca4..5a88e0943f 100644 --- a/.github/actions/docker-push-variables/push_vars.py +++ b/.github/actions/docker-push-variables/push_vars.py @@ -50,8 +50,9 @@ else: f"{name}:gh-{safe_branch_name}-{int(time())}-{sha[:7]}{suffix}", # Use by FluxCD ] -image_main_tag = image_tags[0] +image_main_tag = image_tags[0].split(":")[-1] image_tags_rendered = ",".join(image_tags) +image_names_rendered = ",".join(set(name.split(":")[0] for name in image_tags)) with open(os.environ["GITHUB_OUTPUT"], "a+", encoding="utf-8") as _output: print(f"shouldBuild={should_build}", file=_output) @@ -59,4 +60,6 @@ with open(os.environ["GITHUB_OUTPUT"], "a+", encoding="utf-8") as _output: print(f"version={version}", file=_output) print(f"prerelease={prerelease}", file=_output) print(f"imageTags={image_tags_rendered}", file=_output) + print(f"imageNames={image_names_rendered}", file=_output) print(f"imageMainTag={image_main_tag}", file=_output) + print(f"imageMainName={image_tags[0]}", file=_output) diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index 3625d0213b..cf0ee5936f 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -213,6 +213,9 @@ jobs: permissions: # Needed to upload contianer images to ghcr.io packages: write + # Needed for attestation + id-token: write + attestations: write timeout-minutes: 120 steps: - uses: actions/checkout@v4 @@ -241,6 +244,7 @@ jobs: run: make gen-client-ts - name: Build Docker Image uses: docker/build-push-action@v6 + id: push with: context: . secrets: | @@ -253,6 +257,12 @@ jobs: cache-from: type=registry,ref=ghcr.io/goauthentik/dev-server:buildcache cache-to: type=registry,ref=ghcr.io/goauthentik/dev-server:buildcache,mode=max platforms: linux/${{ matrix.arch }} + - uses: actions/attest-build-provenance@v1 + id: attest + with: + subject-name: ${{ steps.ev.outputs.imageNames }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: ${{ steps.ev.outputs.shouldBuild == 'true' }} pr-comment: needs: - build @@ -276,4 +286,4 @@ jobs: - name: Comment on PR uses: ./.github/actions/comment-pr-instructions with: - tag: gh-${{ steps.ev.outputs.imageMainTag }} + tag: ${{ steps.ev.outputs.imageMainTag }} diff --git a/.github/workflows/ci-outpost.yml b/.github/workflows/ci-outpost.yml index 98d388c4f6..6d39d39348 100644 --- a/.github/workflows/ci-outpost.yml +++ b/.github/workflows/ci-outpost.yml @@ -71,6 +71,9 @@ jobs: permissions: # Needed to upload contianer images to ghcr.io packages: write + # Needed for attestation + id-token: write + attestations: write steps: - uses: actions/checkout@v4 with: @@ -96,6 +99,7 @@ jobs: - name: Generate API run: make gen-client-go - name: Build Docker Image + id: push uses: docker/build-push-action@v6 with: tags: ${{ steps.ev.outputs.imageTags }} @@ -107,6 +111,12 @@ jobs: context: . cache-from: type=registry,ref=ghcr.io/goauthentik/dev-${{ matrix.type }}:buildcache cache-to: type=registry,ref=ghcr.io/goauthentik/dev-${{ matrix.type }}:buildcache,mode=max + - uses: actions/attest-build-provenance@v1 + id: attest + with: + subject-name: ${{ steps.ev.outputs.imageNames }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: ${{ steps.ev.outputs.shouldBuild == 'true' }} build-binary: timeout-minutes: 120 needs: diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index 2f46af608b..f4bbd6e25c 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -11,6 +11,9 @@ jobs: permissions: # Needed to upload contianer images to ghcr.io packages: write + # Needed for attestation + id-token: write + attestations: write steps: - uses: actions/checkout@v4 - name: Set up QEMU @@ -41,6 +44,7 @@ jobs: mkdir -p ./gen-go-api - name: Build Docker Image uses: docker/build-push-action@v6 + id: push with: context: . push: true @@ -49,11 +53,20 @@ jobs: GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }} tags: ${{ steps.ev.outputs.imageTags }} platforms: linux/amd64,linux/arm64 + - uses: actions/attest-build-provenance@v1 + id: attest + with: + subject-name: ${{ steps.ev.outputs.imageNames }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true build-outpost: runs-on: ubuntu-latest permissions: # Needed to upload contianer images to ghcr.io packages: write + # Needed for attestation + id-token: write + attestations: write strategy: fail-fast: false matrix: @@ -95,12 +108,19 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build Docker Image uses: docker/build-push-action@v6 + id: push with: push: true tags: ${{ steps.ev.outputs.imageTags }} file: ${{ matrix.type }}.Dockerfile platforms: linux/amd64,linux/arm64 context: . + - uses: actions/attest-build-provenance@v1 + id: attest + with: + subject-name: ${{ steps.ev.outputs.imageNames }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true build-outpost-binary: timeout-minutes: 120 runs-on: ubuntu-latest @@ -178,8 +198,8 @@ jobs: image-name: ghcr.io/goauthentik/server - name: Get static files from docker image run: | - docker pull ${{ steps.ev.outputs.imageMainTag }} - container=$(docker container create ${{ steps.ev.outputs.imageMainTag }}) + docker pull ${{ steps.ev.outputs.imageMainName }} + container=$(docker container create ${{ steps.ev.outputs.imageMainName }}) docker cp ${container}:web/ . - name: Create a Sentry.io release uses: getsentry/action-release@v1