In March 2023, attackers slipped a backdoored version of the 3CX desktop app past static analysis, code signing, and every antivirus vendor watching the download page. The malicious code sat dormant in a legitimately signed binary for weeks. It was only caught because endpoint detection tools noticed the app doing something a softphone client has no business doing: reaching out to attacker-controlled infrastructure and spawning a second-stage payload at runtime. Static code scanning had already passed it. This is the pattern behind nearly every major software supply chain incident of the last five years — the code looked clean on disk and turned hostile only once it executed. Security teams have spent a decade hardening the "left" side of the pipeline: SAST, SCA, secret scanning, pull request gates. Attackers responded by moving their tradecraft to the one place those tools don't look — production, at runtime. That gap between what you scan and what actually runs is where breaches now live.
What exactly is the cloud-to-code visibility gap?
The cloud-to-code visibility gap is the blind spot between a commit that passes static checks and the live behavior of the workload that commit eventually becomes in production. Static tools — SAST, SCA, container image scanners — evaluate code and dependencies as artifacts: text, manifests, and package trees inspected before anything runs. Runtime is where that artifact acquires a network identity, calls out to APIs, spawns child processes, reads secrets from environment variables, and touches cloud IAM roles. A 2024 Gartner survey found that over 45% of organizations experienced a software supply chain attack in the prior three years, yet most of those same organizations still route fewer than 20% of their detection budget toward runtime telemetry. The gap isn't a tooling gap so much as an attention gap: teams built excellent pre-deploy gates and left the post-deploy phase to generic cloud monitoring that was never designed to reason about code provenance. When the xz-utils backdoor (CVE-2024-3094) was discovered in April 2024, it wasn't a scanner that found it — it was a Postgres developer, Andres Freund, noticing SSH logins were consuming 500ms more CPU than expected. That is a runtime signal, not a static one.
Why doesn't static code scanning catch these attacks before they ship?
Static scanning doesn't catch these attacks because it evaluates intent, not behavior, and sophisticated payloads are built specifically to look inert until execution. SAST and SCA tools work by pattern-matching known-bad code, known-vulnerable dependency versions, or CVE identifiers against a manifest. That works well for the 90% case: an outdated lodash, a hardcoded AWS key, a SQL string built with concatenation. It fails against anything that obfuscates its payload, delays execution, or only activates under specific runtime conditions. The xz-utils backdoor was hidden inside binary test fixtures and a build-time script that modified the compiled liblzma object — it was never present as readable malicious source, so every SAST tool that scanned the repository saw nothing wrong. Similarly, the Codecov Bash Uploader compromise (discovered April 1, 2021, but running undetected since January 31, 2021 — roughly two months) worked by modifying a script hosted on Codecov's own infrastructure to exfiltrate CI secrets; the script pulled at pipeline time looked benign in any point-in-time repo scan because the malicious version wasn't the one committed to source control. Static tools evaluate what's checked in. Attackers increasingly attack what's fetched and executed.
What can runtime detection see that static scanning structurally cannot?
Runtime detection can see the actual process tree, network connections, syscalls, and credential usage of a running workload — the exact signals that reveal an attack in progress rather than a theoretical risk. Where SCA tells you a container image includes openssl 3.0.2 and is therefore vulnerable to CVE-2022-3786, runtime tooling tells you whether that library was ever loaded and called by the running process, cutting real exposure lists by 70-85% in most environments (Safeguard's own scan data across customer fleets shows the median container ships with several hundred packages but exercises fewer than a third of them at runtime). More importantly, runtime detection catches classes of attack static analysis cannot model at all: a Log4Shell-style JNDI lookup being triggered via a crafted HTTP header (CVE-2021-44228, disclosed December 9, 2021), a compromised npm postinstall script phoning home during npm install in CI, or a container process unexpectedly forking a shell and reading /proc/1/environ to steal secrets. These are behaviors, not signatures. You cannot grep for them in a Dockerfile.
How much damage happens in the time between deploy and detection?
The damage compounds directly with dwell time, and industry data puts that window at months, not minutes. IBM's 2023 Cost of a Data Breach report measured the average time to identify and contain a breach at 204 days for identification alone, with supply chain-originated breaches running above that average due to the extra hop of trust involved. The SolarWinds Orion compromise, injected into builds starting in September 2019, wasn't publicly disclosed until December 2020 — over a year of dwell time across roughly 18,000 downstream customers. Sonatype's 2023 State of the Software Supply Chain report logged over 245,000 malicious packages published to open source registries that year alone, a number that has grown roughly 200% year over year since 2019, and the overwhelming majority were discovered post-publication by runtime or install-time behavior (unexpected outbound connections, unexpected file writes) rather than by static review of the package source. Every day of undetected dwell time is a day an attacker has to pivot laterally, harvest credentials, and establish a second foothold — which is exactly why MTTR on runtime incidents, not just count of vulnerabilities patched, is becoming the metric boards actually ask about.
What does actually closing the gap look like operationally?
Closing the gap means correlating a runtime event back to the exact commit, dependency, and build that produced it, in seconds rather than during a post-incident forensics exercise. In practice this requires three things working together: an SBOM or build provenance record generated at CI time so every artifact has a known origin; lightweight runtime sensors (eBPF-based agents are now the standard, replacing older sidecar or kernel-module approaches) that observe process, network, and file activity without meaningfully impacting workload performance; and a correlation layer that maps a live anomaly — say, a payment-service pod suddenly resolving a domain registered four days ago — back to the specific package version and pull request that introduced the code path. Teams that implement this loop report materially shorter triage times because the question shifts from "what could theoretically be wrong across 4,000 dependencies" to "this one process just did something it has never done before, and here is the exact line of code that shipped it." That reframing — from exhaustive static risk to actionable runtime signal — is the entire point of closing the gap.
How Safeguard Helps
Safeguard is built around the premise that static findings and runtime behavior have to live in the same graph, not two separate dashboards owned by two separate teams. On the static side, Safeguard generates SBOMs and provenance attestations at build time and continuously scans dependencies and container images against CVE and malicious-package feeds. On the runtime side, Safeguard deploys lightweight eBPF sensors into Kubernetes and cloud VM fleets that watch process execution, network egress, and file/credential access without the overhead of legacy agents. The differentiator is the correlation layer in between: when a runtime sensor flags an anomalous outbound connection or an unexpected child process, Safeguard automatically traces it back through the SBOM to the exact package, version, and commit that introduced it — turning a generic "suspicious network activity" alert into "package left-pad-utils@3.2.1, pulled in by PR #4821, just contacted an IP registered six hours ago." That traceability is what shrinks a 204-day industry-average detection window down to minutes, and it's what lets security teams prioritize the handful of packages actually exercised in production instead of chasing every CVE in a 4,000-dependency tree. For teams that have already invested in SAST and SCA gates, Safeguard doesn't replace that layer — it closes the loop those tools were never designed to close, giving you one place to see the full path from cloud runtime signal back to code.