Triangulating the Fix: Putting FOSS Liability Where It Belongs

On March 25, 1911, 146 garment workers died in the Triangle Shirtwaist Factory fire in New York City. Most were young immigrant women. The exits were locked. The fire wasn’t an anomaly; it was an outcome of incentives. The owners also understood that the building was unsafe, and that the solutions (unlocked doors, a functioning fire escape, basic sprinklers) were neither expensive nor technically complex. The people who could have implemented it simply had no compelling reason to do so. The cost of inaction landed on the workers, not the owners.

One hundred fifteen years later, give or take a week, a North Korean threat actor compromised the axios npm package between 00:21 and 03:20 UTC on a Monday morning. By the time most developers had finished their first coffee, roughly 3% of axios’s weekly downloads (including from companies like Stripe, Microsoft, Amazon, and Google) had pulled a remote access trojan into their production environments. That’s literally millions of downloads. A mitigation against this attack had existed for three years; it was free, and took a mere fifteen minutes to implement. The people who could have mandated it had no compelling reason to do so. The cost of inaction landed on the developers, not the registry, not the maintainers, and certainly not Microsoft.

Last week, Valerio Mulas asked on LinkedIn why things aren’t getting better. The answer appeared in 1911, and echoes today. A century later, the exits were once again locked. The shape of the building has changed... but it is still, unmistakably, a triangle.


Three Is a Magic Number

The Triangle Shirtwaist Factory fire didn’t happen because anyone wanted 146 people to die. It happened because the incentive structure made safety someone else’s problem at every level of the organization. The owners weren’t paying for the sprinklers; the inspectors weren’t losing sleep over the exits; and the workers, who were losing sleep over rent, had no leverage to demand either.

The npm ecosystem has reproduced this structure with remarkable fidelity, and added a third dimension that the original Triangle lacked: the problem now has three distinct vertices, each one rationally externalizing cost to the next, each one with a perfectly coherent explanation for why the fix isn’t their responsibility.

The first node is Microsoft. Through its acquisition of GitHub, Microsoft became the de facto landlord of the modern software supply chain, angling for developer mindshare: every developer living in the GitHub ecosystem is a developer not living in a competitor’s ecosystem. npm came along as part of the deal, a conjunction junction on an acquisition that was never really about package management (hookin’ up repos and packages and functions). Microsoft has the engineering resources, the market position, and the technical capability to mandate OIDC-based trusted publishing across the ecosystem tomorrow. It has not done so. This is not because Microsoft is indifferent to security (it isn’t) but because npm generates no direct revenue. GitHub does. Developer mindshare does. The breach that empties Sarah’s AWS credentials at a fintech startup in Cleveland doesn’t appear on Microsoft’s incident report; it appears on Sarah’s.

The second node is the maintainer. As I’ve written before, the open source ecosystem runs on a labor force that is systematically invisible, undercompensated, and structurally incapable of bearing the security burden the ecosystem places on it. In a sound structure, load is distributed across all three sides. When one side fails, the load doesn’t disappear; it transfers. Trusted publishing takes fifteen minutes to implement... for a maintainer who is alive, attentive, and has fifteen minutes. For the maintainer who burned out in 2023, or transferred their package to a stranger, or (like Annette in the previous article) is simply gone, those fifteen minutes are unavailable. The exit is unlocked, but nobody is left to open it.

The third node is the downstream developer. Sarah, at the fintech startup. The 3% of axios’s userbase that ran npm install on a Monday morning and pulled a remote access trojan into production before anyone noticed. They are the workers at the windows. They bear the cost most acutely, yet control none of the variables that produced it.

A triangle is theoretically the most stable of geometric structures...but that’s true only when all three sides are intact. Remove one, and it doesn’t become a different shape. It simply collapses.


A Brief Tangent

Looking at this from a different angle, there is a concept in biology called commensalism: a relationship in which one organism benefits from another without meaningfully helping or harming it. The egret that follows the water buffalo, eating the insects stirred up by its hooves, is a textbook example. The buffalo is indifferent; the egret eats well. The insects may have opinions about this arrangement, but nobody asks them.

In our open-source triangle, npm is the egret, Microsoft the buffalo, and the developers whose credentials end up in Pyongyang the insects.

This is not a relationship of malice, mind you. Microsoft did not acquire GitHub in order to neglect npm security; rather, it was angling for the strategically valuable developer mindshare, with npm simply coming along as part of the deal. npm benefits from Microsoft’s infrastructure, its credibility, its enterprise relationships. Microsoft benefits from npm’s ubiquity... every developer who lives in the GitHub ecosystem is a developer who is not living in a competitor’s ecosystem. The arrangement is mutually convenient, and largely invisible to both parties... precisely the definition of commensalism. The metaphor isn’t exact; Microsoft monetizes the ecosystem, while developers bear the risk. But it illustrates the systemic externalization of cost.

What commensalism cannot produce is investment in the host’s wellbeing. The egret does not groom the buffalo; it simply follows it. And so Microsoft has neither mandated trusted publishing, nor built the sandbox layer that would make credential theft structurally impossible, nor used its position as de facto landlord of the supply chain to require that exits be unlocked. There is no revenue line that rewards doing so, and there is no cost line that penalizes failing to.

