TL;DR: A clean image scan tells you nothing about init container behavior because most scanners only index the primary image. The defense that works is layered. Admission controllers reject unsigned init containers. Image signatures get verified at the cluster boundary. Pipeline-level policy enforcement catches malicious pod specs before they reach a registry.
Key Takeaways: - Init containers run before the main workload and sit outside what most image scanners actually inspect - CVE-based scanning cannot detect novel miner binaries, and signing alone is not enough without admission-time verification - A green image scan is one of at least three gates, not the only one, in a defense that actually holds
The Green Scan That Hid a 3 AM Incident

Your scanner flagged zero critical CVEs. Your admission controller approved the pod. By morning, your node was running with CPU load nobody could explain. No one deployed a miner. An init container did.
This is the failure mode that keeps security architects up at night. A team that did everything right by the playbook still got compromised. Not because they skipped a step. The playbook was written for a threat the scanners can see.
Init containers run before the main container starts. They often slip past scanning workflows that only look at the primary image.
Consider the gap. Traditional image scanning is vulnerability-based. It looks for known CVEs in known packages. Cryptojacking is behavioral. A novel miner binary has no published vulnerability to flag. The scanner isn't broken. It is doing exactly what it was designed to do. That is the problem.
Defense in depth only works when each layer covers a different attack surface. Image scanning covers CVE-based supply chain risk. It does not cover runtime behavior, pod spec integrity, or init container provenance. For the container security fundamentals, start with that gap.
So what did miss it? And why does the attack happen in plain sight of the very tools meant to stop it?
Why Image Scanners Miss What Init Containers Do
The mismatch between what scanners do and what init containers do is structural. It is not a configuration mistake.
Most scanners index the primary container image. They parse the Dockerfile, walk the layer history, and match package versions against CVE databases. The init container image is a separate field in the pod manifest. The scanner never reads the manifest. It only sees the image you point it at. Most pipelines point it at the application image, not the init image.
A few mechanics make the gap worse: - Multi-stage builds drop intermediate layers. Scanners that skip non-final layers for performance reasons miss payloads hidden in earlier stages. - CVE databases are reactive. A brand new miner variant compiled from public source has no entry to match against. - Signing without admission enforcement is theater. A cosign signature on a tampered image means nothing if the cluster never checks it. - Base layer poisoning slips through when scanners whitelist a registry that has been compromised upstream. We have seen this fail in production, and the pattern is covered in your image scanner whitelists the backdoor in your base layer.
The third point is the one most teams get wrong. Image scanning best practices that stop at "scan and report" leave a door open for any supply chain compromise. The compromise produces a signed, clean primary image with a poisoned init spec.
For a deeper look at the supply chain half, see our SBOM and supply chain risks post. It covers the same gap from a different angle.
The scanner is not lying. The attack is happening in a layer the scanner never looked at. What does the actual chain look like?
Anatomy of an Init Container Cryptojacker
The attack has four stages. Each one is invisible to a scanner that only inspects the primary image.
Stage 1: Entry. An attacker compromises a dependency, a CI runner, or a Helm chart source. They inject an `initContainers` block into a pod spec during a pull request window. The change looks like a routine config update, and reviewers miss it.
Stage 2: Download. The init container runs as root, then pulls a statically linked ELF binary from an external endpoint. Common payloads include Mirai variants and XMRig forks. Static linking means the binary has no dynamic loader dependencies. This helps it run in stripped-down distroless contexts.
Stage 3: Execute and throttle. The miner starts in a side namespace. It throttles its CPU to stay below anomaly detection thresholds, then exfiltrates hashrate to a pool address. Throttling is the trick that defeats naive CPU alarms. A throttled miner that stays just below detection thresholds looks like a busy app, not a hijacked node.
Stage 4: Persist. Once the main application container starts, the init container terminates. The miner process is orphaned to PID 1 in a shared volume. Or it is registered as a cron job inside an `emptyDir` mount shared with the main container.
The "clean" main container is now hosting a hidden process tree. Restarting the pod re-runs the init container, re-downloads the binary, and re-orphans the process. The miner lives longer than the workload that supposedly "passed the scan."
The full mechanism for blocking this at the cluster boundary lives in Kubernetes admission control explained. Detection after the fact is forensics. Prevention means intercepting the workload before it schedules.
The Admission Controller as Security Gatekeeper

