Least Privilege for Agents That Move Money
KEY TAKEAWAYS
- 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.
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.
Trust the caller
Enforce at the edge
The four containment patterns that hold
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.
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.
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.
// 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.
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
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 are Integra internal-ops agents. They are a different number from the production agents in the fund platform, and I keep the two separate on purpose, because precision about what an agent actually did is the same discipline as precision about what it is allowed to do.
What containment buys you
So what does this posture actually get you? It lets you 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.
CONTAINMENT CHECKLIST
- 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.
FAQ
Enjoyed this post?
Get more like it in your inbox every Tuesday.