As I noted in Digital Pollution, and repeatedly in my other articles, this is the pattern: benefits internalized, costs externalized, the gap between the two filled by people who had no say in the arrangement. The buffalo has egrets, who eat well; the insects instead have regrets.


The Wrong Sine

Valerio Mulas, writing at VulNow, has done the industry a service by documenting what should be an embarrassing set of numbers. Of the top 25 most-downloaded npm packages, exactly two have adopted trusted publishing; both are maintained by npm itself. The chalk organization, responsible for packages downloaded 29.7 billion times in a single 90-day period, was compromised in September 2025. Seven months later, none of its packages have trusted publishing. Mulas’s conclusion is that the solution is obvious, available, free, and takes fifteen minutes. He is correct on all four counts.

He is also, inadvertently, asking the wrong question.

“Why won’t anyone use it?” assumes that the barrier is informational... that maintainers and registry operators don’t know about trusted publishing, or don’t understand it, or haven’t gotten around to it yet. But the axios maintainer didn’t fail to implement OIDC because they hadn’t heard of it. The chalk organization didn’t skip trusted publishing out of ignorance. Microsoft didn’t decline to mandate it because the engineering was too complex. Each of these actors made a rational calculation, implicit or explicit, about where the cost of action fell relative to the cost of inaction.

For the maintainer, the cost of a breach lands on downstream developers; the reputational damage is real but diffuse, and the fifteen minutes still has to come from somewhere. For the registry, mandating trusted publishing creates friction that could drive packages elsewhere; the breach that results from not mandating it creates headlines, but the financial cost lands on Sarah’s employer, not on npm. For Microsoft, the calculus is simplest of all: there is no revenue line for npm security, and the cost of the next axios breach will not appear on a Microsoft earnings call.

This is not a technology problem. It is the same problem that kept the exits locked at Triangle Shirtwaist; the same problem that kept Annette’s libraries unpatched after she was gone; the same problem that fills every article on this site. The control that would have prevented this attack existed years ago, and still does. What doesn’t exist is a reason for the people with the power to implement it to bear the cost of doing so.

OIDC is the sprinkler system. The building still needs a fire code.


The $60 Billion Pyramid

The $60 billion figure that Mulas documents for 2025 alone is striking, but the number itself is less interesting than its distribution. This isn’t a cost that lands on the people who created the conditions for it, but rather one that cascades downward through the pyramid, dispersing as it falls, landing heaviest on the people furthest from the decisions that produced it.

At the top of the pyramid, the costs are nearly invisible. Microsoft’s earnings calls won’t mention the axios breach. npm’s traffic metrics don’t reflect the credential theft. The chalk organization’s download numbers didn’t drop after September 2025; seven months later, its packages still lack trusted publishing, and the downloads continue. The people at the top of the pyramid absorbed none of the cost and changed none of their behavior. This isn’t coincidence; it is the system working exactly as its incentive structure requires.

One layer down, the costs become more visible but remain diffuse. The insurance industry noticed: supply chain claims jumped from 6% to 15% of large cyber claims between the first half of 2024 and the first half of 2025, a 150% increase in a single year. Carriers are now requiring third-party risk management programs, vendor cybersecurity certifications, and contractual security language. The market is pricing in the risk that maintainers won't protect themselves; the market has accepted that the problem won't be solved at the source, and is instead distributing its cost across every policyholder in the ecosystem, pricing that failure into the layers least capable of preventing it.

At the base of the pyramid, the costs are neither invisible nor diffuse. They are immediate, specific, and expensive. When Vercel invalidated millions of build artifacts after the September 2025 attack, engineering teams worldwide dropped everything for emergency audits. Roadmaps slipped. Deadlines were missed. CI/CD pipelines broke. Credentials were rotated across thousands of organizations. IBM’s data suggest that supply chain attacks take 267 days to detect and contain (38% longer than any other attack vector), which means the base of the pyramid is paying not just in immediate remediation costs, but in months of compounding exposure they may not even know they have.

This is the Digital Pollution story, told in dollars. As I’ve written before, the defining feature of pollution is that the people who produce it don’t pay to clean it up. The costs drift downstream, dispersing as they go, landing on people who had no say in the arrangement. The $60 billion isn't a number that describes a discrete event; it describes the annual cost of a permanently polluted ecosystem, distributed across millions of organizations that ran npm install and trusted that someone, somewhere, had checked what was in the package.

Nobody in a position to guarantee it had done so. Nobody with the power to require it had any reason to.


The Acute Problem

In October 1999, Microsoft published a document titled “Linux Myths”, an argument against the growing enthusiasm for open source software that was self-serving, strategically motivated... and entirely correct. Among its claims, preserved by Linux Weekly News, was this: “The very definition of Linux as an Open Software effort means that commercial companies like Red Hat will make money by charging for services. Therefore, commercial support services for Linux will be fee-based and will likely be priced at a premium.” Stripped of the competitive framing, the pointed argument was simply that free software comes with nobody to call when things break. No support contract. No warranty. No recourse. You get what you pay for, and what you pay is nothing.

