The workstation is in scope now
Tomás Vega
You drew your first supply-chain threat model with the build server in the middle. Registry to the left, runners to the right, a comforting box around all of it. The developer laptop sat outside the box, because that's where trusted people sit and trusted people write trusted code. Adorable.
A DevOps.com essay this week argues that the laptop is now inside the box, and that anyone still drawing the perimeter at the CI runner is behind the curve. It cites the Megalodon campaign, which injected malicious GitHub Actions workflows into thousands of repositories, and a separate incident involving a malicious Visual Studio Code extension, as evidence that the workstation has become an attacker's on-ramp into the same pipeline everyone else has been busy hardening.
The perimeter moved
For years the discussion focused on centralized infrastructure: build servers, package registries, CI/CD systems. That was defensible. Those are the machines that hold the signing keys and produce the artifacts everyone downstream trusts. Harden them and you bought yourself real ground.
The problem is that everything before those machines still gets to speak on their behalf. The workflow file the runner executes is a file that a human, or something pretending to be a human, committed from a laptop. The extension your editor autoloads runs with the same OS user, the same SSH agent, the same active session as you do. Anything upstream of the commit is upstream of your build, whether the diagram admits it or not.
Two exhibits worth reading again
Megalodon is the obvious one. Poison the workflow, and the runner will happily execute it with whatever permissions your default GITHUB_TOKEN carries, on whatever trigger the attacker chose. You did not need a compromised build server. You needed a repository that would accept a workflow change.
The VS Code extension is the quieter one, and the more interesting. An editor plugin is code that runs with your dev credentials on the machine that holds your dotfiles, your local cloud credentials, and the checkout of every repository you have ever touched. It runs when you launch the editor, not when you deploy. By the time anything downstream sees a signed commit, the signing already happened on a host you no longer have reason to trust.
Isn't that just a hardware issue? Not really. It is an issue of what your pipeline is willing to believe about its own inputs.
Controls the pipeline can still land
Some of this the CI/CD side does have leverage on. Not all.
Signed commits and signed tags catch part of it. A workstation compromise that steals the signing key still gets to sign as you, but one that does not gets caught the moment a merge gate rejects an unsigned commit. Cheap check, useful floor.
Workflow allowlists do more, because Megalodon-style workflow injection dies in code review, provided .github/workflows/ is a protected path with mandatory review from someone who is not the author. A CODEOWNERS entry and a branch-protection rule for workflow files is a Tuesday afternoon of work; a lot of organisations still have not spent it.
Pinning uses: to a full commit SHA (uses: some/action@<full-40-char-sha> rather than a floating @v3 tag) shuts a different door. It stops the tag from being moved under you. It does not help if the pinned SHA was compromised at authoring time, but it kills a whole class of retroactive tampering that a tag reference happily invites.
Ephemeral, least-privileged runners with scoped OIDC tokens carry a smaller blast radius than long-lived self-hosted runners that remember every previous job's secrets. They do not prevent the malicious workflow from running once. They do prevent it from persisting into the next one.
Where the pipeline runs out of leverage
Now the honest part. None of the above stops the malicious VS Code extension. The extension exfiltrates before a commit exists, before signing exists, before your allowlist gets a vote. Any control that lives inside the pipeline is downstream of the machine that produced the input to the pipeline.
That means the workstation itself needs its own controls, and those controls are not owned by the platform team. Managed extension registries. Hardware-backed key storage. MDM policies that treat the editor's plugin surface as a supply-chain surface. Dev containers that quarantine the toolchain from the host operating system. All of those live in the endpoint-security lane, and pretending otherwise is how you end up with a beautifully attested pipeline that trusts an artifact a laptop already lied about.
Take the essay at its word. A threat model that stops at the build server no longer matches the incidents already in the news. The CI-side controls are cheap and worth doing. They just do not cover the machine that fed the pipeline in the first place.
Source: DevOps.com (devops.com)