DEV Community

veto
veto

Posted on

Prompt-level spend limits don't hold: how to actually stop an AI agent from overspending (x402, AP2, and the payment path)

You told the agent: "Don't spend more than $50 on this task."

The agent spent $340.

If you're building on x402, Google AP2, or any rail that lets agents pay autonomously, this isn't a hypothetical. It's an architecture problem, and the fix isn't a better system prompt.


When you put a spend limit in a prompt, you're relying on the model to honor it. That works until it doesn't: a multi-step task where the agent loses context, a tool call that concatenates several individually-small charges, a subagent spawned by the top-level agent that never saw the original instruction, or just a model that decides the task is important enough to override a soft constraint.

Prompt instructions are not enforcement. They're requests.

This distinction matters more now than it did 18 months ago. x402 (the HTTP-402 + stablecoin payment protocol) has settled over $50M across 480,000+ agents. Google AP2 lets agents pay each other autonomously. The surface area for uncontrolled agent spend is real, it's growing, and there's no native policy mechanism baked into either protocol. You are currently shipping agents that can spend money with no hard stop between them and the payment rail.

The payment path is where the limit needs to live. It needs to be in the path that every payment traverses, regardless of which model issued the request, which tool called it, or how many layers of subagents the chain involved. That's not the prompt. This is the same insight that makes RBAC work for databases. You don't enforce access control by asking the application to be polite. The control has to be structural, not instructional.

An enforcement layer at the payment level intercepts the transaction before the rail executes it, checks it against policy, and either approves, denies, or escalates. The agent can't bypass this by ignoring a prompt constraint, because the constraint isn't in the prompt.


Veto is built around this model. It sits between an agent and the money it's about to spend across any agent, any payment rail. A few things that matter technically:

  • Mandates, not promises. Rather than trusting that an agent intends to stay within budget, Veto uses mandates — explicit buyer-side authorizations ("may my agent spend $X?"). These are signed artifacts, not prompts. They're cryptographically issued, and the merchant side can verify them locally at zero latency before any capture happens.
  • A fixed enforcement order. The Acceptance Gate runs in a fixed sequence before any payment executes: verify mandate, check replay, evaluate reputation, run policy. The docs are explicit about why the order matters: "The order is the chargeback defense." And: "The rail only ever executes a spend the gate already approved." There's no shortcut, no layer an agent can skip.
  • Rail-agnostic. The policy engine sits above the settlement layer. x402 is the primary rail, but the architecture is pluggable (mock for offline testing, card as a future stub). One policy surface covers whichever rail you're using — "one policy, one audit surface, every rail."
  • Signed receipts. Every approved transaction produces a merchant-signed artifact linking back to the buyer's mandate. The dispute trail is created at the moment of transaction, not reconstructed from logs after the fact.
  • Non-custodial. Veto never holds funds. You bring your own receiving address.

If you're using Claude Code with payment-capable tools, Veto ships a PreToolUse hook that intercepts payment-shaped tool calls before they run — transfers, sends, swaps, cast send, solana transfer, x-payment / HTTP-402 flows, Stripe calls. The hook queries Veto for allow / deny / escalate before the tool executes.

That's the right abstraction. By the time the agent has decided to spend money and is calling the tool, no amount of system-prompt hedging is relevant. The firewall either lets it through or it doesn't. Slash commands (/veto:authorize, /veto:receipts, /veto:policy) give you inspection and override directly in the workflow.


If you're building an agent that spends money — API calls, onchain transactions, anything on x402 or AP2 — there's one question prompt engineering can't answer: what actually stops the agent from exceeding its authorization?

If your spend limit is only in the prompt, it's not a limit. It's a suggestion.

Top comments (0)