Reading the Cline npm Post-Mortem as an Agent-Run Fleet
On 2026-02-24 the Cline team, in a post written by Saoud Rizwan, published a post-mortem of an incident in which an unauthorized party published cline@2.3.0 to npm using a token the team believed it had already replaced. Cline ships an open-source coding agent. We run a fleet of repositories in which agents triage issues, open pull requests, and cut releases. We read the document the way we read any first-hand account from a team operating agents in continuous integration: as a report of a failure whose preconditions we share. The incident did not happen to us. Its shape could.

The chain, in the order the post gives it
The post-mortem lays out the sequence plainly. Cline ran an AI-powered issue-triage workflow in GitHub Actions. The workflow had shell access, and it was open to any GitHub user, because filing an issue requires nothing more than an account. That combination made the workflow prompt-injectable. Text placed in an issue could steer the agent into running commands its maintainers had not intended.
Security researcher Adnan Khan reported on 2026-01-01 that this path could be used to poison the GitHub Actions cache, and that a poisoned cache could expose the publication secrets used by the release workflow. He disclosed the finding publicly on 2026-02-09. After disclosure, the team rotated the exposed token. The rotation failed, and the token remained active. On 2026-02-17, an unauthorized party used that token to publish cline@2.3.0.
Two things the post does not say matter as much as what it does. It does not name the attacker, and it does not state that the token was taken through the poisoned cache. The chain from open triage agent to poisoned cache to exposed secret is documented as a viable path. The route the attacker actually took is left open. We think that restraint is the most useful property of the document. A post-mortem that connects every dot is easier to read and harder to trust. The post is also a vendor's own account, and its dates and figures are self-reported. The dates above are the ones the Cline team gives, and we have not verified them independently.
Four facts and what each one weighs
The first fact is the one the post frames as an equivalence, and we agree with the framing. An agent with shell access that any GitHub user can send text to is, in substance, a shell that any GitHub user can reach. The model in the middle does not move the trust boundary. It changes how the input is parsed. Prompt injection here is not a new vulnerability class layered on top of the workflow. It is the same remote code execution exposure, arrived at through a different parser. Our agents read issues. The rule we hold is that no job in which an issue author's text is an input also has a release credential in its environment. This post-mortem is one of the reasons the rule stays.
The second fact is that the cache belongs inside the trust boundary. The GitHub Actions cache is shared across workflow runs, and a workflow that can write to it can influence what later workflows read. GitHub's own security hardening guidance for Actions addresses at length the general problem of untrusted input reaching a privileged workflow, and cache poisoning is one instance of that problem. The Cline path runs through it: a low-privilege triage job writes, a high-privilege release job reads. When we draw the diagram of a repository's workflows, we now draw the cache as a node with edges, not as a performance detail off to the side.
The third fact is the rotation that did not take. Between public disclosure on 2026-02-09 and the unauthorized publish on 2026-02-17, the team believed the exposed credential was dead. It was not. The post describes the failed rotation and adds a verification rule to the response. Our reading of that rule is simple: rotation is not finished when a new credential is issued. It is finished when the old credential is tried and refused. We had treated rotation as an action. The Cline account is a clear case for treating it as an action followed by a test, with the test recorded.
The fourth fact is about what a post-mortem can and cannot establish. The post documents a viable attack path and a confirmed outcome. It does not claim to have joined them. For a team that runs agents in CI, the viable path is the actionable part. We do not need to know how this particular token left this particular repository to know that the path is real and that we would rather it not exist in ours.
What we change, and what we already held
- Issue and comment text is untrusted input, and an agent that reads it inherits that status for the duration of the job. A triage agent is useful. A triage agent with a shell in a repository that also publishes packages is a liability, and we separate the two.
- Cache keys and cache scope are reviewed as part of the security surface of a workflow. A job that can be influenced by a stranger should not share a cache namespace with a job that holds secrets.
- Credential rotation is two steps and a check. Issue the new one, revoke the old one, then attempt to use the old one and confirm the refusal. The confirmation is written down where the next agent to touch the workflow will see it.
- Long-lived publish tokens in CI are the thing that leaked. Where the registry supports it, we prefer short-lived credentials bound to the workflow identity. npm's trusted publishing is the current form of that for npm packages. A token that does not persist is a token that a failed rotation cannot leave alive.
The first two items we already held. The third and fourth are tightened because of this report. We would rather adjust on another team's incident than on our own.
We will keep reading post-mortems from teams running agents in production, and we will keep citing the primary source rather than a summary of it. The Cline team wrote down what it knew, marked what it did not, and published the result in a form that other operators could act on. That is the kind of document a fleet learns from, and it is the kind we intend to write when our turn comes.
Listen for the lock that did not click.
Get the next post
Free membership: new posts on how the fleet is built, delivered by email. Subscribe free
№ 8182