
Dependency attacks start before your scanner runs

When you run npm install, you're not just installing the requested package. You're also pulling in every transitive dependency in the package’s dependency graph. Many of these are packages you didn’t consciously choose, from maintainers you don’t know, including code that executes automatically before any build pipeline step runs. An average React application can pull in over 900 dependencies, most of which arrive automatically, not by selective choice.
That's the architecture of modern software development. Reusing open source packages at scale makes it possible to ship complex applications that meet the high expectation of users without rebuilding foundational infrastructure from scratch. But the security model currently in use wasn’t designed to address the exposures created by reusing open source packages.
A leaked npm publish key makes that exposure visible. The credential isn't the problem, rather it's what reveals the gap between where organizations believe enforcement happens and where it actually happens.
The evolving nature of software development and the rise of security supply chain attacks changed who's paying attention to this gap. Security teams don't need to experience an incident to start conversations around their supply chain. The axios compromise, the Shai-Hulud-style worms, and near-misses reported by high-profile engineering organizations present a threat environment that makes industry signals a catalyst for change. So, while the trigger is different, the gap is the same.
Downstream effects of a leaked key
It may seem like a leaked npm key is a credential rotation problem and not a supply chain problem. Here’s how we get from key to attack.
No matter how a publish key gets exposed, whether that’s in a CI log, a repository that was briefly public, or a secret rotation that wasn't fully completed, that key grants write access to one or more packages on the public npm registry. Write access means the ability to publish a new version.
The attacker publishes a version that looks legitimate: same package name, incremented version number, valid metadata. In the axios compromise, the malicious versions were tagged latest and legacy. Consumers pulling the latest version get the malicious one automatically on their next install.
Here's where the transitive dependency becomes the attack surface. Most downstream consumers aren't pulling the compromised package directly. They're pulling a framework that depends on a tool that depends on the package. No developer makes a conscious choice to install it. The package manager resolves the dependency graph and pulls everything in. In the axios case, the attackers added a new software dependency named plain-crypto-js which serves as a legitimate encryption and hashing utility. The associated npm postinstall script runs automatically during installation. The malicious code executed before any build step, before any scanner ran, before anyone knew the package arrived.
By the time a developer or CI job completes npm install, attack code can exfiltrate credentials, establish remote access, and take steps to avoid detection.
The credential leak opened the door. The artifact pipeline, specifically, the absence of an interception point between a package being requested and when the package is executed. This is precisely where the adversary makes an impact.
What existing tooling misses
Investing in security tooling can create a sense of false confidence. Especially as organizations grow, adapting to nuanced changes in the software development process at scale can be challenging. So, this confidence makes sense: they have application security scanning, CI/CD pipeline scanning, and endpoint detection. These are good tools, but where they sit in the timeline is the problem.
AppSec and static analysis tools analyze the code your team wrote. SAST tools like Checkmarx, Veracode, Snyk, and Semgrep, do serious work and find real vulnerabilities. They analyze source code before the build runs. The SAST tool already finished its pass by the time your build system is pulling packages from npm. It has no visibility into the dependency tree. So, a compromised transitive dependency gets pulled in, its installation script executes, and the SAST report comes back clean because the SAST tool never saw the dependency tree.
CI/CD scanning runs after the package manager pulls the requested packages. In npm, postinstall scripts run during download, not during execution. When the malicious code runs at install time and your pipeline scanner runs afterward, then it's checking the pool for contaminants after the swimmers have been in it for an hour. The tool works correctly and you get a clean report, but that’s because the timing is wrong once again. The attacker already has your credentials.
Endpoint and runtime security is excellent at detecting anomalous behavior once code is running, like suspicious network traffic, unusual file operations, and credential access patterns. CrowdStrike, your EDR tooling, etc., catch these things, but they're reactive by design. By the time your endpoint detection notices the suspicious outbound connection, the credentials are already gone. Detection at minute three doesn't help much when the exfiltration happened at minute one.
This is the architecture of the standard security model, and it has a structural blind spot: every control point operates after ingestion. Code downloads and executes before any of those controls see it. That's not a problem you solve by adding another scanner at a later stage in the same pipeline. Adding more tooling downstream of the gap doesn't close the gap.
The control plane has shifted
Consider a fire department. They detect and respond to fires. We need fire departments. But we also need a fire code that prevents fires from starting. The fire code is embedded in the design and operation of buildings; it’s invisible because it's foundational. Fire response and prevention are different things, and both matter. The difference is that only one of them stops the problem before it starts.
The artifact registry functions like the fire code. It’s where that kind of foundational control can actually live for software supply chains. It sits at the boundary between untrusted software, like everything on the public internet, and your trusted environment. Every package your developers and build systems consume passes through it. That makes it the one place in the entire delivery pipeline where enforcement can happen before code downloads, installation scripts run, or anything executes.
Enforcement at the trust boundary changes the attack timeline entirely. A compromised version of a package previously marked as safe gets evaluated against policy before it enters the environment, so doesn’t reach your environment at all. Policy stops being advisory ("this package is risky, here's a dashboard entry") and instead becomes an automated enforcement control ("this package is not entering this environment for this reason").
A few things become possible at the artifact layer that aren't possible anywhere downstream:
Continuous re-evaluation. A package that was clean when it arrived six months ago and has a new CVE or a threat intelligence flag today gets re-evaluated without manual action. Build-time scanning doesn't revisit what's already in the environment, but an enforcement layer at ingestion can.
Richer signal than CVEs. Most modern supply chain attacks don't begin with a known vulnerability. They begin with compromised open source maintainers. These threats don't appear in a common vulnerabilities feed and instead rely on scanning the open source upstream registries (PyPI, npm, Packagist, etc.) for unwanted code changes (malicious packages) using a database like OSV.dev. . This data is actionable at the artifact layer, before the package is introduced into any developer builds.
An audit trail that answers the incident question. When something goes wrong, "were we exposed?" should be answerable from a single system of record. An enforcement layer at ingestion is that record – what entered, when, under what policy state, with what provenance. Not a multi-tool investigation across disconnected logs.
The problem with bolt-on security
The instinctive response to a supply chain incident is to add tooling. Buy the additional security module. Enable scanning at another pipeline stage. Each addition addresses a visible gap and each one is a reasonable decision in isolation.
The accumulated result is a different problem: a patchwork of controls with seams between them. Each tool has its own configuration requirements, its own maintenance cycle, its own expertise to operate correctly. The security stack grows in response to incidents until nobody fully understands how it fits together or what to do when something falls through a seam. The operational burden of the stack becomes its own risk.
This pattern shows up consistently in teams that started with a repository and added security on top: fragmented coverage, high maintenance overhead, and a circumvention problem. When authentication against an internal proxy creates enough friction, developers route around it and pull directly from the public registry. A control that gets bypassed at scale is worse than no control because it creates the appearance of coverage while the actual exposure grows.
The architectural distinction matters here. Controls built into the artifact layer from the foundation behave differently from controls added on top of a repository designed for something else. The former is simply infrastructure while the latter is configuration layered on infrastructure with a different original purpose. Those are two different approaches that behave differently under pressure.
Teams choosing a platform built for supply chain security describe making that choice explicitly to avoid assembling the capability from components. The assembly works, until it doesn't. The seams are where attacks succeed.
What the incident actually reveals
The leaked npm key is almost never the actual exposure. It's the event that made the exposure visible.
The supply chain incident – the credential, the flagged package, the build that broke in a way nobody could explain quickly – functions as a diagnostic. It reveals where enforcement actually lives in the pipeline, which is almost always different from where teams assumed it lived.
The useful question that comes out of the diagnostic: where in your pipeline does enforcement actually happen? Does it occur before packages enter the environment, or after?
For most organizations running standard CI/CD scanning on top of a repository, the answer is after. The follow-on question is what it would take to move it upstream. The teams that have made that move describe the same outcome: not more tooling on top of the existing architecture, but a different architectural starting point. A platform where enforcement at the boundary is the foundation, not an addition.
Cloudsmith is a cloud-native artifact management platform that enforces policy at the point of ingestion – before packages enter your environment – and provides continuous re-evaluation, full audit logging, and developer-transparent controls across every package format your teams use.See how Cloudsmith protects your software supply chain from dependency attacks. Schedule a conversation to discuss your tech stack today.
More articles


Inside the Mastra npm supply chain attack

How Cloudsmith cooldown policies block newly published packages without disrupting your builds

The EU Cyber Resilience Act: What engineering teams need to do to be compliant

The Miasma worm's path of destruction

