Continuum AI is now public. Try out the most secure GenAI service!
Blog
Fabian Kammel
Constellation, our Confidential Kubernetes engine, is now open source. Check it out on GitHub or say "Hi" on Discord.
In a previous post, we explored how to generate a Software Bill of Materials (SBOM) and subsequently scan them for vulnerabilities. In this post, we show you how SBOMs can be signed and then stored in the same container registry as the scanned image. This improves security & discoverability!
Up until now, our generated SBOM is a plain JSON file with some metadata and a list of dependencies. This leaves lots of room for malicious actors to manipulate our SBOM before it gets to our users.
How could a malicious actor benefit?
Signing our SBOMs enables end users to trust the dependency information we publish and make sure it has not been tampered with!
On the other side, the consumer needs more than just the signature. A valid signature proves that the private key and signed data were in the same place at the same time. The signed data needs to make a claim (predicate) about a thing (subject).
Our signature proves that the SBOM was generated for our specific artifact at a given point in time.
Finally, in-toto attestations are a developing standard and define a format to hold exactly this information: a signature and payload, which contains a subject and predicate.
In our v2.1.0 release of Constellation, we stored the SBOMs for our container images in our GitHub release, while our images were stored in the GitHub Container Registry (ghcr.io). This made it difficult for users to discover our SBOMs.
$ cosign tree ghcr.io/edgelesssys/constellation/verification- service:v2.1.0 📦 Supply Chain Security Related artifacts for an image: ghcr.io/edgelesssys/constellation/verification-service:v2.1.0 No Supply Chain Security Related Artifacts artifacts found for image ghcr.io/edgelesssys/constellation/verification-service:v2.1.0
Since then we learned that cosign attach can be used to store this critical meta information directly with the artifact in the same registry!
$ cosign attach --help Provides utilities for attaching artifacts to other artifacts in a registry Usage: cosign attach [command] Available Commands: attestation Attach attestation to the supplied container image sbom Attach sbom to the supplied container image signature Attach signatures to the supplied container image
The actual implementation is quite easy, once you understand what each step is for. Syft and sigstore already took care of the integration work, so Syft can directly sign with our cosign.key.
IMAGE_REF=ghcr.io/edgelesssys/constellation/verification-service:v2.2.0 syft attest --key cosign.key -o cyclonedx-json ${IMAGE_REF} > verification- service.att.json cosign attach attestation --attestation verification- service.att.json ${IMAGE_REF} cosign verify-attestation ${IMAGE_REF} --type 'https://cyclonedx.org/bom' --key cosign.pub
The attached metadata can be discovered and consumed automatically.
$ cosign tree ghcr.io/edgelesssys/constellation/verification- service@sha256:fe31333a0696e4b044a2e1e7c6d6c88d7c387753350f68e7533383e1c70e6360 📦 Supply Chain Security Related artifacts for an image: ghcr.io/edgelesssys/constellation/verification- service@sha256:fe31333a0696e4b044a2e1e7c6d6c88d7c387753350f68e7533383e1c70e6360 └── 💾 Attestations for an image tag: ghcr.io/edgelesssys/constellation/verification-service:sha256- fe31333a0696e4b044a2e1e7c6d6c88d7c387753350f68e7533383e1c70e6360.att └── 🍒 sha256:8a369a8bac7d8d9ea8540e1d90478842b2e79cb4a2ea248636d99daa0b60186b
At the time of writing this, an open issue exists, which requires the user to manually specify the --type parameter when using cosign verify-attestation.
It is not trivial to find the value for this parameter because a lot of encoded and nested data structures need to be unpacked to find the actual value. As commented on the issue, cosign download can be used to fetch the in-toto attestation. The payload field contains the base64 encoded in-toto statement, which contains the predicateType we are looking for.
A handy one-liner can be used to fetch the information easily:
cosign download attestation <image_ref> | jq -r .payload | base64 -d | jq .predicateType
Follow Edgeless Systems, to learn how we continue to secure the supply chain of Constellation, and don't forget to star it on GitHub!