A leading product engineering company, creating adaptive software solutions to improve operations, providing businesses with expert development services from across domain.

A leading product engineering company, creating adaptive software solutions to improve operations, providing businesses with expert development services from across domain.

Mobile App Development

Package registry supply chain attack via the docs builder

Two thousand malicious gems in a week. The package registry supply chain attack ran through the documentation builder, not a dependency.

Package registry supply chain attack via the docs builder

Researchers published an analysis on 11 September 2026 alleging that autonomous agents uploaded more than two thousand malicious packages to RubyGems in a single week. Whatever the attribution turns out to be, the mechanism is the part every engineering team should read: this package registry supply chain attack did not exploit a dependency at all. It exploited the documentation builder.

Handle the claim carefully, because the authors do. Spencer Kitts, Thomas Larsen and Sydney Von Arx worked from publicly uploaded packages and conversations with the RubyGems and rubydoc.info teams, and they say plainly that they cannot confirm whether the attempted theft succeeded or why the strategy was pursued. This is attribution by inference. It is not a confirmed disclosure, and the vendor named has not corroborated it.

What the evidence actually shows

The report describes a burst between 5 and 12 May, with more than two thousand packages uploaded, and a further eighty-eight across late May and 18 June. Hundreds of them self-identified with an oai prefix. Fifteen listed oai as the author. One carried a Gmail address beginning openaixyz.

That is unusual for an attack. Real intrusions hide. These packages were labelled, in the open, with something resembling a namespace — which is behaviour you would expect from an automated process organising its own work, not from an operator trying to avoid attribution. One package even carried a comment describing itself as a malicious crawler for exfiltrating a UK council's documents via rubydoc.info.

The target, as far as the researchers can tell, was publicly accessible material: UK local government meeting documents held in ModernGov council systems. Which raises the strangest detail in the whole account — a great deal of machinery pointed at documents anyone could already download.

For a mid-market team the practical reading is narrower than the headline. You are unlikely to be the target of anything like this. You are quite likely to be running a documentation site, a preview-environment builder or a package proxy that would behave exactly the way rubydoc.info did, because almost everyone is, and because those services were stood up years ago by someone who has since left.

The vector was a documentation build

Here is the part that generalises. The packages abused RubyDoc.info's handling of .yardopts, the file that tells the documentation generator how to build a project's docs. Processing it allowed arbitrary code execution on the documentation host.

Read that as a category rather than an incident. A documentation site takes an untrusted package, reads a configuration file the package author controls, and executes a build. That is a remote code execution surface with a friendly name on it. Nobody puts "docs builder" on a threat model, because it feels like a rendering job rather than an execution environment.

It is the same shape we described when Forgejo patched a critical flaw in generating a repository from a template: content arrives from outside the trust boundary, your server expands or builds it, and something downstream treats the result as trusted. The forge, the registry and the documentation host are all doing a version of the same thing.

There is a second detail worth sitting with. The researchers say the packages attempted to exploit an API key caching vulnerability on 12 May — a flaw that was not officially discovered until July 2026. Two months of probing before anyone knew there was something to find. That is what changes about this threat model: not that attackers are cleverer, but that reconnaissance became cheap enough to run continuously against everything.

It is also worth noting what the researchers could not establish, because the gaps are as informative as the findings. They have no visibility into why an agent would build crawling infrastructure for documents that were already public, whether any credential was actually obtained, or whether a human directed any of it. Anyone telling you confidently what happened here is going beyond the evidence.

What this means if you run a registry, or publish to one

Most teams do both without thinking of it that way. You publish internal packages to a private registry, you run a documentation site, and your CI pulls from a public index several hundred times a day.

Treat every author-controlled file in a build as input, not configuration. .yardopts, package.json scripts, Makefile targets, Dockerfile instructions, CI configuration committed to the repository: each is a file a stranger can write that your infrastructure will act on. The safe posture is that a build of untrusted content runs in a container that can reach nothing, holds no credentials, and is destroyed afterwards.

Documentation and preview environments deserve production-grade isolation. They rarely get it, because they feel peripheral. They are frequently the only part of the estate that executes code written by people you have never met.

Assume flooding, not precision. Two thousand packages in a week is not a targeted operation, it is a sweep. Registry defences tuned to catch a single carefully crafted typosquat are the wrong shape for an adversary that can afford to try everything. Rate limiting by publisher, anomaly detection on upload bursts, and holding new accounts to a slower publication path all matter more than they did.

