Yesterday, GitHub said it had detected and contained a compromise of an employee device involving a poisoned VS Code extension. The company said its current assessment is that the activity involved exfiltration of GitHub-internal repositories only, and that the attacker's claim of roughly 3,800 repositories is directionally consistent with its investigation so far. GitHub removed the malicious extension, isolated the endpoint, and prioritized rotation of critical credentials.
A few days earlier, I had been doing something similar from the other direction. I yanked OpenAI's Codex Chronicle off my laptop and replaced it with a local Gemma 4 instance running on a Mac mini I own. Originally, that was a cost decision. The breach made the security implications of the architecture impossible to ignore.
A trusted third-party binary. Installed locally. Full read access to your screen, your files, your tokens. An outbound network path the user set up themselves, allowed by every firewall because the user did it.
Compromise the binary at any point in its supply chain, and you do not need to compromise the platform. The platform is doing what it was told.
You walked in.
That is the GitHub breach. That is also Codex Chronicle if a tool like it were ever compromised at the build pipeline or distribution layer. The architectures are siblings.
A local model is not automatically safe. A compromised local agent with filesystem and shell access is still a privileged execution environment. The difference is that local architectures reduce the mandatory external trust boundary and make inspection possible.
The warning signs were already everywhere
TeamPCP is not a one-off. The group is tracked in public reporting as UNC6780, and its 2026 target list before this week included Trivy, Checkmarx, LiteLLM, the Bitwarden CLI, PyTorch Lightning, and most recently the TanStack and durabletask npm and PyPI compromises connected to the Grafana breach a week earlier.
Look at that list.
Trivy. Checkmarx. LiteLLM. Bitwarden CLI. PyTorch Lightning.
Every one of those is developer or developer-adjacent tooling. Trusted. Locally installed. Frequently updated. Each one is a trojan vector with a credential blast radius that extends from the developer's laptop through cloud accounts and into production.
The npm side of the same campaign is worse. According to public analysis from SlowMist and other researchers, attackers compromised the npm account atool and pushed hundreds of malicious package versions across hundreds of packages within minutes. The Mini Shai-Hulud malware family specifically targets GitHub tokens, AWS keys, Kubernetes secrets, SSH credentials, password manager databases, and local crypto wallet files.
This is not a string of bad luck. It is a deliberate, sustained campaign against the supply chain that ends at every developer's ~/.config, ~/.aws, and ~/.ssh.
The developer endpoint is the perimeter
For roughly a decade, the prevailing security model has been: trust the developer, harden the platform.
Endpoint security on engineering laptops is usually a thin layer: corporate EDR, maybe a DLP agent, maybe MDM. The real controls live around code review, CI/CD policy, and production access.
That model is over.
The developer endpoint is the highest-privilege, least-monitored node in most environments. It has SSH keys to servers. It has cloud CLI tokens with broad blast radius. It has GitHub credentials with push access to repos that ship to production. It has unencrypted source code.
And increasingly, it is running a fleet of trusted third-party processes the security team has never reviewed.
VS Code extensions are one example. Most developer environments have dozens. Each one runs with the developer's full user-level privilege. Each one can read any file the developer can read.
MCP servers and AI coding agents inherit the same trust model almost verbatim: local execution, broad filesystem visibility, ambient credentials, user-approved outbound network access, and a supply chain most organizations do not inspect.
I run more than thirty MCP servers connected to my own development environment. I built several of them. I trust myself.
I do not, in the strict sense, trust the supply chain of every dependency every one of them pulls in.
Almost nobody does.
The industry adopted AI-assisted developer tooling with the operational rigor of browser extensions, not privileged infrastructure. Convenience won faster than trust modeling caught up.
What mechanical enforcement actually looks like
The fix is not a memo telling developers to be careful. Telling a tired engineer at midnight to audit their extension list is not a control. It is a wish.
The fix is mechanical enforcement that runs whether the developer is paying attention or not.
In my own development setup, that looks like four layers. None of them are clever. All of them are boring.
Boring is the point.
Layer one: pre-commit hooks. Every commit, in every repo, runs a Python scanner before the commit is allowed to complete. The scanner has specific patterns for OpenAI, Anthropic, Google, GitHub, Slack, Discord webhooks, AWS access keys, and a dozen other token shapes, plus raw .env and certificate/private-key file detection. It excludes example and placeholder shapes to keep the false positive rate low. If a real secret is staged, the commit blocks. The hook does not care if the developer noticed.
Layer two: agent hooks. Claude Code and Codex both expose hooks that can fire before file writes and command execution. I run the same scanner against proposed edits. The agent cannot persist a secret to disk through the normal write path, because the hook denies the operation before the write happens.
This catches genuine mistakes, like an agent paraphrasing a .env it read into the next file it writes. It also catches credential reconnaissance. A Bash command that greps for password across the repo or cats an .env is blocked at the tool-call boundary, not at the application layer.
I have actual logs of this firing. During a real OAuth flow earlier this spring, an agent tried to retrieve a shared password by probing the local vault directory, running systemctl cat, and grepping across config files.
Five Bash calls. Five denials.
Each one cited the security policy by name. The correct path was for the user to explicitly authorize retrieval through the canonical vault command, which is exactly what eventually happened.
The hook did its job.
Layer three: .claudeignore. Every repo on my development machine has one. It is the agent equivalent of .gitignore. It prevents the AI tool from loading sensitive paths into context in the first place. The list is uncontroversial: .env* files, certificate and key shapes, raw database files, build output, editor metadata. If the agent never sees the secret, it cannot accidentally leak it into a draft, summary, or commit.
Layer four: a single secrets vault. All real credentials live in AWS Secrets Manager, in a dedicated account, accessed through a single CLI. Application code, agent tools, and CI all pull from the vault at runtime. Source code commits placeholders only. Rotating a credential means updating it in one place. If a secret is ever leaked, it can be rotated globally in seconds, not by tracking down every config file that ever held a copy.
The line in my own security policy doc reads:
Hook failures are security findings, not lint style.
If the mechanical layer catches an actual secret, it is rotated. The hook is not asking for permission to be turned off.
What this does not do
This stack would not have stopped the GitHub compromise.
A poisoned VS Code extension running with the developer's full privilege has its own pathway. It does not need to commit anything. It does not need to call the agent's write path. It can read tokens directly from disk, hit any network endpoint, and exfiltrate immediately.
None of my hooks would see it, because it does not flow through any of my hook points.
That is the honest part. The mechanical layer is defense in depth, not a wall.
What the stack does do is harden the common failure modes: the developer who pastes a real key into a commit, the agent that helpfully echoes a secret back into a file, the credential probe an attacker uses as next-step reconnaissance after initial compromise.
It removes easy mistakes. It logs attempts. It makes privileged paths visible.
The harder problem is the one the GitHub breach is screaming about: the supply chain that delivers third-party code to a developer's local environment has almost no security model.
There is no meaningful review for VS Code extensions beyond "removed after it was reported." There is no meaningful review for MCP servers beyond "trust the maintainer." There is no enforced signing requirement, no provenance attestation requirement, and no runtime sandbox that most teams can rely on.
If you are a security leader, the actionable question is not:
"What did the attackers do to GitHub?"
The actionable question is:
"What is the inventory of third-party processes running with developer privilege in my environment, and what would happen if any single one of them was compromised this afternoon?"
For most organizations, the answer is not encouraging.
What is coming
I expect three things in the next twelve months.
First, the major platforms will harden. GitHub and Microsoft will tighten VS Code extension publishing controls. Anthropic and OpenAI will add provenance signatures to their tool ecosystems. npm and PyPI will likely see at least one more wave before the registry-level changes that need to happen actually happen.
Second, MCP servers will get their first major incident. The trust model is wrong. The attack surface is large. The defender side has barely started. Someone will write a malicious MCP server that behaves like a malicious VS Code extension, and it will run for weeks before anyone notices.
Third, the conversation about endpoint security on engineering laptops will move from "EDR plus a memo" to "your dev environment is a production system." The organizations that get to that mental model first will spend the next eighteen months less expensively than the ones that wait for their own TeamPCP moment.
The Codex Chronicle install I pulled last weekend is a small example of the right reflex. The thing I removed was not malicious. It was a legitimate research preview from a major lab.
I removed it because it had the wrong architecture for what I wanted: a local capability that periodically used recent screen context through a cloud service, a binary I could not audit, and a network path I did not need open.
The replacement runs on hardware I own, in a way I can inspect, without a mandatory outbound dependency.
That architecture choice is what more developer tooling should default to in 2026. Not local because of privacy theater. Local because the trust profile is smaller and the failure modes are more visible.
The cloud round trip should be reserved for cases where the cloud is genuinely necessary, not cases where the vendor wants recurring usage.
The GitHub breach made the security case for that reflex more obvious than any threat model I could have drawn on a whiteboard.
The interesting question is not whether security teams agree with this in principle. Most will, when asked.
The interesting question is whether they have enforcement that runs whether anyone agrees with it or not.
If your developer endpoints are running on policy memos, the next year is going to be expensive.
Top comments (0)