DevSecOps · Supply Chain · Compliance

You Did Not Write Most of Your Software. Can You List It?

  • DevSecOps · Supply Chain · Compliance
  • Q3 2026
  • blog
Software supply chain and build pipeline dependencies

Two billion lines is the wrong number to be impressed by

The most quoted figure in this area comes from Rachel Potvin, an engineering manager at Google, who told the @Scale conference in 2015 that Google's codebase ran to two billion lines of code across 86 terabytes. Around 25,000 engineers worked in it, changing roughly 15 million lines across 250,000 files every week, at about 45,000 commits a day. For scale, the Linux kernel at the time was about 15 million lines.

It is a genuinely astonishing number and it is also the wrong one to worry about, because that is code Google wrote and owns. Almost nobody else's estate looks like that. The interesting question for the rest of us is not how much code we have written. It is how much of what we ship we have never read.

The growth that matters is assembly, not authorship

Academic work on the ecosystem published this year describes npm as carrying over two million packages and more than a billion downloads a month. Nobody has read two million packages, and nobody needs to, because the problem is not the size of the catalogue. It is that you do not choose most of what you install. You choose a framework, and the framework chooses a few dozen things on your behalf, and those choose more. The manifest you actually edit is a small fraction of what ends up on disk.

This is worth sitting with if you work in the Salesforce ecosystem, because the two halves of a typical estate are governed on completely different terms. Every managed package listed on AppExchange has to pass a mandatory Salesforce security review, and that review applies to every listing type, including solutions that only talk to Salesforce over an API. Publishing to npm requires that you have an account.

The AppExchange package in your org was audited. The Lambda behind the integration next to it installed whatever the lockfile resolved to that morning.

Both are in production. Both can reach your data. Only one of them went through a gate, and it is usually not the one carrying the most third-party code.

Even the storefronts are struggling with volume

If you want a sense of how much of this is now automated, look at what the platform owners have had to do about it. Analysis by Appfigures, reported by TechCrunch in April 2025, found Google Play had fallen from around 3.4 million apps at the start of 2024 to roughly 1.8 million, a decline of about 47 per cent, driven by raised quality requirements and a sustained purge. Over the same period Apple's App Store went from about 1.6 million to 1.64 million.

One store shed nearly half its catalogue and the other barely moved. That is not a story about Android being worse. It is a story about what happens when publishing is nearly free and review is not, and it is the same dynamic that shapes a package registry.

Seventy-five per cent

The rate at which new code arrives has changed faster than most of the commentary about it. Sundar Pichai said in October 2024 that more than a quarter of Google's new code was AI-generated. By April 2025 that was more than 30 per cent. On 24 April 2026 he said 75 per cent of all new code at Google is now AI-generated and approved by engineers, up from 50 per cent the previous autumn.

I would not skip past the qualifier. "Generated and approved by engineers" is doing a great deal of work in that sentence, and it is the only part of it that describes a control. The generation is the cheap half. The approval is where accountability still lives, and it is worth asking honestly what approval means when the volume triples in eighteen months.

There is a second-order effect that gets less attention than the line counts. An agent scaffolding a service does not just write code, it selects dependencies. It is now trivial to assemble a working product out of a couple of hundred packages nobody on the team has evaluated, in about the time it takes to describe what you wanted.

The institutions that used to tell you have given up

For most of the last twenty years there was a quiet assumption underneath all of this: if something you depend on turns out to be vulnerable, somebody will catalogue it, enrich it with the detail you need to act, and publish it for free. That assumption has now formally expired.

NIST, April 2026. CVE submissions rose 263 per cent between 2020 and 2025. NIST enriched close to 42,000 CVEs during 2025, about 45 per cent more than in any previous year, and still could not keep pace. It has now changed how the National Vulnerability Database operates, enriching only those CVEs that meet defined criteria. Everything else remains listed but is treated as lowest priority and does not get the deeper analysis. Submissions in the first quarter of 2026 ran nearly a third higher again than the same period a year earlier. Help Net Security called it, fairly bluntly, admitting defeat on the backlog.

I do not read that as an institutional failure, and it would be cheap to write it up as one. It is a volume problem that no reasonable amount of human triage was ever going to absorb. But the consequence still lands on you. The complete, enriched, free feed that a good deal of tooling quietly depends on is not coming back, and anything that was relying on someone else doing the analysis now has a gap in it.

The exploit window went negative

The other half of the timeline moved in the opposite direction. Mandiant's time-to-exploit tracking put the average at around 63 days in 2018, 44 days across 2020 and 2021, and 32 days across 2021 and 2022. Its analysis of vulnerabilities disclosed in 2024 put the mean at minus one day. The 2026 M-Trends reporting puts it at about minus seven.

PeriodMean time to exploit
2018About 63 days
2020 to 202144 days
2021 to 202232 days
2024 disclosuresMinus 1 day
2025, M-Trends 2026About minus 7 days

A negative number means exploitation is routinely happening before the patch exists. Every remediation policy written around the phrase "patch promptly" assumed a window between disclosure and attack, and budgeted some portion of it for discovering whether you were affected. That window has closed, and the part of it most organisations spent on discovery was always the largest part.

Which changes the question

The useful question was never "is there a vulnerability in our stack". There is, right now, and there will be another one on Tuesday. The question is narrower and much harder: are we affected, which released artefact is affected, is it actually deployed, what do we do about it, and can we show afterwards why we decided what we decided.

