Container security often fails before your application ever runs. Five minutes after deployment, your CNAPP reports more than 250 container image vulnerabilities in a brand-new application, even though it hasn't processed a single request. Nobody has exploited it. Your developers haven't even logged into the pod.
So where did those software vulnerabilities come from?
Most security teams instinctively start with the dashboard.
- Which CVEs are critical?
- Which workloads are exposed?
- Which vulnerabilities should be patched first?
Those are important questions. Modern Cloud-Native Application Protection Platforms (CNAPPs) excel at answering them by providing visibility into cloud-native environments, prioritizing risk, and helping security teams respond faster.
But they’re not the first questions. The first question is much simpler.
How did a brand-new application become vulnerable before anyone had even used it?
At first glance, the answer seems obvious. Someone probably wrote vulnerable code. A dependency must have introduced the issue. Maybe the application was compromised during deployment.
In reality, that’s often not what happened.
Many of the vulnerabilities reported after deployment were introduced long before Kubernetes scheduled the first pod. They were already present when the container image was assembled, inherited from software that existed before your application was ever copied into the image.
That distinction changes how we think about container security.
This blog isn’t about replacing your CNAPP or comparing security tools. Quite the opposite. A CNAPP plays a critical role in modern cloud-native security by helping organizations understand what is running in production, identify operational risk, and prioritize remediation.
Instead, we explore something that receives far less attention.
Where does container security actually begin?
To answer that question, we’re going to investigate a single container from the moment it’s created until the moment a CNAPP reports its first vulnerability.
By the end, you’ll see that while your CNAPP may be the first place you discover a vulnerability, it’s rarely where that vulnerability originated.
The Investigation Begins: Inside a Vulnerable Container Image
Every investigation starts with evidence. In our case, the evidence isn’t a Kubernetes cluster, a vulnerability scanner, or a CNAPP dashboard. It’s the container itself.
If we want to understand where those 250+ vulnerabilities came from, we need to go back to the moment the container was created and examine what went into it.
Let’s start with a container that looks familiar.
FROM python:3.12WORKDIR /appCOPY requirements.txt .RUN pip install -r requirements.txtCOPY . .CMD ["python", "app.py"] If you’ve worked with Docker before, this Dockerfile probably looks familiar. It starts from an official Python base image, installs the application’s dependencies, copies the source code, and defines the command that starts the application.
Nothing unusual. In fact, thousands of production applications start exactly this way.
Now imagine you’re reviewing this Dockerfile during a pull request. At this point, most engineers naturally focus on the application.
- Is the code correct?
- Are the dependencies up to date?
- Does the application build successfully?
Those are all reasonable questions. But there’s another question that often goes unasked.
How much software did we just inherit before adding a single line of our own code?
It may not look like the most important line in the Dockerfile.
For this investigation, it is.
FROM python:3.12In a single line, you’ve chosen a base image that brings with it an operating system, language runtime, system libraries, cryptographic libraries, and hundreds of supporting components that become part of your final container image.
Long before your application starts running, one of the most important security decisions in its lifecycle has already been made.
Evidence #1: Our Container Isn’t Empty
It’s easy to think of a container image as “our application packaged with Docker.” In reality, your application is only one layer of the final artifact.
The moment you write:
FROM python:3.12you’re doing much more than choosing a programming language. You’re inheriting an entire software stack.
Conceptually, it looks something like this.

Before your application has a chance to process its first request, it already depends on software contributed by multiple upstream projects. Some components provide the operating system, others provide the language runtime, and still others handle networking, encryption, certificates, compression, or memory management. Your application sits on top of all of them.
Your application sits on top of all of them.
Every layer you inherit becomes part of your application’s attack surface, whether your developers interact with it directly or not.
More importantly, those inherited components become part of the software supply chain your organization is ultimately responsible for securing.
If one of those underlying components later receives a security advisory, that advisory becomes part of your application’s security posture, even though your developers never wrote that code.
You can see this yourself by inspecting the image layers.
docker history python:3.12 The output reveals that several layers already exist before your application is copied into the image.
Those layers represent software that has already been assembled, packaged, and shipped long before your own application enters the picture.
Investigation Note #1
Before your application exists, your container already contains an operating system, a language runtime, cryptographic libraries, operating system packages, and supporting software inherited from the base image.
Your application isn’t the entire container. It’s simply the latest addition to software that already existed.
Evidence #2: How Base Image Vulnerabilities Reach Production
Now let’s return to the question we started with.
Five minutes after deployment, your CNAPP reports more than 250 vulnerabilities.
Imagine one of those findings is a vulnerability in OpenSSL.
This isn’t just a hypothetical scenario. Security teams routinely discover vulnerabilities in shared components such as OpenSSL, glibc, and operating system packages that were inherited through the base image rather than introduced by application code.
A single vulnerable base image can become the foundation for hundreds of application images across an enterprise.
A CNAPP correctly identifies where those vulnerable workloads exist.
Understanding how that vulnerable component entered the image requires looking further back in the software lifecycle.
At first glance, the conclusion seems obvious: “Our application contains a vulnerable version of OpenSSL.”
But does it?
Let’s walk backwards.