The admission controller is the only chokepoint every pod must pass through. That makes it the right place to enforce init container policy.
Three enforcement patterns matter. They compose cleanly.
1. Registry allowlists for init containers. Reject any pod spec that names an init container image from outside an approved set. Most teams do this for the main image and forget init containers are a separate field in the manifest. The policy has to walk every init container, not just the first.
2. Signature verification at admission. Cosign verification wired into a validating webhook means an unsigned or tampered image is rejected before the scheduler sees it. The same pattern catches a malicious image even if a developer pushed it through a compromised pipeline. Without admission-time verification, signing is documentation, not a control.
3. Runtime constraints on init containers. Deny any init container that runs as root, requests no resource limits, or opens egress to non-allowlisted CIDRs. The third rule kills the "download a binary from an external endpoint" stage. Init containers should never need wide open egress.
A Kyverno policy for the egress rule looks like this:
1apiVersion: kyverno.io/v12kind: ClusterPolicy3metadata:4 name: restrict-init-egress5spec:6 validationFailureAction: Enforce7 rules: - name: deny-init-egress8 match:9 any: - resources:10 kinds: - Pod11 validate:12 message: "Init containers may not initiate egress to external endpoints."13 pattern:14 spec:15 initContainers: - name: "*"16 =(securityContext):17 =(runAsNonRoot): true18 resources:19 limits:20 cpu: "500m"21 memory: "256Mi"
OPA Gatekeeper gives you the same guarantees with Rego. A custom controller works if you need logic the off-the-shelf tools don't express. For a fuller pattern catalog, our admission controller policy examples post walks through the realistic set. The signing half is covered in the cosign image signing guide.
Admission policies stop the bad pods. The attacker got in through your pipeline in the first place. Where does that pipeline get hardened?
Pipeline-Level Controls That Catch What Scanners Cannot
The pipeline is where the malicious pod spec enters the system. Catching it there shifts the work left, away from runtime firefighting.
Four controls compose a defensible pipeline: - Static analysis of manifests. Lint Helm charts and Kustomize output in CI. Fail builds that introduce new `initContainers` blocks without an explicit security review annotation. The annotation is cheap. The audit trail is what you need later, when someone asks how an init container with a six-month-old binary ended up in production. - SBOM diff at build time. Generate an SBOM in SPDX or CycloneDX format and diff it against a known-good baseline for the service. A new system binary with no upstream package is exactly what a static miner looks like. The diff is what catches it. - Runtime detection as a compensating control. eBPF-based tools like Falco and Tetragon can flag unexpected outbound connections from init container lifecycles. Init containers should download, configure, and exit. They should not be making persistent egress to mining pools. The detection is your safety net when the other layers have a gap. - Break-glass review. Any addition of an init container to a service that previously had none requires a security architect sign-off, logged in the deployment record. This sounds heavy. It catches more real attacks than any single tool, because it puts a human in front of the exact change that matters.
Our DevSecOps pipeline design post covers the wiring end to end. The runtime detection with Falco write-up shows what the eBPF side looks like in production, including the rule packs that matter.
There is a related failure mode worth naming: the secure pipeline that signs the malware it should block. Signing at the build step is necessary, not sufficient. The admission controller must verify. The two halves together close the loop.
A pipeline that signs everything is a pipeline that signs the attacker too, if the signing step happens after the compromise. Stack these layers and the original failure mode becomes structurally impossible. What does the day-to-day look like?
What Changes When the Defense Actually Holds
When the defense holds, three things shift.
First, the green image scan becomes meaningful again. It is one of three gates, not the only gate. The scanner's job narrows to CVE detection on the primary image.
Init container provenance, signature verification, and policy compliance are handled elsewhere. Each tool does what it is good at. The failure of one does not equal the failure of all.
Second, security architects stop being incident responders and start being policy authors. The work moves from "who do I blame for this 3 AM page" to "which policy needs a new rule."
Coverage becomes measurable in lines of admission policy and pipeline checks, not in alerts triaged. The on-call rotation gets quieter, and the policy repo gets busier.
Third, the organization gets provable DevSecOps maturity. Not "we scan images," but "we enforce signed, policy-compliant, SBOM-verified workloads at the cluster boundary." The phrasing matters. Auditors and engineering leaders both read it differently when it includes "verified" and "enforced."
For the model that maps to your current state, our measuring DevSecOps maturity post gives a workable framework.
If you are staring at a cluster where the scan is green and the node is still hot, the fix is not a better scanner. It is an admission controller that reads the pod spec. It is a signing policy the cluster enforces. It is a pipeline that rejects unsigned init containers before they reach the registry.
Layer those three, and the failure mode that opens this article stops being a question of when.
Frequently Asked Questions
Q: How do crypto miners end up in Kubernetes init containers?
A: Attackers typically compromise a dependency, CI pipeline, or Helm chart source to inject an init container spec. Init containers run to completion before the main workload starts, so the malicious code executes even if the primary container image is clean and signed.
Q: Can image scanning detect cryptojacking malware in containers?
A: Traditional CVE-based scanners cannot flag novel miner binaries that have no published vulnerability. They also typically only index the primary image, not the init container image specified in the pod manifest. Behavioral runtime detection and admission-time policy checks fill the gap.
Q: What admission controller policies prevent init container cryptojacking?
A: Effective policies reject unsigned images, block init containers from unapproved registries, forbid running as root, and deny outbound network egress from init containers. Kyverno and OPA Gatekeeper are common enforcement frameworks, often backed by cosign signature verification.
Q: Does container image signing stop supply chain attacks?
A: Signing alone is not enough. It must be verified at admission. When cosign or a similar tool checks signatures as a cluster admission requirement, a tampered or unsigned image is rejected before it schedules. That closes the supply chain gap scanners leave open.
Compare your current pipeline against the three gates above and pick one to harden this week.
Sources
Research and references cited in this article:
- Сontainer Security Vulnerabilities: Deep Overview 2026 | Iterasec
- DevSecOps for Container Security: Best Practices
- 17 New Container Security Vulnerabilities - 2026
- DevSecOps Container Security: 10 Docker & Kubernetes Risks
- What is Container Image Security? Tips & Best Practices
- Shielding your Kubernetes runtime with image scanning on ...
- Admission Controller
- Preventing Vulnerable Container Deployments with Admission Control
- Using Admission Control to Prevent Unauthorized or Vulnerable Image De..
- Image Scanning admission controllers : r/kubernetes - Reddit
- Container Security in Action: Tools & Techniques that Work for 2026 - Fyld
- Container Security And How To Secure Containers In 2026
About the author
Mayank Singh is a software developer at Levitation Infotech, where he builds web and AI-powered applications across the company’s fintech, healthcare, and enterprise projects.
