This project demonstrates how to use a series of tools to build container images with corresponding Software Bill Of Materials, or SBOM. The tools highlight the use of container basics, an SBOM generation tool, and an OCI compatible registry. The end result is an end-to-end (albeit, hacky) solution to integrate SBOM generation and distribution into the container ecosystem.
We will use Virtual Box and Vagrant to spin up a Vagrant box (a VM) containing all the required ingredients installed. We just clone this project, cd into it and run:
vagrant up
vagrant ssh
Note: depending on how powerful your computer is, bringing up the Vagrant box can take a long time. Perhaps go make yourself a nice cup of tea and come back.
Once we are in the vagrant box, we can spin up an instance of the distribution registry:
$ podman pull registry:2.7.1
$ podman run -d -p 5000:5000 --name registry registry:2.7.1
Or run the convenience podman_setup.sh
script:
$ cd containers-with-sboms
$ ./podman_setup.sh
We then build the container and corresponding sbom:
$ cd containers-with-sboms <-- (only if you are not already in the directory)
$ ./base_container.sh
This should create a container called localhost:5000/debian:10
, and a file called debian-sbom
, which is also pushed to the local registry. You should still be able to see the image when running podman images
or buildah images
and the sbom file.
Now that we have a container with an OS and a corresponding SBOM, we can create another container on top of this which includes the original SBOM:
$ ./derived_container.sh
This should create container called localhost:5000/python:3
and two files called debian-sbom
and python-sbom
. These files can be deleted as we now have them on the registry.
The SBOMs can be signed using cosign
just like container images!
First, generate a cosign key-pair
$ cosign generate-key-pair
Enter password for private key: Enter again:
Private key written to cosign.key
Public key written to cosign.pub
$ cosign init
Now you can sign the SBOM image
cosign sign -key cosign.key localhost:5000/debian-sbom:10
Pushing signature to: localhost:5000/debian-sbom:sha256-b284208b40a3886b7aac543312dce3aba2123602a013ce56c156276de9e838f4.sig
The nice thing about reusing SBOMs in this way is that even if the build container is gone, the SBOMs describing the containers remain and can be propagated with the deployment image. To demonstrate this, we first make a golang container using the base debian image and a golang binary:
$ ./golang_container.sh
We can then use this container to build our golang application:
$ ./hello_container.sh
$ podman run localhost:5000/hello:1.0 hello
You may view the bootstrap.sh
script to see how to provision a single node with all the tools. Here, I am using a debian/bullseye Vagrant box as it is the easiest seed for creating a base container rootfs. Your Mileage May Vary.
Overall, you will need the following tools:
base_container.sh
creates a container from scratch using buildah.buildah unshare
will mount the container in the user's namespace and return a mount path. There is some path manipulation as this is not exactly where the files are located since buildah unshare
creates the mount point in a different namespace which disappears.buildah add
will add the debian.tar
rootfs which we had created before using debootstrap
.buildah commit
will create an image containing this rootfs.tern report --live
will generate an SBOM given the path to the rootfs. The rootfs doesn't have to be mounted at this point, although in order to show the resulting filesystem created by the storage driver in subsequent container uses, this is required for generating an accurate SBOM.We notice that there are some very basic UX needs in order to make this usable at a large scale:
We need to keep track of all of the tags. This is currently the problem with many client tools which use registries to store artifacts along with container images. A working group on using Reference Types which link the artifacts back to the container image allows the reduction of tags as shown below
I don't expect contributions to this project, but if you feel it is missing some key information or some misconceptions, feel free to submit a PR! For more details on how to contribute, refer to CONTRIBUTING.md.
This project is licensed under the BSD-2-Clause license. Please refer to the LICENSE and NOTICE files for more information.