This is a warning we have been wanting to put on the record. We are publishing it now because the wave we have been watching is large enough that we would rather have the note out before the next big one lands.

Most teams treat CI as a build system. CI is not a build system. CI is the highest-leverage production system the company runs. It has simultaneous write access to source code, deploy keys, secrets, package registries, and the machines of every downstream consumer. There is no other system in the modern stack with that combination of authority, and no other system that is defended this poorly.

We have been watching the attack class for about eighteen months. It is escalating. The year ahead is going to be a procession of incidents that look, after the fact, completely predictable.

What already happened

In March 2025, the tj-actions/changed-files GitHub Action was compromised. The action was used by roughly twenty-three thousand repositories. The attacker modified every existing version tag to point at malicious code. The payload dumped runner memory to the workflow log. On public repositories, those logs were world-readable. CISA filed it as CVE-2025-30066. Reviewdog's action-setup was compromised in the same week and the two were chained.

The compromise lasted less than a day. The blast radius was every secret used by every workflow that pinned a tag, including downstream actions that depended on tj-actions transitively. Most teams that ran the affected versions did not, and could not, enumerate which of their secrets had been exposed.

That is the floor. The ceiling is what we expect to see in the months ahead.

What we expect next

Four patterns we have been watching, roughly in the order we expect them to land.

Worm-class compromises. A single maintainer takeover that spreads through that maintainer's other published packages, into the secrets used to publish them, and from those secrets to other maintainers' packages. Once one of these completes a self-replication cycle in a major ecosystem, the time between compromise and a meaningful percentage of the registry being affected is measured in hours. The npm registry's structure makes this particularly easy. We do not believe a worm of this class has been published yet. We believe one is in development. OIDC and trusted publishing abuse. The shift away from long-lived publishing tokens toward OIDC and trusted publishing was a real security improvement. It also concentrated trust in the CI workflow itself. Once an attacker has arbitrary code execution inside a workflow that has trusted publishing rights, they have publishing rights without ever touching a token. We have not seen this fully weaponized at scale. The economics suggest someone is working on it. Cache poisoning as a primitive. The GitHub Actions cache is a per-repository key-value store reachable from any workflow that runs on a branch. Most teams treat cache contents as inputs to be trusted. They are not. A cache entry written by an untrusted workflow can be read by a trusted one. This has been a known issue for two years. It is still latent in approximately every CI configuration we audit. Slopsquatting. An LLM suggests a package name that does not exist. An attacker registers the name. A developer copies the suggestion into their dependency file. The attacker now has code execution in the developer's build, and by extension in the CI runner. Research from late 2025 found a 21 percent hallucination rate on open-source coding models. The base rate of attempts is going to climb with the deployment curve of AI coding assistants.

Why this got worse

Three structural reasons.

CI used to do less. The set of things a typical pipeline did five years ago was test, lint, build, push artifact. The set of things a typical pipeline does today includes provisioning infrastructure, rotating production credentials, running database migrations, deploying mobile binaries, and publishing public packages. The blast radius of a compromise has grown roughly with the blast radius of what CI is now allowed to do.

CI is a soft target. The standard threat model for a build system was written when the build system had no production access. Most of the controls in place at most companies still match that model. The result is that the most consequential system in the stack is defended at the level of an internal Jenkins box from 2014.

The supply chain is opaque. A typical action pulls dependencies that pull dependencies that pull dependencies. Few teams pin to commit SHAs. Fewer audit the SHAs they pin to. Almost none re-audit when the pin moves. The tj-actions incident was an existence proof. The lesson, broadly, has not been absorbed.

What we would be doing about it

If we were defending a non-trivial codebase right now, four changes would be on the short list.

Pin every action to a commit SHA, not a tag. Tags are mutable. SHAs aren't.

Treat every workflow that handles a secret as a production deployment. Code review. Approval. Logging. Restricted maintainer list. Separate identities for build secrets, deploy secrets, and publish secrets.

Use ephemeral runners. Self-hosted runners that persist between jobs are persistent footholds waiting to be claimed. Each job gets a fresh machine that dies when the job ends.

Treat your .github/workflows/ directory as the most security-sensitive part of the repository, because it is. Repository rulesets that require approval on workflow changes are free and almost nobody uses them.

None of this is novel. All of it is in the OpenSSF guidance, in CISA's advisories, in GitHub's own hardening documentation. Almost no team we have audited implements more than two of the four.

The honest one-liner

CI compromises are going to be the breach story of the next twelve months. We are putting this on the record now because the months ahead are going to be louder, and we would rather have called the pattern early than be one of the labs explaining it after the fact.

If you operate critical infrastructure and have not had this conversation internally yet, our suggestion is that you have it this week.