Identity & access · · 6 min read
The lethal trifecta: where it actually lives
Untrusted inputs + private data access + outbound communication. The framing names the risk space correctly; the standard mitigation pattern picks the wrong layer.
Mid-2026 industry conversations named a pattern the lethal trifecta. In the framing's authors' view, an agent that has all three of these properties at once is exposed to a class of attacks that no single defense layer can fully prevent:
- Untrusted inputs. The agent reads content it does not control: user prompts, tool outputs, web pages, ticket bodies, customer documents.
- Private data access. The agent has authority to reach data the operator behind it would not want exposed: tenant tables, internal documents, customer records, source code.
- Outbound communication. The agent can act in a way that leaves the system: API calls, network requests, file writes that other systems read, message sends.
Security blogs and incident-response writing picked up the framing through the first half of 2026 (Airia blog). The combination is what makes catastrophic incidents possible. The defense most often paired with it sits at the wrong enforcement layer.
Why the three together are the problem#
Each leg is old. Programs have always processed untrusted input, had access to private data, and sent messages to other systems. A static program with all three legs still does only what its code does, every run. An agent in the same configuration does what the model decides at runtime, and code review does not constrain that decision. The model's decisions are conditioned on the input.
The classic attack:
- An attacker inserts an instruction into content the agent will read: a ticket, a document, a webhook payload.
- The instruction asks the agent to do something with the private data it can reach, then send the result somewhere the attacker can receive it.
- The agent reads the content, interprets the instruction, accesses the data (it has authority), builds the outbound message (it has authority), and sends it.
From the SIEM's perspective, every step was an authorized action by the agent's service identity. The breach is invisible at the action layer.
The standard mitigation pattern#
The standard response layers model-side defenses: a prompt-injection classifier on inputs, a content classifier on outputs, an instruction-following monitor on the model. The intuition is that if the model interprets untrusted text as an instruction, the defense should sit at the model.
That works for a narrow band of attacks where the instruction is recognizable as malicious. It fails on three broader classes.
- The attack does not look malicious. A legitimate-sounding instruction in a ticket produces the same outcome, and the classifier has no anomaly to detect.
- No injection is needed. In the cross-tenant reach incident class, where agents read data they were never scoped to, there is usually no injection. The agent decides on its own that reading the adjacent data is the right thing to do.
- The classifier sits at the wrong altitude. Whether a tool call is authorized is a question for the identity layer. A model-side classifier that says "don't do this" can be ignored by the same model on the next turn. An identity-layer denial cannot.
Where each leg has to be controlled#
Each leg has its own enforcement layer.
Untrusted inputs. Enforcement sits upstream of the model, in input provenance and trust labeling. The runtime tracks which parts of the context window came from which source (the operator's prompt, retrieved documents, tool outputs) and carries that provenance into downstream decisions, so a sensitive action is weighed together with the input class that provoked it. Simon Willison and others have written about this as "trust-tracking", and in 2026 it is becoming standard in mature agent stacks.
Private data access. Enforcement sits at the identity layer. The agent's identity for the run carries the scope it is allowed to access, and the policy gate refuses requests outside it. If the agent is helping customer A, the gate refuses reads of customer B's data because the identity is not scoped to it, whatever the model intends.
Outbound communication. Enforcement sits at the egress layer: an allowlist of destinations the agent can reach, with a separate policy for outbound payloads. A model induced to build an exfiltration payload still cannot send it when the destination is not on the allowlist. The egress check sees the destination directly, while the model's self-restraint can be talked out of refusing.
Where the trifecta lives in your architecture#
The three legs are enforced at three different layers, each with its own latency budget and observability.
- Input provenance lives in the orchestrator, the layer that builds the context window from operator input, retrieved documents, and tool outputs. Tracking is cheap because the runtime knows where each chunk came from. The cost is design discipline: prompt-construction code has to propagate provenance instead of flattening everything into one block.
- Identity-scoped access control lives in the policy gate. The latency budget is the per-action evaluation cost (Microsoft Agent OS targets sub-millisecond). Observability is the audit log: every refused and every allowed action is a row the security team can query.
- Egress control lives in the network layer or in an MCP gateway that intercepts outbound tool calls. The latency budget is per egress. Observability is the network log plus the audit row recording what the agent tried to send.
The model-side classifier is a fourth layer, useful as defense in depth and never the load-bearing one.
A 2026 incident#
In March 2026, public reporting documented a financial services company whose customer-facing AI agent had leaked internal pricing data for three weeks before discovery (Aimagicx blog). The attacker had inserted a carefully worded question that caused the agent to expose data it had access to.
The incident maps cleanly to the trifecta. The untrusted input was the attacker's question, the private data access was the agent's authority over pricing data, and the outbound communication was the agent's responses returning to the attacker.
The standard-mitigation framing says a model-side classifier should have recognized the question as adversarial. That layer was absent or did not fire.
The layered framing finds the missing defense at the identity layer. The agent's service identity could read internal pricing because the integration was built around "the agent can answer questions about pricing." The identity was not scoped to which prices a given customer is allowed to see, so the gate had nothing to deny on a question that looked legitimate. The fix is an identity scope the gate can evaluate without relying on the model's self-restraint.
What this means for runtime design#
The framing names a combination that would otherwise be analyzed as three separate problems. Accepting it without checking where each leg is enforced sends defensive investment to the wrong layer.
A runtime that takes the framing seriously has three things:
- Input provenance threaded through the agent's context, so the orchestrator can pass it to the policy gate.
- A policy gate that scopes data access by run, with the operator's identity as the source of truth for what the agent is allowed to reach.
- An egress layer that allowlists destinations and inspects outbound payloads against the scope.
None of the three is the model. Each is runtime infrastructure evaluated before or alongside whatever the model decides to do.
For calls routed through Deixic, policy and approval apply at the action, and identity and results are recorded in a tamper-evident history. Egress allowlisting and input provenance remain in the buyer's stack. See What you can do for the approval and policy surfaces.