In the six months since our last update, Tern has made significant progress towards being a more secure, Kubernetes friendly tool. If you’re not familiar with Tern, it’s an open source inspection tool for generating a Software Bill of Materials (SBOM) for container images and Dockerfiles.
Tern Now Runs in an Unprivileged Container
While we as maintainers have opinions about what we think are important features in the larger context of SBOMs and supply chain security, we also prioritize working on user-requested features. The biggest request we saw from users was to remove the requirement that Tern must run in a privileged container. A privileged container is a container that has all of the root capabilities of the host machine it runs on. In some cases, this may be desirable (i.e. if a container needed to access hardware information) but for containers that may run on public clouds or CI/CD executor VMs, this could give a bad actor critical access to the host’s resources.
Prior to release 2.9.0, if you wanted to run Tern in a container it had to be a privileged container. We are now happy to report that this is no longer the case and Tern now runs in an unprivileged container. This is possible due to a new method of applying the diff file system layers using bulk copy instead of the previous implementation where we relied on the overlay2 or fuse storage driver (which required a privileged container). The new bulk copy implementation copies files between container filesystem layers and analyzes them in context. Note that to maintain backwards compatibility, the overlay2 and fuse drivers are still available to use in Tern using the –driver command line option (but do require running Tern in a privileged container).
Remove Docker Dependency for Container Image Analysis
In December of 2020, the Kubernetes project announced that Docker as an underlying runtime was being deprecated in favor of runtimes that use the Container Runtime Interface (CRI) created for Kubernetes. Specifically, dockershim was being removed from Kubelet, which removed support for Docker as a container runtime in Kubernetes after 1.2.0. As maintainers work towards enabling Tern to run in Kubernetes, this announcement meant that Tern could no longer rely on the use of Docker commands to pull images from a registry if it wanted to be compatible with running in Kubernetes.
We’re happy to announce that starting with Tern version 2.9.0, Tern no longer relies on Docker to pull container images for analysis. Instead, Tern now uses Skopeo. Skopeo is an open source command line utility that has the ability to perform various operations on container images and image repositories. Specifically, Tern uses Skopeo to pull a remote image from a registry prior to inspection. Skopeo uses the OCI schema version 2 to fetch container images. Note that while image analysis no longer relies on Docker to pull the image, Docker is still required to analyze Dockerfiles using Tern.
Support for Two Major SBOM Standards
There are two main SBOM standards that exist to satisfy the NTIA minimum requirements for an SBOM — SPDX and CycloneDX. SPDX is an open, ISO standard for communicating software bill of material information, including components, licenses, copyrights, and security references. Tern can produce both Tag Value and JSON SPDX formatted documents. CycloneDX is a lightweight SBOM standard designed for use in application security contexts and supply chain component analysis. Tern can produce CycloneDX JSON formatted reports for container images and Dockerfiles.
Report Source Package Information
Tern now reports source package name and version in the JSON and YAML reports. Prior to release 2.9.0 Tern only reported binary packages installed in the container. What exactly is a source package, you ask?
Some package managers like Debian and RPM have this concept of source vs binary packages. For these package managers, a source package contains the source code which builds/produces the associated binary packages. The binary packages produced from the source package are what typically get installed. Despite the relationship between source and binary packages, the source and binary package names will typically differ (in rare cases, the source and binary version will also differ). For example, in Debian, the systemd source package produces systemd, udev, libudev1 binaries, and more.
While the source package is not typically installed in a container, source package name and version are helpful data points when it comes to CVE lookups in vulnerability databases. It’s typical for these vulnerabilities to be reported by source package name and version instead of binary package name and version.
Lastly, note that the concept of source package does not exist for all package managers. For the package managers which source packages are applicable, Tern will report the source package information in the JSON and YAML formats. Keep an eye out for source package metadata to make its way into CycloneDX and SPDX reports in the near future.
Tern’s final milestone before declaring our long awaited ‘Beta’ milestone for the project is to create a Docker container that can be released on DockerHub so users can run Tern in a centrally located container instead of having to build it themselves. We hope to have this container uploaded to DockerHub at the end of March 2022. Stay tuned!
As always, if you ever have questions, feature requests, or bugs to report, we’re just a few clicks away via GitHub issues and would be happy to help. Additionally, if you’re interested in contributing to the project, don’t hesitate to reach out on GitHub.