From 59d3bba835b6171a0e7516cdeccbc57a2309f9d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20M=C3=A9taireau?= Date: Tue, 22 Apr 2025 17:45:53 +0200 Subject: [PATCH] CI: Add an option to attach container signatures to the registry The `build-push-image.yml` reusable workflow can generate keypairs and sign the container images with them. This is only used by the CI, to test that a valid signature is actually detected as such. --- .github/workflows/build-push-image.yml | 56 ++++++++++++++++++- .github/workflows/ci.yml | 52 +++++------------ .github/workflows/release-container-image.yml | 1 + 3 files changed, 70 insertions(+), 39 deletions(-) diff --git a/.github/workflows/build-push-image.yml b/.github/workflows/build-push-image.yml index e6a7892..af48634 100644 --- a/.github/workflows/build-push-image.yml +++ b/.github/workflows/build-push-image.yml @@ -15,11 +15,21 @@ on: reproduce: required: true type: boolean + sign: + required: true + type: boolean + key_name: + required: false + type: string + default: "dangerzone-tests" + key_cache: + required: false + type: string + default: "v1-keypair-${{ github.ref_name }}" # unique for the branch / PR secrets: registry_token: required: true - jobs: lint: runs-on: ubuntu-latest @@ -44,6 +54,7 @@ jobs: debian_archive_date: ${{ steps.params.outputs.debian_archive_date }} source_date_epoch: ${{ steps.params.outputs.source_date_epoch }} image: ${{ steps.params.outputs.full_image_name }} + tag: ${{ steps.params.outputs.tag }} steps: - uses: actions/checkout@v4 with: @@ -60,7 +71,7 @@ jobs: echo "debian_archive_date=${DEBIAN_ARCHIVE_DATE}" >> $GITHUB_OUTPUT echo "source_date_epoch=${SOURCE_DATE_EPOCH}" >> $GITHUB_OUTPUT - echo "tag=${DEBIAN_ARCHIVE_DATE}-${TAG}" >> $GITHUB_OUTPUT + echo "tag=${TAG}" >> $GITHUB_OUTPUT echo "full_image_name=${FULL_IMAGE_NAME}" >> $GITHUB_OUTPUT echo "buildkit_image=${BUILDKIT_IMAGE}" >> $GITHUB_OUTPUT @@ -73,6 +84,7 @@ jobs: debian_archive_date: ${{ needs.prepare.outputs.debian_archive_date }} source_date_epoch: ${{ needs.prepare.outputs.source_date_epoch }} image: ${{ needs.prepare.outputs.image }} + tag: ${{ needs.prepare.outputs.tag }} strategy: fail-fast: false matrix: @@ -140,6 +152,7 @@ jobs: debian_archive_date: ${{ needs.build.outputs.debian_archive_date }} source_date_epoch: ${{ needs.build.outputs.source_date_epoch }} image: ${{ needs.build.outputs.image }} + tag: ${{ needs.build.outputs.tag }} digest_root: ${{ steps.image.outputs.digest_root }} digest_amd64: ${{ steps.image.outputs.digest_amd64 }} digest_arm64: ${{ steps.image.outputs.digest_arm64 }} @@ -246,3 +259,42 @@ jobs: --platform \ linux/${{ matrix.platform.name }} \ ${{ needs.merge.outputs[format('digest_{0}', matrix.platform.name)] }} + + sign: + if: ${{ inputs.sign }} + runs-on: "ubuntu-latest" + env: + COSIGN_PASSWORD: "password" + COSIGN_YES: true + needs: + - merge + # outputs: add signature location ? + steps: + - name: Install Cosign + uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a + with: + cosign-release: 'v2.5.0' + - name: Check install + run: cosign version + - name: Generate keypair + run: |- + cosign generate-key-pair --output-key-prefix="${{ inputs.key_name }}" + - name: Cache keypair + uses: actions/cache@v4 + with: + path: "${{ inputs.key_name }}.*" + key: ${{ inputs.key_cache }} + enableCrossOsArchive: true + + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ inputs.registry_user }} + password: ${{ secrets.registry_token }} + + - name: Sign container + run: |- + export IMAGE_URI="${{ inputs.registry }}/${{ inputs.image_name }}:${{ needs.merge.outputs.tag }}@${{ needs.merge.outputs.digest_root }}" + cosign sign -d --yes --key=${{ inputs.key_name }}.key "$IMAGE_URI" + shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ee7bd73..a862710 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,11 +11,10 @@ on: permissions: packages: write + actions: read # for detecting the Github Actions environment. + id-token: write # for creating OIDC tokens for signing. env: - REGISTRY_USER: ${{ github.actor }} - REGISTRY_PASSWORD: ${{ github.token }} - IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} QT_SELECT: "qt6" # Disable multiple concurrent runs on the same branch @@ -45,35 +44,18 @@ jobs: # This is already built daily by the "build.yml" file # But we also want to include this in the checks that run on each push. build-container-image: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Get current date - id: date - run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT - - - name: Cache container image - id: cache-container-image - uses: actions/cache@v4 - with: - key: v5-${{ steps.date.outputs.date }}-${{ hashFiles('Dockerfile', 'dangerzone/conversion/*.py', 'dangerzone/container_helpers/*', 'install/common/build-image.py') }} - path: |- - share/container.tar - share/image-id.txt - - - name: Build Dangerzone container image - if: ${{ steps.cache-container-image.outputs.cache-hit != 'true' }} - run: | - python3 ./install/common/build-image.py - - - name: Upload container image - uses: actions/upload-artifact@v4 - with: - name: container.tar - path: share/container.tar + name: Build, push and sign container image + uses: ./.github/workflows/build-push-image.yml + with: + registry: "ghcr.io/${{ github.repository_owner }}" + registry_user: ${{ github.actor }} + image_name: "dangerzone/dangerzone-staging" + reproduce: false + sign: true + key_name: "dangerzone-tests" + key_cache: "v1-test-keypair-${{ github.ref_name }}" + secrets: + registry_token: ${{ secrets.GITHUB_TOKEN }} download-tessdata: name: Download and cache Tesseract data @@ -227,9 +209,7 @@ jobs: uses: actions/cache/restore@v4 with: key: v5-${{ steps.date.outputs.date }}-${{ hashFiles('Dockerfile', 'dangerzone/conversion/*.py', 'dangerzone/container_helpers/*', 'install/common/build-image.py') }} - path: |- - share/container.tar - share/image-id.txt + path: share/container.tar fail-on-cache-miss: true - name: Build Dangerzone .deb @@ -336,7 +316,6 @@ jobs: key: v5-${{ steps.date.outputs.date }}-${{ hashFiles('Dockerfile', 'dangerzone/conversion/*.py', 'dangerzone/container_helpers/*', 'install/common/build-image.py') }} path: |- share/container.tar - share/image-id.txt fail-on-cache-miss: true - name: Build Dangerzone .rpm @@ -433,7 +412,6 @@ jobs: key: v5-${{ steps.date.outputs.date }}-${{ hashFiles('Dockerfile', 'dangerzone/conversion/*.py', 'dangerzone/container_helpers/*', 'install/common/build-image.py') }} path: |- share/container.tar - share/image-id.txt fail-on-cache-miss: true - name: Restore cached tessdata diff --git a/.github/workflows/release-container-image.yml b/.github/workflows/release-container-image.yml index da63204..98ff66e 100644 --- a/.github/workflows/release-container-image.yml +++ b/.github/workflows/release-container-image.yml @@ -18,5 +18,6 @@ jobs: registry_user: ${{ github.actor }} image_name: dangerzone/dangerzone reproduce: true + sign: false secrets: registry_token: ${{ secrets.GITHUB_TOKEN }}