That is the argument we made in Time-to-Market Is Not the Same Thing as Quality-to-Market, and this is the same shape of problem from the other end. The bottleneck has moved from discovery to decision. What has changed is that you can no longer answer the first part by reading your own code, because most of it is not yours and never was.

Which makes it an inventory problem

A Software Bill of Materials is the unglamorous answer. It is an ingredient list: a formal, machine-readable inventory of every component in a piece of software, including the ones you never chose. Two standards matter in practice, SPDX and CycloneDX, and for most purposes the choice between them is less important than having either.

A usable entry carries the component name and exact version, the supplier or author, a unique identifier such as a Package URL so that two things with similar names cannot be confused, the dependency relationships that say which component pulled in which, a cryptographic hash of the artefact so tampering is detectable, and the licence.

What one actually looks like

People talk about SBOMs a great deal more than they show them, which makes them sound more abstract than they are. This is a trimmed CycloneDX document in JSON, with one direct dependency and one thing it dragged in behind it.

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "serialNumber": "urn:uuid:9f0a1c7e-2b44-4c81-9a1e-6f3d5b0c8e11",
  "version": 1,
  "metadata": {
    "timestamp": "2026-09-18T02:14:33Z",
    "component": {
      "type": "application",
      "name": "appgenie-file-bridge",
      "version": "4.2.1"
    }
  },
  "components": [
    {
      "type": "library",
      "name": "express",
      "version": "4.21.2",
      "purl": "pkg:npm/[email protected]",
      "supplier": { "name": "OpenJS Foundation" },
      "licenses": [ { "license": { "id": "MIT" } } ],
      "hashes": [
        {
          "alg": "SHA-256",
          "content": "9f2b7a1d4c6e8035bd41a2f97c5e0d3a8b6417de92c0af53718b4e6d2c9a7f10"
        }
      ]
    },
    {
      "type": "library",
      "name": "cookie",
      "version": "0.7.1",
      "purl": "pkg:npm/[email protected]",
      "supplier": { "name": "jshttp" },
      "licenses": [ { "license": { "id": "MIT" } } ],
      "hashes": [
        {
          "alg": "SHA-256",
          "content": "3c81f0a94d27be5106af3e8d7b2c45019fa6e3d8c71b0942ae5f36d8017c2b4e"
        }
      ]
    }
  ],
  "dependencies": [
    {
      "ref": "pkg:npm/[email protected]",
      "dependsOn": [ "pkg:npm/[email protected]" ]
    },
    {
      "ref": "pkg:npm/[email protected]",
      "dependsOn": []
    }
  ]
}

Nothing there is clever, and that is rather the point. The dependencies block is the part that earns its keep: it records that nobody asked for cookie, it arrived because express wanted it. When the next advisory lands against something three levels down, that block is the difference between a query and an archaeology project.

What it actually buys you

The first thing is the ability to answer the Log4j question in seconds rather than days. Most organisations spent that particular week doing manual archaeology across repositories to work out whether they were exposed. With a current inventory that is a database query against a vulnerability feed, and the engineering time goes into fixing rather than finding.

The second is licence exposure, which is duller and occasionally more expensive. Open-source code is free to use and still legally binding. A restrictive copyleft licence pulled in three levels down, into a commercial product, is a genuine commercial problem that nobody discovers until somebody looks. An inventory lets a scanner flag it before the thing ships rather than during diligence.

The third is provenance. Those hashes are the reason the format bothers with them: they let you prove the artefact you shipped is the artefact you built, which matters rather a lot now that attackers have worked out that poisoning a package registry scales better than attacking a firewall.

Most of the SBOMs I have seen were produced for an auditor, not for an incident.

Which is the whole problem, and it is the same one we wrote about in Who Watches the Watcher?. An inventory built at audit time describes a build that no longer exists. It has to be generated by the pipeline, per build, stored with the artefact it describes, and actually queryable when the advisory lands at four in the afternoon. Otherwise you have bought the paperwork and none of the capability, which is a worse position than having neither, because you now think you are covered.

Why it stopped being optional

This moved out of the realm of good practice some time ago. United States Executive Order 14028 pushed SBOMs into federal software procurement, and the European Union's Cyber Resilience Act carries obligations in the same direction for products sold into that market. If you sell software to government or operate anything classed as critical infrastructure, a verifiable bill of materials is now part of the transaction rather than a nice-to-have in the security section.

For an Australian consultancy or ISV, the practical version of this is simpler than the regulatory reading suggests. The buyers who ask hardest are the ones with the longest contracts, and the question arrives during procurement rather than after an incident. Not being able to answer it is increasingly a commercial problem before it is ever a security one.

Where this leaves us

The pieces line up in an uncomfortable way. Most of what you ship, you did not write. The rate at which new code arrives has roughly tripled in eighteen months at the one organisation that publishes numbers about it. The body that used to enrich vulnerability data for everyone has formally narrowed its scope because the volume beat it. And exploitation now tends to arrive before the fix.

None of that is solved by a better scanner. It is solved, or at least made tractable, by knowing precisely what you have shipped, being able to prove it has not been altered, and being able to answer the affected-or-not question fast enough to make a decision rather than an apology. That is not a compliance exercise. It is the minimum viable knowledge of your own product.