ci: add cosign keyless signing for container images

Use Sigstore cosign with GitHub Actions OIDC identity tokens to sign
container images pushed to quay.io. This allows users to verify that
images were built by the CI pipeline without requiring any private key
management.

Closes: #117

Assisted-by: Pi (Claude Opus 4.6)
This commit is contained in:
Jonathan Lebon 2026-05-03 18:24:42 -04:00
parent ce7c29dbfc
commit 2bfd8569ba
2 changed files with 39 additions and 3 deletions

View file

@ -86,15 +86,21 @@ jobs:
runs-on: ubuntu-24.04
permissions:
packages: write
id-token: write
steps:
- name: Install cosign
uses: sigstore/cosign-installer@v4.1.1
- name: Create and push manifest
id: push-manifest
run: |
set -euo pipefail
podman login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io
podman manifest create ghcr.io/${{ github.repository }}:${{ github.sha }} \
ghcr.io/${{ github.repository }}:${{ github.sha }}-amd64 \
ghcr.io/${{ github.repository }}:${{ github.sha }}-arm64
podman manifest push ghcr.io/${{ github.repository }}:${{ github.sha }}
podman manifest push --digestfile=/tmp/manifest-digest \
ghcr.io/${{ github.repository }}:${{ github.sha }}
echo "digest=$(cat /tmp/manifest-digest)" >> "${GITHUB_OUTPUT}"
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
TAG="${GITHUB_REF#refs/tags/}"
podman tag ghcr.io/${{ github.repository }}:${{ github.sha }} ghcr.io/${{ github.repository }}:${TAG}
@ -103,6 +109,11 @@ jobs:
podman tag ghcr.io/${{ github.repository }}:${{ github.sha }} ghcr.io/${{ github.repository }}:latest
podman manifest push ghcr.io/${{ github.repository }}:latest
fi
- name: Sign ghcr.io image
run: |
cosign login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }}
cosign sign --yes --recursive \
ghcr.io/${{ github.repository }}@${{ steps.push-manifest.outputs.digest }}
release:
needs: manifest
@ -110,24 +121,35 @@ jobs:
runs-on: ubuntu-24.04
permissions:
packages: write
id-token: write
steps:
- name: Install skopeo
run: sudo apt-get update && sudo apt-get install -y skopeo
- name: Install cosign
uses: sigstore/cosign-installer@v4.1.1
- name: Push to quay.io
id: push-quay
run: |
set -euo pipefail
mkdir -p ~/.docker
echo '${{ secrets.QUAY_AUTH }}' > ~/.docker/config.json
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
TAG="${GITHUB_REF#refs/tags/}"
skopeo copy --all --src-creds=${{ github.actor }}:${{ secrets.GITHUB_TOKEN }} \
skopeo copy --all --digestfile=/tmp/quay-digest \
--src-creds=${{ github.actor }}:${{ secrets.GITHUB_TOKEN }} \
docker://ghcr.io/${{ github.repository }}:${{ github.sha }} docker://quay.io/coreos/chunkah:${TAG}
skopeo copy --all --src-creds=${{ github.actor }}:${{ secrets.GITHUB_TOKEN }} \
docker://ghcr.io/${{ github.repository }}:${{ github.sha }} docker://quay.io/coreos/chunkah:latest
else
skopeo copy --all --src-creds=${{ github.actor }}:${{ secrets.GITHUB_TOKEN }} \
skopeo copy --all --digestfile=/tmp/quay-digest \
--src-creds=${{ github.actor }}:${{ secrets.GITHUB_TOKEN }} \
docker://ghcr.io/${{ github.repository }}:${{ github.sha }} docker://quay.io/coreos/chunkah:dev
fi
echo "digest=$(cat /tmp/quay-digest)" >> "${GITHUB_OUTPUT}"
- name: Sign quay.io image
run: |
cosign sign --yes --recursive \
quay.io/coreos/chunkah@${{ steps.push-quay.outputs.digest }}
- name: Cleanup old images
uses: actions/delete-package-versions@v5
with:

View file

@ -17,6 +17,7 @@ with content-based layers.
- [Motivation](#motivation)
- [Highlights](#highlights)
- [Installation](#installation)
- [Verifying image signatures](#verifying-image-signatures)
- [Usage](#usage)
- [Splitting an existing image](#splitting-an-existing-image)
- [Splitting an image at build time](#splitting-an-image-at-build-time-buildahpodman-only)
@ -80,6 +81,18 @@ may be more convenient to `cargo install` the binary into your builder image
(whether at runtime or build time if you own the builder image). chunkah is also
packaged in Fedora, making it easier to do this there.
### Verifying image signatures
Container images are signed using [cosign] keyless signing. You can verify
the signature of an image using cosign v3+:
```shell
cosign verify \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-github-workflow-repository coreos/chunkah \
quay.io/coreos/chunkah:latest
```
## Usage
There are two main ways to use chunkah:
@ -393,6 +406,7 @@ well.
[add-determinism]: https://github.com/keszybz/add-determinism
[bootable container images]: https://containers.github.io/bootable/
[build-chunked-oci]: https://coreos.github.io/rpm-ostree/build-chunked-oci/
[cosign]: https://github.com/sigstore/cosign
[OCI image config]: https://github.com/opencontainers/image-spec/blob/26647a49f642c7d22a1cd3aa0a48e4650a542269/specs-go/v1/config.go#L24
[buildah-rfe]: https://github.com/containers/buildah/issues/6621
[buildah-annotations-bug]: https://github.com/containers/buildah/issues/6652