Do You Know What’s In Your Docker Image? Buildpacks Do.

Emily Casey
Buildpacks
Published in
3 min readNov 19, 2019

You can’t patch a vulnerability you don’t know you have. That’s why knowing what’s inside a Docker image is the first step toward making sure it’s secure. Fortunately, any image that’s built with Cloud Native Buildpacks contains metadata you can use to determine not only what the image contains, but also what’s in each layer and how the image was created.

Any image you create with the Pack CLI using the pack build command can also be inspected with the inspect-image command, like this:

$ pack inspect-image ekcasey/myimage
Inspecting image: ekcasey/myimage
REMOTE:Stack: io.buildpacks.stacks.bionicBase Image:
Reference: index.docker.io/cloudfoundry/run@sha256:8de6ef35195a6ebb4875cfb2ab5dfb4334c7bef85425318739a6c6bfc4edb202
Top Layer: sha256:9335faa48c88fc9f7f831f86e41ba979fa402bc715671b11d63c4f3eb4f69458
Run Images:
cloudfoundry/run:base-cnb
Buildpacks:
ID VERSION
org.cloudfoundry.openjdk v1.0.48
org.cloudfoundry.jvmapplication v1.0.66
org.cloudfoundry.springboot v1.0.88
LOCAL:
...

This example output tells us that the image was built with three buildpacks. It also tells us the stack ID and the tag of the run-image used to create the final image. Included with this information is the reference for the “Top Layer” of the stack, which you can use to separate the base image from the layers the buildpack created.

This information is what Pack uses to perform its rebase command, where the layers created by the buildpack are used to create a new image with an updated stack — without ever running a build.

The metadata on the image also contains information about what’s inside each layer. We can view this by providing the --bom option, which emits a Bill-of-Materials for the image. This information is derived from the build plan created by the buildpacks. Because this information is stored in the config layer of the image it can be read cheaply without pulling the entire image from the registry.

$ pack inspect-image ekcasey/myimage --bom | jq .remote
[
{
"buildpack": {
"id": "org.cloudfoundry.openjdk",
"version": "v1.0.48"
},
"metadata": {
"licenses": [
{
"type": "GPL-2.0 WITH Classpath-exception-2.0",
"uri": "https://openjdk.java.net/legal/gplv2+ce.html"
}
],
"name": "OpenJDK JRE",
"sha256": "2f08c469c9a8adea1b6ee3444ba2a8242a7e99d87976a077faf037a9eb7f884b",
"uri": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.5%2B10/OpenJDK11U-jre_x64_linux_hotspot_11.0.5_10.tar.gz"
},
"name": "openjdk-jre",
"version": "11.0.5"
},
...

In this entry we can see that the image contains OpenJDK JRE version 11.0.5. We can also see the license associated with this JRE and the URI it was pulled from.

Another example Bill-of-Materials entry contains information including the classpath and installed dependencies

$ pack inspect-image ekcasey/myimage --bom | jq .remote
...
{
"buildpack": {
"id": "org.cloudfoundry.springboot",
"version": "v1.0.88"
},
"metadata": {
"classes": "BOOT-INF/classes/",
"classpath": [
"/workspace/BOOT-INF/classes",
"/workspace/BOOT-INF/lib/attoparser-2.0.5.RELEASE.jar",
"/workspace/BOOT-INF/lib/classmate-1.4.0.jar",
"/workspace/BOOT-INF/lib/hibernate-validator-6.0.18.Final.jar",
"/workspace/BOOT-INF/lib/jackson-annotations-2.9.10.jar",
...
],
"lib": "BOOT-INF/lib/",
"start-class": "io.buildpacks.example.sample.SampleApplication",
"version": "2.1.10.RELEASE"
},
"name": "spring-boot",
"version": ""
},
...

This information can be used by hand or more likely with automation to ensure compliance, scan for vulnerable dependencies, or to generate files for open source licensing disclosure.

Buildpacks use structured data to report the exact contents of an image instead of relying on external tools that glean what they can from the filesystem. This makes them well suited for organizations that have strict compliance or security requirements without forcing developers to compromise on their tooling. Buildpacks achieve a balance between ease-of-use and operability by separating developers from concerns like generating a Bill-of-Materials.

--

--