//nefariousplan

Trust Inversion

The tools and credentials that authorize access to your systems are now the attack surface.

Security has a blind spot, and it is the shape of its own assumptions.

When you enumerate attack surface, you draw a line around ports, endpoints, parsers, auth flows. Everything inside the line is the system. Everything outside is the attacker. The things that straddle the line, the authorizers, the signing tools, the maintainer accounts, the package registries, the CI bots, the admin consoles, the AI assistants, those rarely make the surface diagram because they are not the system, they are what lets the system run.

They are also where 2025 and 2026 kept breaking.

Mechanism

The inversion is subtle. Every piece of infrastructure has things it distrusts by default and things it trusts by construction. Distrusted input gets parsed, validated, rate-limited, auth-checked. Trusted input just runs.

The pattern: an attacker moves the attack from the distrusted lane to the trusted lane. Not by breaking validation, but by compromising something further up the chain that was never modeled as hostile. Once they are riding an authorizer, the validation never fires, because the validation was built to stop outsiders and the attacker is now, in the system's view, an insider.

This is not credential theft. Credential theft is stolen credentials used for direct access. Trust inversion is bigger: the attacker captures the thing that confers legitimacy and uses it to ratify attacks across every system that downstream-trusts it. One compromise, N breaches, one for every N that trusted the mechanism.

The authorizers sit in a specific architectural position. They are upstream of the thing being protected. They typically run with broader privilege than the caller. They are deployed once and not rehardened. Nobody maps them. Security teams enumerate ports and endpoints. Nobody enumerates the things that confer legitimacy. That gap is the working surface every trust-inversion incident exploits. The fix is not better validation on the distrusted lane. The fix is recognizing that the trusted lane has an attack surface at all.

Exhibits

The Trust Inversion. The namesake post lays out the shape. Start there if the category is new, then come back for specifics.

Axios, Sapphire Sleet, and 70 Million Weekly Installs. The axios maintainer account was compromised, which meant the next npm publish carried an attacker's code with the maintainer's signature. 70 million weekly downloads downstream, and none of them had authenticated the attacker, because they were authenticating the maintainer. The distrusted lane (a random package) was closed. The trusted lane (the same package you have always used) was wide open.

Bybit: $1.5B via a JavaScript Injection Nobody Was Looking For. The signing surface on the Safe multisig UI displayed one transaction, signed a different one. The cryptographic signature was correct. The signers had reviewed the transaction in the display. The display was the attacker's rendering. The signed bytes were the attacker's payload. One and a half billion dollars, no credential theft, no key exfiltration. The trust boundary lives at the rendering layer, and that is the layer that was poisoned.

tj-actions: Mutable Tags Were Always a Lie. GitHub Actions users reference third-party actions by tag. Tags are mutable. For years the ecosystem treated @v1 as a pinned release. An attacker moved the tag, and every pipeline that imported the action at that tag imported the attacker's code. The thing the ecosystem depended on for immutability was, at the protocol level, mutable by design.

Prompt Injection Is a Supply Chain Attack. Every input to an LLM is interpreted as potential instruction. When the context window contains content from email, a webpage, a PDF, anything the attacker places inside the prompt is, from the model's perspective, coming from the same trusted channel as the user's question. The AI's capability to take your intent and act on it is also the attacker's capability to take the attacker's intent and act on it.

TeamPCP Came for the Scanners. The team's vulnerability scanner was the payload delivery mechanism. A defender's tool, running with defender privileges, reading every repository in the org, became the attacker's read primitive. The scanner is supposed to find attacks. Now it is an attack.

Boundaries

Not every supply-chain attack is trust inversion. If a developer installs a malicious package they chose from a search, that is a naive trust decision, not an inverted mechanism. Trust inversion requires that the mechanism OF trust was itself compromised.

Not every credential theft is trust inversion. An attacker who steals a user's password and reads their email is impersonating. It becomes inversion only when the stolen credentials are used to ratify attacks against the credential-holder's downstream dependents. A compromised npm maintainer unlocks that maintainer's ability to ship to millions. That is inversion. A stolen personal Gmail password does not, unless Gmail happens to be a signing authority for something.

Not every phishing attack is trust inversion. Phishing requires the user to be fooled. Trust inversion often does not touch the user at all. The mechanism that was supposed to shield the user from having to decide is the thing that got compromised. Your signing tool, your scanner, your tag. The user kept doing what they always did. What changed is what the trusted thing said.

Defender playbook

Enumerate your authorizers. Not your systems, the things that authorize actions on your systems. Which accounts can publish. Which tags can move. Which tools run with elevated scope. Which LLM contexts can call tools. Which scanners have read across the org. That is your trust-inversion attack surface.

For each authorizer, ask what happens when it is compromised, not when it fails. Failure models assume the component is honest but broken. Compromise models assume the component is under attacker control and still performing its function. The second is where you find your actual exposure.

Check which of your authorizers use mutable references. Tags, latest, version ranges, dynamic resolution. If the reference is mutable and the thing downstream treats it as pinned, you have the tj-actions shape sitting in your codebase.

Ask what part of your trust chain lives in a user interface that you do not control. Hardware wallet displays, admin dashboards, signing prompts. Whoever controls the rendering controls the signature, regardless of what the cryptography says.

Rate every maintainer account you depend on by blast radius, not by reputation. The question is not whether the person is trustworthy. The question is what happens to you if their account is not the person.

Kinship

Revocation Gap. Trust inversion opens the door; revocation gap determines how long it stays open. The moment a trusted mechanism is compromised, every downstream that still trusts it is being attacked. Detection time and revocation time are the window where damage compounds.

Security Tool As Primitive. A specific shape of trust inversion where the authorizer is a security tool. The defender's hands become the attacker's hands. The mechanism is the same, just applied to tooling built to protect rather than to authorize broadly.

The Detector Is The Target. Sibling of security-tool-as-primitive, applied to detection surface (sandboxes, SOC tooling, scanners). If your detection mechanism has attacker-controlled input, your detector is now part of the attacker's surface.

You did not get breached by an attacker. You got breached by the thing you trust.