A RapidFort customer preparing a deployment for a large financial institution found a Bluetooth driver package carrying 125 vulnerabilities in an application that never used Bluetooth. No one on the team knew it was there. Removing that package and every other component the application never loaded shrank the image from 1.8 GB to 262 MB. As AI assistants write more of your code, packages like that Bluetooth driver pile up faster, and each one adds to your container attack surface. This article explains why unused components carry more risk now, which leftover tools attackers use first, and how to find and strip unused components from your images on every build.
How AI-assisted development grows your container images
Ask an engineer which Python version a service runs or whether it needs a particular system package, and a common answer today is that they'd have to ask the AI assistant that wrote the code. AI assistants now generate a large share of new code at many organizations. In fact, for about a quarter of Y Combinator startups, 95% of their code base was written by AI. Each time a developer changes a prompt, the assistant can add new libraries to satisfy the request. It rarely goes back to remove the ones the previous version needed.
Those additions land on top of a stack that was already mostly inherited. Base OS layers, OS packages, language runtimes, and their transitive dependencies typically make up 90% or more of what a container ships. When nobody tracks why each package is there, unused components stay in the image indefinitely and get copied into every service built from it.
For a VP of Engineering, this shows up as images nobody can fully explain and vulnerability findings that return every quarter. For a CISO, it means the software you're accountable for includes components no one chose, reviewed, or needs.
Why AI-driven vulnerability discovery raises the cost of unused code
AI models are also getting better at finding vulnerabilities in the code you ship. Anthropic's Claude Mythos Preview, for example, is being used by a limited set of organizations through Project Glasswing. In RapidFort customer environments, a set of eight freshly patched containers now accumulates a couple hundred new findings within a week.
Every package in an image is code that a person or a model can search for flaws. A package the application never loads still counts, because an attacker who gains a foothold in the container can call it. Removing it takes that code out of the search entirely: there is nothing left to scan, patch, or exploit.
Smaller images also make multi-step attacks harder. Attackers often chain several vulnerabilities to move from initial access to control of an application. Each component you remove is a link that chain can no longer use. Removal also ends recurring work, because a CVE in a package you've deleted can't reappear in next quarter's report.
What attackers use when you leave it in the image
NIST's container security guidance treats patching and removing unnecessary components as two separate controls. Many teams stop after the first one. The components most often left behind in production images include:
- Shells and common utilities such as curl and wget
- Package managers such as apt, apk, pip, and npm
- Compilers and build tools left over from the build stage
- Libraries the application never loads
- Default accounts, sample files, and example configurations
Each of these gives an attacker something to work with after they get in. A package manager lets them install their own malware. A shell and a networking utility let them open a tunnel and move data out. Without those tools, an attacker who reaches the container has few ways to move laterally, and bringing their own tooling into a locked-down image is much harder.
The same reasoning applies to the tools you pull into your pipeline. Developer and security tools downloaded from public registries have themselves been compromised to steal credentials. Verifying what enters your registry and removing what you don't use address the same problem from two directions.
How to find and remove unused components on every build
You can't remove components safely until you know which ones run. A software bill of materials (SBOM) lists everything in an image. A runtime bill of materials (RBOM®) records what actually loads and executes. The gap between the two is what you can remove.
That gap is usually large. In one NGINX image, profiling found that 47 of 152 packages were in use. The other 105, about 69%, never loaded, because most deployments use only a few of NGINX's proxy and load-balancing functions.
The RapidFort workflow runs in three stages:
-
Profile in QA. Install the RapidFort Helm chart, which
deploys a DaemonSet to your Kubernetes QA cluster and generates an SBOM
and RBOM® for each image. Run at least one full QA test cycle.
helm install rfruntime oci://quay.io/rapidfort/runtime \ --namespace rapidfort \ --set profile.enabled=true \ --wait
- Review what's unused. The RapidFort dashboard shows each image's used and unused packages, down to the file level. Save your selections as an optimization profile.
- Apply the profile at build time. The RapidFort Optimizer strips the unused components on every build, so packages an AI assistant adds and later abandons don't reach production.
The profile keeps learning after the first run. It combines behavior across every node in the cluster where the application runs, and when a new code path appears, the next build keeps the package that path needs. That matters when AI-generated changes ship often: the profile follows what the code does now, instead of what someone documented months ago.
Size reductions of 60% to 80% are typical for Python, Node, and Java images. Go and Rust images, and images already built on distroless or scratch bases, see about 30%. Smaller images also cost less to store and pull.
Where profiling needs your attention
Profiling depends on test coverage. A code path your QA suite never exercises, such as a quarterly batch job or a rarely triggered error handler, can land on the removal list unless the profiler detects it another way. RapidFort supplements observed execution with memory-allocation and dependency analysis to catch infrequent paths, custom hardening profile files, and a thorough QA cycle remains your best protection. Review the removal list for rarely run functions before your first optimized release.
Removal also has limits. In the Bluetooth example, the optimized image still had three vulnerabilities with no fix available yet. Pair optimization with RapidFort Curated Images for the base layers and exploitability-based prioritization for what remains, as covered in How to cut container CVE remediation from months to 48 hours.
Three questions to bring to your next security review
You can gauge how much unused code your images carry with information your teams already have:
- For your five most-deployed images, can the owning team list every package and explain why it's there?
- How many CVEs in last quarter's reports had already been closed once before?
- Which production images still include a shell, a package manager, or build tools?
If the answers are "no," "many," and "most," unused components are a large part of your container attack surface, and removing them will cut both risk and recurring patch work.
Learn how the RapidFort Optimizer removes unused components from your container images
Latest posts
Eliminate Attack Vectors at the Source
Continuously eliminate up to 99.9% of CVEs without code changes
Products
Use Case
Quicklinks
Stay in touch
Subscribe for product updates and RapidFort newsletter.
Address
440 North Wolfe Road, Sunnyvale, CA 94085
© 2026 RapidFort, Inc.
RapidFort, RAPIDFORT, and RBOM® are registered trademarks of RapidFort, Inc. All other marks and names mentioned herein may be trademarks of their respective companies.