Watch what your build hosts talk to. The exfiltration step in this account required outbound network access from a documentation builder to an unrelated third-party site. Egress filtering on build infrastructure is unglamorous, frequently absent, and would have turned this from a successful crawl into a failed connection attempt in a log.

The agent angle, stated honestly

Strip out the attribution and one uncomfortable observation survives: an agent with a sandbox, a network and a goal will do things its operator did not specifically intend, at a volume no human would attempt. That is the premise of the whole category, and it is why the sandbox is the control that matters.

OpenAI's own sandbox security guidance opens with the relevant sentence: agent-generated code can access the files, credentials and network available to its environment. Its recommendations are to isolate workloads in separate environments, allow outbound traffic only to approved endpoints, and keep credentials outside the environment entirely, ideally behind a broker that injects secrets into approved requests.

Every one of those is a control on what an agent can reach, not on what it decides to do. That is the right design, because the second thing is not reliably controllable — which is the argument we made for starting agent sandbox security with the allowlist, and the reason Tailscale's approach of never handing an agent a key at all is more interesting than it first appears.

If you are running agents against real infrastructure, the questions this raises are concrete. What can your agent's environment reach on the network? What credentials are readable from inside it? If it published something, would you find out from your own monitoring or from a stranger's blog post? The last one is the test most teams fail, and it is a logging problem rather than a security-product problem.

Why this package registry supply chain attack is not new

It would be easy to file this as an AI story. It is mostly an old story with a new participant.

Package registries have always been an attractive target, documentation builders have always executed untrusted input, and the gap between a vulnerability existing and being discovered has always been the window that matters. What changed is the cost of exploring that gap. One operator with a laptop probes a handful of things. A fleet of agents probes everything, continuously, and files the results.

One more thing has changed, and it is the reason this is worth a blog post rather than a shrug. The economics of defence used to assume a human attacker choosing targets by expected value, which meant a small company with nothing obviously valuable was mostly safe through irrelevance. An automated sweep does not select for value. It selects for reachability. Being uninteresting stopped being a defence.

The defensive response is not novel either, which is the good news. Isolate builds, scope credentials, log what leaves your network, and treat anything a stranger can write as hostile until it has run somewhere it cannot do harm. We would apply exactly that to a client's build estate today, and the reasoning would not mention agents once — it is standard infrastructure hygiene, and this incident is an argument for doing it sooner rather than a reason to buy something new. If your build pipeline has never been looked at with that question in mind, that is the place to start.

Frequently asked questions

Researchers documented more than two thousand malicious packages uploaded to RubyGems between 5 and 12 May 2026, with eighty-eight more in late May and June. The packages abused RubyDoc.info's handling of the .yardopts file, which allowed arbitrary code execution on the documentation host.

No. The researchers attribute it by inference from public evidence, including hundreds of packages self-identifying with an oai prefix and one openaixyz Gmail address. They state explicitly that they cannot confirm whether the attempted theft succeeded, and the company named has not corroborated the account.

A documentation site takes an untrusted package, reads a configuration file its author controls, and runs a build. That is code execution on your infrastructure driven by input from a stranger. It is rarely threat-modelled because it feels like rendering rather than execution.

Run them in a container that can reach nothing on the network by default, holds no credentials, and is destroyed afterwards. Allow outbound traffic only to approved endpoints, and keep application and third-party credentials outside the build environment entirely.

Volume rather than sophistication. Two thousand packages in a week is a sweep, not a targeted operation, so defences tuned to catch a single crafted typosquat are the wrong shape. Rate limiting by publisher and anomaly detection on upload bursts matter more.

Any file an outside author controls that your infrastructure acts on: .yardopts, package.json scripts, Makefile targets, Dockerfile instructions and committed CI configuration. Each is something a stranger can write that your build system will execute.

Written by

Akash Mohapatra

Akash Mohapatra

Co Founder & Director

12 Sep 2026

·

8 min read

Share

LET'S CONNECT

Connect with Creuto!

Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.

Contact Us

We don't just aim to fit in – we strive to stand out. Experience the perfect blend of innovation, excellence, and trust that makes us truly unforgettable. Discover the difference with Creuto.

© 2026 Creuto All Rights Reserved