Hardened Container Images 101: What, Why, and How for DevSecOps [2025]
Transcript:
Most teams use containers, but not all of them know or control how many vulnerabilities or unnecessary packages their base image contains. Hardened container images help to solve these issues. Minimized attack surface, low to zero CVEs, immutable component set, and continuous patching. Let's explore these and other features of hardened container images and see how to integrate them into your workflow.
Many container images ship with some random base that includes a ton of unnecessary tools such as a package manager, a debugger, a compiler, and lots of random utilities. What is worse, the base image often lacks provenance, so it is hard to determine what is in the base image anyway. The result is more than 600 vulnerabilities in a typical container image. Most of them are in the base image, not in the application code.
The attack surface is the size of a given container image. Every scan report contains hundreds of CVEs. You either accept the risk or drown in the attempt to patch them all. Of course, you can try to patch all these vulnerabilities, but few teams do that. And frankly, it is not your job to solve issues in code that you did not write.
Hardened container images are there to solve these issues. One can say that they set a new standard for container image security. The concept of hardened container images rests on four key pillars.
First, a minimalistic base. The image contains only the components your application needs to function in production. No unnecessary packages, hence a reduced attack surface.
Second, low to zero CVEs. The vendor of hardened base images performs continuous patching so the base image stays free of known vulnerabilities.
Third, an immutable component set. Hardened images cannot be modified. There is no package manager and no other ability to change them. The risk of attackers introducing malicious packages or tampering with a container at runtime is minimized.
Fourth, provenance data. The images come with a software bill of materials and a digital signature. You can always verify their origin and the components they contain.
You might have heard of or even used distroless images. What is the difference between them and hardened base images? Distroless images are about stripping down almost all Linux components, including the shell. Image hardening, on the other hand, is about a clear CVE management process: tracking components, monitoring CVEs, and patching them.
Hardened container images integrate perfectly into DevSecOps practices, and here is why. You get reduced noise from security scanners. Fewer CVEs mean fewer false-positive alerts, so the security team can focus on real issues. You can shift security left without slowing down deployments, with hardened images standardized across the organization. Developers do not have to reinvent Dockerfiles every time.
Thanks to SBOMs and digital signatures, hardened container images facilitate compliance and audits. You can say that you know exactly what you are running in production and easily prove it. The potential attack blast radius is reduced. For attackers, it is harder to introduce malicious packages or exploit known vulnerabilities because there is basically nothing in the container image they can leverage.
To sum up, hardened container images are a security baseline. You standardize deployment processes once and solve several problems right away: compliance, CVE monitoring, and patching.
Now let's look at how we can introduce hardened container images into the workflow. There are several vendors who provide hardened container images. I will use BellSoft's hardened images as an example. They are available for free on various registries and for various runtimes.
To try them out, pull the required container image. You can use Cosign to verify the image signature. Then you can run it with your application.
Suppose you have a Dockerfile and you want to migrate to a hardened base. On the screen, you can see a Dockerfile for a Java project. It uses OpenJDK as a base image, compiles, and runs the application. To use a hardened base, we need to rewrite this Dockerfile to use multi-stage builds. We build the application in the first stage and then transfer it into a fresh base image without any packages or tools used during the build. This way, the image will be smaller and free of additional utilities.
If you already use multi-stage builds, migrating to a hardened base image is just a matter of substituting the FROM command. Remember that hardened base images are immutable, so you cannot add additional packages. It is also recommended to pin the image by digest for reproducibility.
As far as signature verification is concerned, Cosign verification can be introduced into the CI/CD pipeline, for example with GitHub Actions.
That was hardened container images 101. Leave a comment if you want me to discuss other topics related to hardened images. And as usual, do not forget to like, subscribe, and until next time.