This is the journey the vulnerability took before it appeared on your dashboard.
The CNAPP didn’t create it. Kubernetes didn’t introduce it. Your application may not even use OpenSSL directly.
The vulnerability became part of your application the moment the base image introduced that library into the final artifact.
That doesn’t mean every reported vulnerability is inherited from a base image. Application dependencies, language packages, and custom software can all introduce vulnerabilities as well.
The important observation is this:
By the time your CNAPP reports a vulnerability, the software that contains it has already been assembled.
Investigation Note #2
A CNAPP tells you where the vulnerability was found.
Understanding where it entered the software requires looking much further back in the software lifecycle.
Evidence #3: What a CNAPP Actually Secures in Cloud-Native Environments
At this point, it’s worth asking another question.
If vulnerabilities often originate earlier, what exactly is the role of a CNAPP?
The answer is simple: a very important one.
Modern Cloud-Native Application Protection Platforms provide the operational visibility needed to secure cloud-native environments at scale. They help organizations understand the security posture of their cloud infrastructure and workloads by answering questions such as:
- Which workloads are vulnerable?
- Which containers are publicly exposed?
- Which Kubernetes resources violate policy?
- Which identities have excessive permissions?
- Which risks should be addressed first?
- Which vulnerabilities are actively exploitable?
Those capabilities are indispensable. But notice something interesting.
Every capability we just listed assumes the software already exists. The image has been built, the artifact has been published, and the workload has been deployed.
The CNAPP isn’t responsible for creating software. It’s responsible for understanding the security posture of software that’s already running.
That isn’t a limitation. It’s exactly where a CNAPP provides the greatest value.
Conceptually, the lifecycle looks like this.

The software already exists.
The CNAPP helps you understand its security posture, prioritize operational risk, and respond effectively.
Runtime visibility is most effective when it’s paired with stronger software entering production.
The best runtime security outcomes begin with stronger software foundations.
The earlier software quality is improved; the less inherited risk runtime security needs to manage.
The Real Shift in Thinking
By now, our investigation has revealed something important.
The dashboard wasn’t the beginning of the story.
It was simply the first place we noticed the problem.
For years, container security has largely been discussed in terms of products.
Container scanners, CNAPPs, admission controllers, and runtime protection each play an important role, but they all answer questions about software that already exists.
Our investigation didn’t reveal a tooling problem. It revealed a software lifecycle problem.
The bigger shift is to think about container security as a software lifecycle problem.
A container’s security posture is shaped long before it reaches production.
- Which base image was selected.
- Which dependencies were installed.
- Which software was inherited.
- Which components became part of the final artifact.
- How that artifact was assembled.
Runtime security reveals the result of those decisions.
It doesn’t replace them.
“Where a vulnerability is discovered is rarely where it originated.”
Instead of thinking about container security as a collection of products, think about it as a sequence of decisions.
Stage | Security Question |
|---|---|
Base Image | What software I am starting with? |
Dependencies | What software am I adding? |
Build | What artifact am I producing? |
Registry | What artifact should be deployed? |
Deployment | Should this artifact be allowed to run? |
CNAPP | What risk exists in production? |
Runtime | Is the workload behaving as expected? |
Each stage contributes something different.
None replaces the others.
The further left you improve software quality; the less inherited risk reaches production.
The further right you improve visibility, the faster you can detect, investigate, and respond to operational threats.
The strongest container security strategies invest in both.
Why Container Security Starts Before Your CNAPP
By now, the answer should be clear.
We’re not saying that runtime security is less important. Nor are we suggesting that a CNAPP is somehow incomplete.
Quite the opposite. A CNAPP does exactly what it was designed to do. It provides visibility into software that already exists.
But by the time a CNAPP analyzes a workload, the software inside that workload has already been:
- Selected.
- Assembled.
- Packaged.
- Published.
- Deployed.
Most of the decisions that shaped its security posture have already been made.
That’s why container security starts before your CNAPP.
It begins with the software you choose.
The dependencies you trust.
The artifacts you build.
And the decisions you make before a workload ever reaches production.
Key Takeaway
Where a vulnerability is discovered is rarely where it originated.
A CNAPP tells you where software risk becomes visible.
The software lifecycle tells you where that risk began.
Strengthening Software Before Deployment
Once organizations recognize that many container security risks originate before deployment, the next logical question becomes:
How do we reduce inherited risk before software reaches production?
Most mature engineering organizations strengthen four areas across the software lifecycle:
- Verified software foundations that reduce inherited risk by starting from trusted container images.
- Trusted open-source dependencies that improve the quality and integrity of software entering the build process.
- Software provenance and verification so teams understand exactly what was built, where it came from, and whether it can be trusted.
- Software supply chain visibility and governance that help organizations understand, govern, and enforce policy before software reaches production.
These practices don’t replace runtime security. They make runtime security more effective by improving the software entering production.
This is where CleanStart complements existing container security investments.
CleanStart helps organizations strengthen the earlier stages of the software lifecycle through verified software artifacts, software provenance, and software supply chain visibility.
- CleanStart Images provide verified container images with a minimal software footprint, helping reduce inherited risk before deployment.
- Clean Libraries help engineering teams discover, evaluate, and consume verified open source libraries before they become part of an application.
- CleanSight provides software supply chain visibility, helping teams understand what software they are running, where it originated, and how it entered their environment.
Together, these capabilities strengthen the software entering production while complementing existing CNAPP investments, enabling security teams to spend less time responding to inherited risk and more time focusing on the threats that matter most.
Every Container Image Carries Its Security History
Every software artifact carries the decisions that shaped its security posture.
Your CNAPP tells you how that story ends, showing you the workloads that are vulnerable, the risks that matter, and the threats that require attention.
Understanding how that story began is what enables organizations to build more secure software in the first place.
Because where a vulnerability is discovered is rarely where it originated.
And understanding where it originated is what allows you to write a better ending.



