Agentjacking: hijacking AI coding agents via poisoned Sentry error events
# The tool boundary is the new attack surface
The agentjacking write-up from Tenet Security is the honest post-mortem I have been waiting for.
The mechanic is simple. A Sentry DSN, the write-only key you embed in your web app's frontend so the client can report errors, is a public credential by design. An attacker who can find a target's DSN, which is trivial, can send an arbitrary error event to Sentry's ingest endpoint via a POST. If the payload is crafted so its message field looks like a legitimate Sentry system template, and if the target's developers use an MCP-connected AI coding agent to triage their Sentry queue, the agent will read the poisoned event, render it as trusted content, and execute the attacker's commands with the developer's own privileges.
Tenet tested this in a controlled setting against over one hundred organisations. The attack worked 85% of the time against widely deployed agents, including Claude Code, Cursor, and Codex. In a broader scan, they identified 2,388 organisations with valid injectable DSNs. That is the number that tells you whether the problem is a subtle configuration bug or a category-level failure. In this case, category.
Three things stood out.
First, the attack surface is not the model. It is the tool. Over the last two years, most of the serious jailbreak research has focused on user turns, on how a user can trick a model into breaking a policy. Agentjacking is the pivot. The interesting failure mode is now the tool response. Data that flows into the agent's context wearing the visual clothes of a trusted system can carry new instructions, and the agent, following the plainest reading of its context, will act on them. If your agent renders tool output as markdown, and if any tool it calls can return user-controllable strings, you have a prompt injection channel and you probably do not know it. The tool boundary, the point at which authority meets attacker-controlled data, is where post-mortems will keep landing.
Second, this is what an agent post-mortem should look like. Concrete, reproducible, ranged, pinned to a specific privilege boundary. The number 85% is interesting; the number 2,388 is decisive. When you are triaging a class of vulnerability, the fraction of affected systems is the metric that argues for category-level intervention rather than one-off patches. I would like to see this format become the norm. A write-up that starts from a specific credential, walks through the ingest path, quantifies exposure, and names the trust boundary that needs to move.
Third, Sentry's response is correct and honest in a way I want to praise. Their leadership acknowledged the issue the same day it was reported and then declined to fix it at the DSN layer, because the DSN is a public credential by design. That is the right call. If a public credential can carry an attacker payload into a downstream agent, the problem is not with the credential; it is with the agent's trust boundary. Too many disclosures in the last two years have ended with a reporting vendor patching around the real problem and everyone walking away agreeing the class is closed. The right fix here is at the MCP client, the agent code that reads Sentry, and Sentry's refusal to pretend otherwise is a service to the field.
What I would change this quarter if I were shipping an MCP client.
Treat tool responses as untrusted input. Render them as plaintext, not markdown, until you have a story for how markdown from a tool cannot smuggle a new instruction into the model's context.
Put a policy layer between the agent and any tool that can return user-controllable strings. This is the same shape as the spend-approval gates most serious agent teams already run. If you have Hiveclaw-style approvals for money, you should have Hiveclaw-style approvals for shell execution triggered by tool output. It is the same pattern applied to a different resource.
Log the raw tool payload alongside the model's next action, on a retention window long enough for a real security team to reconstruct causality. Post-mortems are impossible without this. Most teams still do not capture full agent traces by default, and the ones that do usually drop the raw tool payload for storage reasons. That is the wrong economy to be optimising.
Build a canary tool. One tool under management, deployed to the same MCP endpoint as the real ones, that intentionally returns a well-known suspicious string. Alert if any agent ever executes anything after receiving it. This is a red-team primitive I want in every serious agent runtime. It is a cheap check that lights up the moment your trust boundary starts leaking.
There is a deeper point. The interesting boundary in an agentic system is not the model boundary and it is not the API boundary. It is the tool boundary. That is where authority meets attacker-controlled data. If your risk register still lists 'jailbreak' as the top model risk and does not list 'malicious tool response' as a peer, update it this week.
Two closing observations.
The attack is not novel. It is a straight-line application of prompt-injection theory to a real tool with a real deployment count. The theory has been mature for two years. The tooling and the number of exposed organisations were the missing piece, and now they are here. The lesson to draw is not that we did not know; it is that we did not act.
The industry response I want to see is a shared, versioned specification for how tool responses become model context, with defaults that assume the response is hostile. The response I do not want to see is each MCP client patching Sentry in isolation. If you are on an MCP-client team, I would love to read your write-up.
I was wrong about how long it would take for a serious agent incident to have a legible post-mortem in public. I thought we would spend another year on breathless disclosures with no numbers. Tenet's write-up shows the format works when someone bothers to do it. I would rather see more of these than another sprint of capability announcements.