Safeguard
Cloud Security

Why static scanning misses runtime threats (the case for ...

Trivy's build-time CVE scans miss fileless malware, reverse shells, and live threats. Here's how ATT&CK-mapped runtime protection closes the gap.

Karan Patel
Cloud Security Engineer
8 min read

A container image scans clean. Trivy reports zero critical CVEs, the pipeline goes green, and the image ships to production. Three weeks later, a dependency's post-install script — never flagged because it wasn't a known vulnerability, just malicious behavior — opens a reverse shell to an external host. The scan was accurate. It was also irrelevant to what actually happened, because nothing was watching the container once it started running. This is the gap between static scanning and runtime protection, and it's not a hypothetical: known-CVE databases only cover vulnerabilities someone has already disclosed, while live workloads face fileless payloads, compromised packages, and post-exploitation behavior that no point-in-time scan will ever see. Trivy, built by Aqua Security, is one of the most widely deployed static scanners in the industry. This post looks at what it covers, what it structurally cannot cover, and where Safeguard's runtime layer picks up the difference.

What Does Trivy Actually Scan?

Trivy is invocation-based. You run trivy image, trivy fs, trivy repo, trivy k8s, or trivy config against a target, and it produces a report from a snapshot of that target at the moment of the scan. It checks OS packages and language dependencies against vulnerability databases, flags known-bad configurations in IaC, detects hardcoded secrets, and can generate a CycloneDX or SPDX SBOM. All of this is genuinely useful, and all of it happens before or independent of the workload executing.

That's the defining property to understand: Trivy's scan types are all "scan this artifact and report," not "watch this process and alert." There is no mode of Trivy that observes a running container's syscalls, network connections, or process tree. That's not a criticism of the tool's execution — it's a description of its design category. Aqua Security also sells a commercial CNAPP platform with runtime capabilities, but that is a separate product from the Trivy scanner itself, and most teams that reach for Trivy do so precisely because it's free, fast, and CI-native — which also means most Trivy deployments have no live workload visibility at all unless they've separately bought and deployed something else.

Why Doesn't a Clean Scan Guarantee a Safe Runtime?

A static scanner can only flag what's already in a vulnerability database and present in the artifact it's given. Three categories of risk fall outside that boundary by construction:

  • Unknown vulnerabilities. A zero-day with no CVE entry yet doesn't exist in any feed Trivy queries, so it can't be flagged, no matter how thorough the scan.
  • Behavioral compromise. A dependency with a malicious install script, a typosquatted package, or a supply-chain-injected backdoor doesn't necessarily trip a CVE check — the code isn't "vulnerable," it's intentionally hostile, and that's a runtime behavior problem, not a version-matching problem.
  • Fileless and in-memory execution. Payloads that never touch disk — reflectively loaded shellcode, memory-resident miners, living-off-the-land binary chains — leave no artifact for a filesystem or image scan to find, because there's no file to scan.

None of this is a knock on Trivy's accuracy. It does what static scanning does: compare declared package versions and configurations against known-bad lists. The problem is treating a clean static scan as evidence that a workload is safe once it's running, when the two questions — "does this artifact contain known vulnerabilities?" and "is this workload currently doing something malicious?" — are answered by different classes of tooling entirely.

What Does Safeguard Add at Runtime?

Safeguard runs a rule engine against live workload behavior — shells spawned inside containers, unexpected outbound connections, sensitive file access, privilege escalation, and container-escape techniques — and maps each detection to a specific MITRE ATT&CK technique, so an alert arrives with adversary context instead of a bare log line. The managed rule packs cover reverse shells (T1059), crypto-miners (T1496), container escapes (T1611), fileless/in-memory execution (T1620), privilege escalation (T1548), and LOLBin download-and-execute chains (T1105) — exactly the categories a build-time scan structurally cannot see.

Runtime visibility also feeds back into SCA prioritization. Safeguard's engine records which packages actually load and which functions actually execute per workload, and passes that into AutoTriage: a statically-reachable CVE that gets runtime-confirmed is bumped up in priority, and a package that's declared but never loaded gets bumped down. Reachability re-ranks findings — it never suppresses a malware detection, so a live threat is never quietly filtered out by a noise-reduction heuristic.

DimensionTrivy (static)Safeguard (runtime layer)
Scan triggerManual/CI invocation against a snapshotContinuous, live workload monitoring
Detects known CVEs in declared packagesYesYes (via SCA + reachability)
Detects fileless/in-memory executionNo — no artifact to scanYes, dedicated rule pack (T1620)
Detects reverse shells / C2 behaviorNoYes, dedicated rule pack (T1059)
Maps findings to MITRE ATT&CKNoYes, per rule pack
Can take automated action on a live threatNo — reporting onlyYes, policy-gated (alert/block/kill/quarantine/isolate)
Re-ranks CVEs by runtime confirmationNoYes, via AutoTriage

Can a Scanner Ever Respond to a Live Threat?

No, and this is a structural limit, not a maturity gap. A tool that runs, produces a report, and exits has nothing left running to take action once that report is filed. Response requires an agent that's still resident in the workload's execution path at the moment the bad behavior occurs.

Safeguard's response tier is built around that requirement, and it's deliberately conservative by default: alert-only is the standing default until a tenant opts in to more, and destructive actions — kill, quarantine, full network isolation — require policy plus human approval unless a specific high-confidence rule is explicitly opted into auto-response. Actions are safe-fail, meaning a failed response is recorded rather than crashing the workload, and a kill action targets only the precisely identified offending process. This matters because runtime response is easy to get catastrophically wrong (auto-killing the wrong process in a shared pod is its own outage), and treating "can respond" and "responds safely by default" as separate design questions is the difference between a runtime tool teams actually turn on and one they leave in log-only mode forever.

Where Does Each Tool Fit in the Pipeline?

Trivy's natural home is pre-deployment: CI/CD gates, pre-commit hooks, registry admission checks, and periodic image audits. It's fast, free, well-documented, and answers "does this artifact contain known bad things" cheaply and repeatedly. There's no reason to stop running it.

Safeguard's runtime layer is the complement, not a replacement: it picks up exactly where the artifact stops being a static object and starts being a running process. The two questions Trivy and a runtime engine answer are different, and a pipeline that only asks the first one is blind to everything that happens after deployment — which, for a workload with a multi-month or multi-year lifespan, is most of its actual exposure window. Safeguard also correlates runtime findings against exposure: a workload is prioritized far higher when it's simultaneously running, network-reachable, exposed to an untrusted boundary, and over-privileged, than when only one of those is true. That correlation is only possible with live signal — a static scan of an image has no way to know whether the resulting container will be internet-facing, internal-only, or running with a service account that holds cluster-admin.

How Safeguard Helps

If your pipeline already runs Trivy — or any static scanner — at build time, Safeguard's runtime layer is designed to sit downstream of it rather than compete with it. The rule engine watches for the specific behaviors a static scan can never see: reverse shells, crypto-miners, container escapes, fileless execution, privilege escalation, and LOLBin chains, each mapped to a MITRE ATT&CK technique so responders get context instead of a raw alert. Runtime signal feeds back into SCA triage through AutoTriage, so a CVE that's confirmed to be actually loading in production gets prioritized over one that's declared but dormant — without ever suppressing a genuine malware finding. And when a response is warranted, Safeguard's gated action tier (alert, block, kill, quarantine, isolate) lets you start at alert-only and dial up automation as confidence grows, with safe-fail behavior and precise process targeting built in from the start. Static scanning tells you what shipped. Runtime protection tells you what's actually happening — and for any workload that runs longer than the time it takes to read this sentence, you need both.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.