SKIP TO CONTENT
AI AGENTS6 minAgents in Production / Ep. 4 · Stage 4-1

AI Agents That Move Money: How to Limit What They Can Do

Hidden text in one invoice can tell an AI agent to pay a stranger. What stops the payment when the agent obeys?

XIN
Pixel-art illustration of a robot inside a tight glowing containment ring reaching toward a money-transfer rail blocked behind a raised gate.

IN 30 SECONDS

Least privilege is giving an AI agent only the access its current task needs, and nothing more. No filter reliably stops hidden text that tricks an agent, so the permission check has to sit outside the agent, where the money moves.

KEY TAKEAWAYS · 3

  • Treat prompt injection as an ongoing threat: a filter makes an attack harder without proving it fails.
  • Enforce permissions outside the model, at the account, the API or the payment service, so a compromised agent has limited authority.
  • The model is the one ERC-3643 already runs: on ordinary transfers the token, not the caller, enforces permission at the moment value moves. I am one of its five named authors.
On this page

No fool-proof fix for prompt injection

IN SHORT Most defenses so far are filters, and a filter makes an attack harder without proving it fails.

So design for Prompt injection Text hidden in something the agent reads, like an email or a web page, that tries to give it new orders. See the glossary as an ongoing risk. Still run a filter, but pair it with permissions enforced outside the model, and test both.

A filter is worth having, but not worth betting a fund on.

I’d enforce Least privilege Giving an agent only the access its current task needs, for as long as the task runs, and nothing more. See the glossary at the account, the API (the interface other software calls) and the resource. Then a manipulated model can’t simply choose to skip the checks.

Treat the agent as possibly compromised, and define and test the authority it can reach. That is what I mean by Containment Limits set outside the agent, so that even a tricked agent can only reach what it was granted. See the glossary.

TWO DESIGNS

Trust the caller

The agent, as the caller, is supposed to run the permission check before it acts. A hijacked agent skips it, or argues past it. The gate is only as honest as the caller.

Enforce at the edge

The payment service should enforce the allowed scope itself, whatever the agent asks for. Both this and ERC-3643’s token checks depend on secure administration and a correct implementation.
Illustrative: the same agent in two designs. Only the second still holds once the agent is hijacked.

I didn’t come to this from AI security. I came from 10+ years in Web3, where my work included writing transfer rules in smart contracts, the programs that run on a blockchain.

ERC-3643 is a standard for tokens, digital assets kept on a blockchain. Its whole job is to refuse a transfer the caller isn’t allowed to make.

Coming up next: So what does a contained agent look like in everyday terms?

Words to know

IN SHORT A contractor’s one-day office badge already works the way a contained agent should.

WORDS TO KNOW

Prompt injection
Text hidden in something the agent reads, like an email or a web page, that tries to give it new orders.
Least privilege
Giving an agent only the access its current task needs, for as long as the task runs, and nothing more.
Containment
Limits set outside the agent, so that even a tricked agent can only reach what it was granted.

ADAM says: The badge opens only today’s rooms and stops working at 6 pm. Where it breaks: a contractor can ask before obeying a strange email; an agent may just follow hidden text, at machine speed.

That gap sets the design rule: the doors, not the agent, have to say no.

IN PLAIN WORDS

You stop asking whether the agent will behave. You ask what it can touch if it doesn’t, and you make that list short.

Coming up next: So where exactly should the door sit?

Enforce permission at the edge, not in the caller

IN SHORT Put the check where the action happens, so the caller can’t avoid it.

Token design taught me this. In a naive token, compliance is a check the calling app is supposed to run before a transfer.

Then one app forgets it, or an attacker calls the transfer directly. An ineligible holder lands on the cap table, the register of who owns the token. The check existed, but nothing forced it to run.

STEP BY STEP

Flow diagram: 4 stepsFlow diagram: 4 steps. An untrusted caller asks for a transfer, then The transfer function runs, whoever called it. The transfer function runs, whoever called it, then The token asks the identity registry. The token asks the identity registry, then Eligible and other checks pass: it settles.1An untrusted caller asksfor a transferA forgotten integration, anattacker, or a prompt-injectedagent. The token doesn’t knowwhich, and doesn’t need to.2The transfer functionruns, whoever called itOrdinary transfers run thetoken’s checks. Privilegedoperations and administratorsneed separate review.3The token asks theidentity registryIs this receiver eligible?The answer comes fromon-chain identity, not fromthe caller.4Eligible and other checkspass: it settles
An on-chain list of verified holders, kept on the blockchain.

Step 1. A request arrives. Someone asks the token to move. It could be a trusted app, a buggy one, an attacker or a hijacked agent.

Pick a step to see it move
  1. A request arrives Someone asks the token to move. It could be a trusted app, a buggy one, an attacker or a hijacked agent.
  2. The checks run anyway An ordinary transfer runs the token’s own checks, whoever called it. The caller can’t switch them off.
  3. Not eligible: it reverts The registry says the receiver isn’t eligible. To revert means the transfer is cancelled and no tokens move.
  4. Eligible: it settles A verified receiver and passing checks: the transfer goes through. What the caller wanted never entered the decision.
One ordinary ERC-3643 transfer. Privileged operations, like forced transfers, follow their own rules and need separate review.

ERC-3643 puts checks inside ordinary transfers. It also has privileged operations, such as forced transfers, so the admins and the identity registry are part of what you have to trust.

An agent hit by Prompt injection Text hidden in something the agent reads, like an email or a web page, that tries to give it new orders. See the glossary is exactly that untrusted caller. If your security depends on the agent choosing to run the check, injection removes the choice.

ITEM GET

Move the check to the edge

The account, the payment rail that actually moves the money, or the resource refuses what the agent isn’t allowed to do, whatever it was talked into asking.

For the on-chain original, see how ERC-3643 enforces permission at transfer time, inside the token itself.

STAGE CLEAR

What you now know

  • Why a filter alone can’t protect an agent that touches money.
  • Why you ask what an agent can touch, not whether it will behave.
  • Why the check belongs where the action happens, not in the caller.

Check yourself

Tap or click a question to see the answer.

Illustrative case: one agent key can both draft and send payments, and a filter catches most injection attempts. Is the agent contained?

No. The one attempt the filter misses can send money, because nothing outside the model stops it. Contained means a missed attempt still can’t move money, because the payment system decides, not the agent.

Next stage:Which controls contain a payment agent, and which actions must a person sign?6 min
Adam Boudjemaa
Adam Boudjemaa

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.

Have a project to ship or a role to fill?

Discuss your project or role
Follow the engineering notes

Get new articles on production AI and smart contracts by email.