ci: sign Docker images and attach build provenance - #4451
Draft
stevenvegt wants to merge 3 commits into
Draft
Conversation
Images pushed to Docker Hub are now signed with cosign using the GitHub Actions OIDC identity (Sigstore keyless), and BuildKit SLSA provenance and SBOM attestations are embedded in the image index. This lets users verify that a published image was built by this repository's CI workflow, rather than pushed manually with Docker Hub credentials. Signing runs in a separate job because GitHub does not issue OIDC tokens to workflows triggered from forked pull requests, and to avoid exposing the OIDC credential to third-party build actions. Assisted-by: AI
Contributor
|
Coverage Impact This PR will not change total coverage. 🚦 See full report on Qlty Cloud »🛟 Help
|
Adds a deployment page showing how to verify image signatures with cosign, deploy by digest, and enforce verification with Kyverno on Kubernetes/AKS and in Azure DevOps pipelines. Assisted-by: AI
Embargoed security releases are built from the private clone nuts-foundation/nuts-node-private, so their signature carries that repository's workflow identity. Accepting only the public identity would make enforcing verifiers reject exactly the security releases users most need to install. Assisted-by: AI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What
Adds Sigstore keyless signing and SLSA provenance/SBOM attestations to the Docker image build workflow, plus user documentation (deployment section) covering manual verification, digest pinning, and enforcement in Kubernetes/AKS and Azure DevOps pipelines. Images pushed to Docker Hub (master and release tags) are signed with cosign using the workflow's GitHub Actions OIDC identity.
Why
Today, possession of the Docker Hub credentials is the only thing standing between users and a locally built image published under our name. With keyless signing, the signature certificate names the repository, workflow file, ref and commit. A signature with that identity can only be produced by the workflow running on GitHub's infrastructure, not by anyone holding registry credentials. Every signature is also recorded in the public Rekor transparency log, so signing events are auditable after the fact.
Users can verify a published image with:
The identity regexp also accepts
nuts-foundation/nuts-node-private, the private clone that embargoed security releases are built from; rejecting that identity would make enforcing verifiers block exactly the security releases users most need to install. The new docs page (docs/pages/deployment/verifying-images.rst) expands on this with digest pinning for docker-compose, a Kyverno ClusterPolicy for cluster-side enforcement, and an Azure DevOps pipeline gate.Design notes
id-token: writeout of the build job means none of the third-party build actions ever see the OIDC credential.provenance: mode=maxembeds BuildKit SLSA provenance (source repo, commit, build args) in the pushed image index;sbom: trueadds an SPDX SBOM. On their own these are unsigned metadata; the cosign signature over the index digest is what makes them tamper-evident.latest,master) is covered. Signatures appear on Docker Hub assha256-<digest>.sigpseudo-tags.:devconvenience image is intentionally left unsigned for now.Validation
The workflow change cannot be fully exercised from a PR build: the sign job is skipped on
pull_requestevents and PR builds do not push. The first real validation is the workflow run on master after merge; that run should be watched and the resultingmasterimage verified with the command above. The documentation was built locally with the docs Docker image; the new page compiles without warnings.Follow-ups
nuts-foundation/nuts-node-private, so embargoed releases are signed. Until that is done, an embargoed release ships unsigned and fails verification.Assisted-by: AI