Software Supply Chain Risk in Third-Party Dependency Policies
Static policies cannot keep pace with dependencies that change daily.

Free and open-source code now makes up somewhere between 70 and 90 percent of a typical modern application, according to World Economic Forum estimates, which means most organizations aren't really building software anymore. They're assembling it from parts they didn't write and often haven't inspected. Veracode's State of Software Security 2025 report found that 70 percent of critical security debt comes from third-party code and the broader supply chain, meaning most of a company's actual vulnerability exposure sits in code its own engineers never touched. This piece argues that dependency policies keep failing not because security teams are unaware of the risk, but because those policies describe a snapshot of software that no longer exists by the time anyone reads it.
The scale of the problem shows up in the numbers wherever people bother to measure it. In the OWASP Top 10:2025 community survey, exactly half of respondents ranked Software Supply Chain Failures as the number one risk category, and when tested against real contributed data, the category posted the highest average incidence rate of any listed risk, at 5.19 percent. Large financial institutions now carry an average of more than 4,000 security-relevant third-party components, per TrustSphere's analysis of banking sector dependencies, a figure that makes clear this stopped being a "watch your dependencies" problem years ago. Every package manager pull, every automated build step, every transitive dependency buried three or four layers down is a door somebody left unlocked, not because anyone forgot to check it, but because nobody built the house to keep track of how many doors it has.
How real attacks exploit the gap between policy intent and dependency reality
SolarWinds remains the reference case for a reason. The breach touched more than 30,000 organizations, including multiple U.S. government agencies, and it didn't work by slipping a bad package into a registry. It worked by compromising the build environment itself, inserting malicious code during compilation so that every artifact coming out the other end looked clean while carrying a hidden payload. The World Economic Forum estimated that affected companies lost an average of 11 percent of annual revenue in the aftermath. That is not a rounding error in a security budget. That is a business event.
The npm ecosystem has produced its own string of cautionary tales. In March 2026, according to a Cloud Security Alliance advisory, attackers compromised the npm account of a primary maintainer on the Axios project and pushed unauthorized malicious versions straight to the registry, turning a single stolen credential into a global distribution event. Six months earlier, in September 2025, a malicious self-propagating install script infected more than 180 npm packages, according to a CSA Singapore advisory. That's the transitive dependency graph working exactly as designed, just for the wrong purpose: once one package is compromised, everything that depends on it inherits the compromise automatically.
Then there's the November 2025 typosquat case that was publicly reported, where a package called @acitons/artifact impersonated the legitimate @actions/artifact package, ran a postinstall script that exfiltrated CI/CD secrets, and used a built-in expiration date to dodge detection windows. GitHub later confirmed this was an internal Red Team exercise rather than a genuine external attack. That confirmation doesn't diminish the finding, it sharpens it: the exercise proved that human error, automated build trust, and registry permissiveness can all be exploited at once, by design, which means a real attacker could do the same thing without needing to invent anything new.
Worth noting, too, is July 2024's CrowdStrike-adjacent outage, where a flawed update to an endpoint security tool triggered malfunctions across roughly 8.5 million Microsoft Windows devices, grounding flights, disrupting banks, and knocking out pieces of healthcare and payment infrastructure. Nothing malicious happened there. But the failure mode, an unreviewed change propagating instantly and universally through a trusted update channel, is structurally identical to a supply chain attack. The distinction between "hostile" and "broken" stopped mattering to the people stuck in airports.
What ties these incidents together isn't a lack of policy. Every one of these organizations had a dependency policy on paper. What none of the policies accounted for was the fact that package versions change, maintainer credentials get phished, transitive graphs mutate silently, and build pipelines have their own attack surface separate from the code itself. Typosquatting, dependency confusion, dependency hijacking, and social engineering aimed at maintainers are four distinct attack classes, each demanding a different control, and most policy documents were never written to cover more than one of them at a time.
Why current dependency policies are written against a static model of software
Most dependency policies read like a snapshot: approved registries, acceptable license categories, a vulnerability severity threshold, all fixed at the moment someone wrote the document. They treat the dependency graph as something you check once, not something that keeps moving under your feet.
Lockfiles complicate this more than people realize. A package-lock.json or yarn.lock file pins a version number, but pinning a version is not the same as verifying that the content behind that version number hasn't changed since the day it was first pulled. Version pinning and content integrity are two separate controls, and conflating them is one of the most common mistakes in dependency management today.
The bigger blind spot sits one or two layers further down. A policy that only reviews direct dependencies never looks at the dependencies-of-dependencies, and Veracode's research points to third-party code as the origin of 66 percent of the most critical, long-lived vulnerabilities in enterprise applications. Shadow IT makes this worse: per the CSA advisory, teams routinely adopt external services, APIs, or packages without any formal security review, and those components enter the dependency graph completely outside whatever policy process the organization thinks it's enforcing. Meanwhile, change management for source code, the review gates, the approvals, the sign-offs, rarely extends to dependency version bumps. A package update can roll straight into production with none of the scrutiny a code commit would get.
So the policy is accurate exactly once: the day it's written. Every day after that, it drifts a little further from what's actually running, as upstream packages get updated, maintainers rotate, and new transitive dependencies show up unannounced. The World Economic Forum's Global Cybersecurity Outlook 2025 found that supply chain interdependencies rank as a top concern for both CISOs and CEOs, with 78 percent of CISOs and 87 percent of CEOs citing improved security posture as a primary reason for adopting new regulations. That's real pressure from the top of the org chart. It has not, so far, been enough to force policy documents to behave like living systems instead of static ones.
What regulatory frameworks now require and where they still leave gaps
Regulators have started to respond, and the response is substantial even where it's incomplete. The EU's Cyber Resilience Act mandates SBOMs, ongoing vulnerability handling, due diligence on third-party components, and third-party conformity assessments for higher-risk product categories. Non-compliance can carry penalties up to €15 million or 2.5 percent of global revenue, and the law is expected to be in full effect by 2027.
In the United States, Executive Order 14028 and the NIST and CISA guidance that followed it have institutionalized SBOM adoption across federal software procurement, and that influence has begun reaching beyond federal procurement into broader industry sectors. DORA, the EU's Digital Operational Resilience Act, became fully applicable across the bloc on January 17, 2025, and its first full year of supervisory enforcement is now underway. DORA gives European supervisors direct oversight of named critical ICT third-party providers, including cloud and platform vendors, which effectively pulls the supply chain into the regulated perimeter for the first time.
Here's the shared gap across all three frameworks: they mandate that an SBOM exist and that a supplier assessment happen at procurement time. None of them require that the SBOM stay accurate for the life of the software, and none require that a dependency change trigger a fresh assessment. That's not a small omission. It creates real compliance theater risk, where an organization produces a point-in-time SBOM, sails through the audit, and then keeps operating for months or years on an inventory that no longer reflects reality as dependencies drift underneath it. Technically compliant. Operationally exposed. Regulatory pressure gets the right people paying attention, which matters, but attention alone doesn't fix a policy model built around a single moment in time.
The SBOM as a living inventory, not a compliance artifact
An SBOM is a parts list. It names the libraries, packages, and dependencies bundled into a piece of software, and it's genuinely useful for tracking known vulnerabilities and staying on top of license obligations. What it does not do is say anything about the integrity of the process that produced those parts.
SolarWinds again makes the point concrete. Every component in the affected SolarWinds Orion build was legitimate. The attacker didn't swap in a bad package — the compromise operated at the build pipeline level, so the compiled output was trojanized while every listed component stayed clean. A parts-list inventory of that build's components would have revealed no obvious anomaly, because the compromise operated below the level of what components were present.
Adoption is climbing but starts from a low base. Recent academic analysis found that SBOMs are under version control or available in public releases for fewer than half of the software projects examined, which means most organizations generating SBOMs today aren't managing them as living documents, they're generating them once and moving on. The market is growing fast regardless: the global SBOM market was valued at $2.8 billion in 2025 and is projected to reach $13.2 billion by 2034, growing at an 18.2 percent compound annual rate. That growth mostly tracks compliance-driven tooling purchases, not operational maturity, and the two are not the same thing.
Managing an SBOM as a living inventory in practice means a handful of specific things have to happen. Generation needs to be automated and wired into the CI/CD pipeline at every build, not run once at release time. The SBOM output needs version control, so a change in the dependency graph shows up next to the code change that caused it. Vulnerability monitoring needs to run continuously against the current SBOM, not against a snapshot from six months ago. And coverage needs to reach transitive dependencies, not stop at the direct ones. Best practice holds that inventory should span development and production environments both, since production-only coverage misses exactly the build-time and development-time surface where most supply chain compromises actually happen. Standing in the way of all this: format fragmentation between SPDX and CycloneDX, integration friction with existing pipelines, and limited awareness among smaller vendors who haven't built out this tooling yet, all of which organizations have to navigate every time they exchange an SBOM with a supplier.
Build provenance and why knowing what is in your software is not enough
Build provenance answers a different question than an SBOM does. Where an SBOM lists what's inside an artifact, provenance is verifiable metadata proving how, when, and by whom that artifact was actually built, addressing process integrity rather than inventory.
SLSA, the Supply-chain Levels for Software Artifacts framework, originated at Google and now lives under the OpenSSF. It lays out a maturity model running from SLSA 1 through the three levels of the Build Track, and the current stable release, SLSA v1.2, shipped in November 2025 with a new Source Track added alongside the existing Build Track. At the higher levels, SLSA requires tamper-resistant build environments and cryptographically signed attestations, which means a downstream consumer can verify not just what went into an artifact but that the environment producing it wasn't altered along the way.
Getting there requires specific engineering choices, not a policy memo. Build environments need isolation, each CI job running in its own ephemeral container or virtual machine, with Kubernetes-based runners spinning up ephemeral pods so one build's artifacts stay invisible to the next. Output artifacts need digital signatures so tampering after the fact is detectable. Runners need least-privilege access, meaning CI/CD jobs and signing keys are scoped tightly to the build boundary they actually need rather than given broad standing access. And builds need to be reproducible: the same inputs should always produce the same binary output, so an unauthorized injection shows up the moment someone compares one build against another.
The gap that remains is upstream. First-party source can be spotless while the packages it depends on carry no SLSA provenance at all. Security practitioners generally recommend verifying provenance whenever upstream packages publish it, and treating the absence of it as a risk decision to be made explicitly, weighed against how central that component is to the system, rather than something to wave through by default. Even organizations that want to do this find it genuinely hard at scale: large volumes of in-toto and SLSA metadata, key rotation overhead, verification spread across multiple disconnected systems, and artifacts that live in production for years all add friction that most engineering teams haven't fully solved yet.
How environment reproducibility closes the drift gap that provenance attestations cannot reach
Every engineer knows the phrase "works on my machine." Configuration drift between development, testing, and production environments is the reason that phrase exists, and it's not just a debugging headache — it's a security exposure that stays invisible until something breaks in production that never broke anywhere else.
The scale of the problem is larger than most teams assume. One study of thousands of Docker builds found that only 6.4 percent of rebuilt images matched the exact set of package versions installed in the original build. Containers get treated as a reproducibility guarantee by default, and that assumption doesn't hold up against the evidence. For hosted environments, the most common cause of drift isn't some exotic infrastructure failure, it's manual changes: someone installs a package by hand, overrides a version, tweaks a config, and none of it ever makes it into version control.
Functional package managers like Nix and Guix take a different approach at the architectural level. Every build becomes a pure function of explicitly declared, transitively hashed inputs, with isolation enforced at the kernel level so nothing on the host machine can quietly contaminate the build. That architecture matters well beyond developer convenience. A CI runner that pulls packages at build time from a floating version reference can end up with a different dependency graph than the one a developer actually tested, which means the SBOM generated in that CI run doesn't match what got validated earlier in the process. AI coding agents introduce the identical risk: an agent running in a non-reproducible environment drifts the same way a human developer's laptop does, and its output is only as trustworthy as the environment it ran in. Kubernetes deployments and containerless patterns that assume parity between build-time and run-time environments quietly break down the moment the build environment itself can't be exactly reproduced.
None of the SBOM or provenance work covered above means much without this. If the environment producing a build isn't reproducible, the SBOM generated from it can't be reliably accurate, and a provenance attestation about that build can't be fully trusted either. Reproducibility isn't an extra layer on top of those controls. It's the floor they both stand on.
What a dependency policy looks like when it treats every dependency decision as a security decision
Governance has to start at the moment a dependency is selected, not the moment a scanner flags it. That means checking a maintainer's history, release cadence, and community trust signals, and confirming provenance is available, before the package ever enters the codebase, per CSA advisory guidance.
Dependency updates deserve the same change management gate as code changes, not a lighter, faster side door that skips review because "it's just a version bump." Lockfiles pin versions, but pinning alone isn't enough: cryptographic hash verification is what confirms the content behind a pinned version hasn't changed since it was validated. And every unnecessary dependency removed from production is attack surface eliminated, not just a maintenance chore checked off a list.
Monitoring has to run continuously, not on a quarterly audit cycle. Automated dependency scanning belongs inside the CI/CD pipeline, running against the live dependency graph on every single build. Alerts should fire on suspicious upstream changes, a sudden new maintainer, an unexpected postinstall script, not only on newly published CVEs. The SBOM itself should regenerate continuously and get compared against its prior state so any shift in the dependency graph is visible immediately rather than discovered later.
Shadow IT needs the same formal change management as anything else touching the codebase. The CSA advisory warns that shadow IT can introduce unquantified risk straight into core infrastructure and recommends denying it outright as one of several supply chain security measures. Least-privilege access needs to run across the entire pipeline, developer accounts, service accounts, CI/CD runners, automated jobs, all scoped to the minimum permissions they need, with production secrets and source repository access segmented by role rather than shared broadly out of convenience.
Platform engineering is where all of this either becomes real or stays theoretical. Internal developer platforms built by platform teams can enforce these controls as the default environment every engineer works in, rather than a policy document sitting in a wiki that developers are supposed to remember to follow. When the secure path is also the easy path, adoption stops being a matter of discipline. For third-party suppliers, provenance ought to work the same way: verify it wherever it's published, and treat its absence as a documented risk decision rather than something quietly accepted by default. A reasonable test of whether any of this is actually working: can a new engineer, on their first day, reproduce a complete, policy-compliant development environment with a single command? If the answer is no, the policy exists on paper and nowhere else.
Sources
- Securing software supply chains: how to safeguard against hidden dependencies | World Economic Forum
- Beyond Your Code: A Guide to Software Supply Chain Risk Management | Veracode
- Advisory on Securing the Software Supply Chain and Development Workflows
- WEF sounds alarm on software supply chain vulnerabilities, flags risks in open-source and third-party dependencies - Industrial Cyber
- Top Software Supply Chain Security Best Practices for Enterprises | Veracode
- A03 Software Supply Chain Failures - OWASP Top 10:2025
- The Software Supply Chain Problem: Why Cyber Resilience in Banking Now Reaches Every Vendor