The MIT license hasn’t changed since then. It still says, explicitly, that the software comes with no warranty of any kind. When the axios maintainer’s account was compromised, the license was not violated. Nobody breached a contract. The maintainer didn’t owe Sarah anything; npm didn’t owe Sarah anything; Microsoft didn’t owe Sarah anything. She got exactly what she paid for.

And yet the ecosystem that runs on these warranties-of-nothing now underpins global financial infrastructure, healthcare systems, and critical government services. The packages nobody owns are the packages everyone depends on. We have built our critical infrastructure on orphans... and then expressed surprise when the orphans turn out to be mortal, compromised, or simply gone.

The FOSS license is honest. The ecosystem’s relationship with that honesty is not.

Which brings us, again, to Microsoft. Not because Microsoft is uniquely villainous (it isn’t), and not because the MIT license is broken (it isn’t), but because Microsoft is the only actor in this triangle with the resources, the market position, and the technical infrastructure to do what the license cannot: create the structural conditions under which trusted publishing becomes the default rather than the exception. It owns the identity layer. It owns the CI/CD pipelines. It owns the registry. It operates the default and overwhelmingly dominant distribution channel for the JavaScript ecosystem, placing it on the critical path for nearly every developer. It therefore has every tool needed to mandate that new packages use OIDC, that high-download packages with active maintainers follow within a defined window, and that zero-maintainer packages... the Annettes... are flagged visibly at the moment of npm install, so that Sarah knows, before she runs the command, that she is about to take a dependency on a ghost.

This won’t happen voluntarily. We’ve established why. The egret doesn’t groom the buffalo; it follows it. What changes the calculation is what always changes the calculation: the cost of inaction has to land somewhere closer to where the decisions are made.


Finding the Right Angle

One attempt to land the costs where the power to mitigate them actually sits is the Cyber Resilience Act. The debate around the CRA has focused largely on the wrong question: how do we make open source developers more responsible? The answer to that question, applied bluntly, is a disaster. A regulation that creates liability for publishing code would effectively end casual open source contribution. The hobbyist who wrote the Home Assistant dashboard widget on a weekend didn’t sign up to be a defendant. Neither did Annette.

The right question is different: should commercial entities that profit from open source infrastructure be permitted to disclaim liability for its failures?

Product liability law has answered this question for a century, in contexts ranging from automobiles to pharmaceuticals. If Ford incorporates a component into a vehicle and the component fails, Ford doesn’t escape liability by pointing at the supplier. The entity that built the commercial product owns the liability chain. The fact that the component was free doesn’t change the analysis; Ford’s defense has never been “But we didn’t pay for that part.” The analogy isn’t perfect, but liability law has historically followed control and profit, not purity of authorship.

Microsoft’s position in the npm ecosystem is not passive. It operates the registry. It provides the CI/CD pipelines through which packages are published. It charges Azure customers to run infrastructure that depends on those packages. That’s not the egret following the buffalo; that’s the egret selling tickets to watch the buffalo, controlling the gate, and posting a sign at the entrance disclaiming responsibility for everything inside.

When an axios maintainer’s account is compromised and a remote access trojan rides npm’s distribution infrastructure into thousands of production environments, the question of who bears liability shouldn’t be resolved by pointing at the MIT license. It should be resolved by asking who profited from the transaction. The answer is not the maintainer. It is not Annette’s ghost. It is the entity that built a revenue-generating business on top of the edifice those people constructed for free, and then declined to mandate the fifteen-minute fix that would have made the attack impossible.

A properly scoped CRA would follow the money. Liability attaches not to the act of publishing code, but to the act of profiting from its distribution. The hobbyist is carve-out; the commercial infrastructure operator is not. Annette, who asked for nothing and received nothing, would bear no liability for the node of the triangle she could no longer hold. Microsoft, which built a revenue-generating business on the infrastructure Annette helped create, would bear all of it. Microsoft running npm packages through Azure pipelines and charging customers for the privilege isn’t a passive act. It’s incorporation. And incorporation should carry liability.

Software Bills of Materials (SBOMs) and attestation are part of this picture too... the transparency layer that makes the liability chain legible. You can't assign liability for a failure you can't trace; without SBOMs, every npm install is a trip through The Jungle... you know you're consuming something, but not necessarily what. Trusted publishing, provenance attestation, and complete software bills of materials are the evidentiary infrastructure that makes the legal infrastructure possible. Mulas identified the symptom; this is the diagnosis.

The Triangle Shirtwaist Factory got its fire code, not because the owners wanted one, but because the public decided that “nobody to call” was no longer an acceptable answer when the building was on fire. The exits in that building were locked for the same reason the trusted publishing mandate doesn’t exist today: the people with the keys weren’t the ones who needed to get out.

The shape of the building has changed. The triangle is still recognizable. The exits don’t have to stay locked.

Disclosure: the author serves as a strategic advisor to Ossprey, a platform that does what the ecosystem’s landlords won’t: actively scan for malicious open source code in real time. Unlike the egret, the osprey hunts.