◆Prompt injection is not going to be solved. The engineering bet that pays off is containment: assume the agent is compromised and cap the blast radius.
◆The containment model is the one ERC-3643 already runs: the token, not the caller, enforces permission at the moment value moves. I am one of its five named authors.
◆Least privilege for a money-moving agent is four patterns together: capability scoping, ephemeral credentials, human sign-off on value, and an immutable audit trail.
◆A person signs before money leaves. Injection can propose a payment; it must never be able to execute one.
10+10+
YEARS OF TRANSFER-ELIGIBILITY LOGIC
writing on-chain permission code
55
NAMED AUTHORS OF ERC-3643
I am one of the five
Prompt injection is not going to be solved
Prompt injection is not going to be solved, so stop designing as if it will be. The move that actually holds is containment: assume the agent can be turned against you, and make sure the worst it can do is small. For agents that move money, that means least privilege, enforced by the resource, not requested from the agent.
I did not arrive at this from the AI-security side. I arrived at it from ten years of writing transfer-eligibility logic in smart contracts, and from co-authoring ERC-3643, a token standard whose entire job is to refuse a transfer the caller is not allowed to make. The containment model the agent-security field is now reinventing is the one that standard has run in production for years.
Enforce permission at the edge, not the caller
Here is the analogy that reframes the whole problem for me. In a naive token, compliance is a check the calling code is supposed to run before it transfers. A trusted front end calls it, the transfer goes through, everyone is happy. Then one integration forgets the check, or an attacker calls the transfer function directly, and an ineligible holder is on the cap table. The check existed. Nothing forced it to run.
ERC-3643 makes a different bet. The token transfer function asks an on-chain identity registry whether the receiver is eligible, and reverts if not. There is no path around the check, because it lives inside the function everyone has to call. You cannot forget it, and you cannot call around it.
A prompt-injected agent is exactly the untrusted caller from that story. If your security depends on the agent choosing to run the check, injection removes the choice. So you move the check to the edge: the account, the payment rail, the resource itself refuses an action the agent is not authorized to take, whatever the agent was talked into asking for.
ENFORCEMENT PATH
The check is not something the caller runs, it is something the caller cannot avoid. Swap the token for a payment rail and the caller for your agent, and the same shape contains an injected one.
Trust the caller
The permission check is something the agent is supposed to run before it acts. A hijacked agent simply does not run it, or argues its way past it. The gate is only as honest as the caller, and the caller is the thing you just lost control of.
Enforce at the edge
The resource refuses the action itself. In ERC-3643 the transfer reverts when the receiver is not eligible, no matter who asked. For an agent, the payment rail declines a transfer outside the agent scope, no matter what the prompt said. The check does not depend on the caller behaving.
Least privilege for a money-moving agent is not one control. It is four, and they only work together. Each one assumes the layer above it failed.
DEFENSE IN DEPTH
Four layers, each assuming the one above it already fell. Least privilege caps what a hijacked agent holds, ephemeral credentials expire a stolen token, human approval gates every value move, and the audit trail proves what happened when the first three were not enough.
Pattern
What it contains
What it costs you
Capability scoping
A hijacked agent can only reach what its task was granted. It was never handed the keys to the rest.
You define per-task scopes instead of one standing credential.
Ephemeral credentials
A stolen token is expired by the time it is exfiltrated. Credentials are minted per task and die in minutes.
Short-lived issuance and rotation, instead of a durable secret in an env var.
Human sign-off on value
Injection can propose a payment. It cannot execute one. A person signs the irreversible step.
Latency, and a human in the loop for anything that moves money.
Immutable audit trail
You can prove after the fact what moved, who approved it, and why, even against an agent that lies about it.
Write-once storage and the discipline to log intent, not just outcome.
What a money-moving agent must never do alone
The single most important line to draw is which actions an agent is never allowed to complete on its own. Not because the agent is dumb, but because these actions are irreversible or grant power, and those are exactly the ones injection aims at.
On-chain I learned this the blunt way: a transfer is final. There is no support ticket that un-sends it. So the design question is never 'can the agent do this,' it is 'what happens on the day the agent is wrong, and can anyone undo it.' If the answer is no, a human signs.
THE LINE
Three of the four branches end at a human. Not because those actions are hard, but because nobody can undo them. The agent still proposes every one, with full context and a recommendation.
APPROVAL FLOW
The injection reaches step one and stops. Every value-moving step past "propose" needs a human signature the agent never holds, so a hijacked agent can file a payment but never settle one.
This is also where liability lives. When an autonomous agent pays, someone has to be accountable for the signature, and that is a hard problem on its own.
Why the audit trail has to be immutable
When people hear "audit trail" they picture a log file. In regulated finance it is closer to evidence. If an agent moved money, you have to be able to show, later, exactly what it did, on whose approval, and why, to an auditor who assumes bad faith. A log the agent could quietly edit is worth nothing in that room.
So the audit trail has to be append-only and tamper-evident. Here is the shape I use: every action becomes one record, and each record carries the hash of the one before it.
audit-entry.ts
// One money-moving action, one append-only record.// prevHash chains each entry to the last, so editing any// past entry breaks every hash after it.interface AuditEntry { seq: number actor: string // which agent, under which task-scoped identity action: 'propose' | 'approve' | 'execute' | 'abstain' intent: string // what it meant to do, in its own words target: string // the account, contract, or rail it touched amount?: string // value at risk, when money moves approver?: string // the human who signed a value-moving step ts: string // ISO-8601, from a trusted clock prevHash: string // hash of the previous entry hash: string // hash(this record + prevHash)}// The agent can append to the log. It cannot rewrite it.// A value-moving action with no approver is not a bug to// clean up later. It is an incident.
The field that matters is not amount, it is prevHash. Chain each entry to the last and any silent edit to history breaks every hash after it, so tampering is detectable without trusting whoever holds the log. The agent is allowed to append. It is not allowed to rewrite.
TAMPER EVIDENCE
Tampering is not prevented here, it is made loud. One quiet edit invalidates every record that came after it, which is why prevHash is the field that carries the weight.
This is where the smart-contract background stops being an analogy and becomes the actual mechanism. On-chain, append-only and tamper-evident are not features you implement, they are what a ledger is. ERC-3643 leans on exactly that: the transfer and the reason it was permitted are both permanent, and no caller can pretend afterward that the rule was different. Off-chain audit trails are trying to buy back that property in ordinary infrastructure.
What I have actually run in production
4646
AI AGENTS, INTEGRA INTERNAL OPS
a past role, not the fund platform
None of this is theory I read. I have run agents in production under exactly these constraints, and I have spent real effort trying to break my own.
At Ilayer I built the regulated-fund agent platform and red-teamed it myself, deliberately feeding the agents inputs designed to make them act outside their scope, because "it behaved in the demo" is not a security argument. At Integra, where I was CTO until that role ended in 2026, I deployed roughly 46 AI agents for internal operations. Those 46 were Integra internal-ops agents, a deliberately separate count from the production agents in the fund platform. Precision about what an agent did is the same discipline as precision about what it is allowed to do.
RED-TEAM LOOP
Red-teaming your own agent tests the containment, not the model. If the rail refuses a hostile prompt, the injection you never thought of is survivable too.
Red-teaming my own agents is the same instinct as the eval suite that gates a release: you do not ship on the demo, you ship on the evidence.
What containment buys you
This posture buys you one thing: you can put agents next to money without betting the company on a research problem staying solved. You stop needing prompt injection to be beaten. You need it to be survivable.
That is a very different procurement conversation. "Our agent cannot be injected" is a claim no honest engineer can make. "A compromised agent reaches four scoped permissions, cannot move money without a human, and leaves a tamper-evident trail" is a claim you can actually stand behind, and defend to an auditor.
Every agent runs on a task-scoped identity, never a standing all-powerful credential.
Credentials are short-lived and minted per task, not stored long-term.
No value moves, and no permission widens, without a human signature.
Every action is appended to a tamper-evident, hash-chained log.
You have red-teamed your own agents before an attacker does.
Start at the money. Find every path an agent has to move value or change who can, and put a human signature in front of each one first, before you refactor anything else. That single step converts your worst case from "an injected agent drains an account" to "an injected agent files a proposal a human rejects." Scoping and ephemeral credentials matter, but they reduce blast radius. Human sign-off on value is the one that caps the absolute downside, so it goes in first.
FAQ
No. Every defense today, input filtering, delimiters, classifier models, raises the cost of an attack without proving attacks fail. Treat them as useful, not sufficient. The engineering that survives being wrong about a filter is containment: assume the agent can be compromised and make sure a compromised one reaches almost nothing.
The agent holds only the permissions its current task needs, for as long as the task runs, and no more. A hijacked agent then cannot reach what it was never granted. In practice that is task-scoped identities plus short-lived, per-task credentials, instead of one long-lived key the agent carries everywhere.
Because ERC-3643 already solved the structural version of this problem. It enforces permission at the resource, not at the caller: the token transfer function checks eligibility and reverts, so an untrusted caller cannot force a move. A prompt-injected agent is that untrusted caller. I co-authored the standard, so this is the pattern I reach for first.
It helps and you should run one, but it is still a filter, and filters have a false-negative rate you cannot drive to zero. If the only thing standing between an injected prompt and a wire transfer is a classifier, one miss moves money. Containment means the miss still cannot execute the payment, because the payment needed a human signature the injection never had.
The irreversible and the power-granting steps: sending funds, changing an allowlist or identity claim, raising a spending limit, granting another agent a capability, or editing the audit config. The agent can propose any of these with full context. A person approves the ones that actually move value or widen access.
Former CTO of Integra. Named author (1 of 5) of ERC-3643, first author of ERC-6960, co-author of ERC-7410, and co-author of ERC-8203, which is still a draft. Building production AI and regulated Web3 systems.