Rightshold™ Sign up

Answers · agent payments

How do I require human approval before an AI agent spends money?

Last updated

TL;DR: Put the approval in code the model can't skip, at the point where money moves, not in the prompt. Make every tool that pays, buys, signs a payment or calls a paid API pause and ask a person first: in the OpenAI Agents SDK set needsApproval on that tool, in LangGraph call interrupt() before the payment, and in an MCP client keep confirmation prompts on for tool calls (the MCP spec says a human SHOULD be able to deny tool invocations). Show the person the exact merchant, amount, currency and payee, bind their yes to those details (for example a hash of them), and refuse to pay if anything changed after approval. Add hard limits below the approval step: a per-purchase and daily cap, an allowed-merchant list, and short-lived credentials. Card issuers such as Stripe Issuing enforce limits like these before authorization, and its real-time authorization webhook gives you only 2 seconds to answer, so a person can't approve inside that window; get the approval before the agent starts the purchase.

What should I check, step by step?

1. List every tool that can move money: card or wallet payments, x402 or other pay-per-call APIs, checkout, refunds, invoices, transfers, and anything that buys credits. Treat signing a payment authorization as spending.

  1. Make each of those tools require approval in code: needsApproval: true (or a function) in the OpenAI Agents SDK, interrupt() placed before the payment call in LangGraph, a permission rule or hook in your coding agent, confirmation prompts left on in your MCP client.
  2. Show the approver the facts, not the agent's summary: merchant or payTo address, amount with currency and decimals, network (mainnet or testnet), what is being bought, and whether the price is a ceiling (x402 upto) or exact.
  3. Bind the approval to those facts: hash the canonical JSON of the purchase and check the hash again right before paying. If the amount, payee or item changed, ask again.
  4. Give approvals a short expiry and make them single-use, so an old yes can't be replayed for a second purchase.
  5. Set limits that hold even if approval is skipped or wrong: per-transaction and daily caps, allowed merchants or categories, and a card or wallet that only holds what the agent may spend.
  6. Decide what runs without a person (small, allow-listed, under a cap) and what always needs one, and write it down. AP2 calls the unattended case 'human not present' and requires the user to confirm the conditions up front.
  7. Keep a record of who approved what and when, and make the payment step idempotent so a resumed or retried run doesn't pay twice.

Where the approval has to live

A line in the system prompt saying 'ask before buying' is a request to the model, not a control. Text the agent reads from web pages, emails or tool results can talk it out of asking. Put the check in the tool runner, where the model's output can't remove it.

Approval plus limits, not approval alone

People approve quickly when asked often, so pair approval with limits that don't depend on attention. Stripe Issuing spending controls can block merchant categories and countries and set spending_limits per authorization or over an interval such as weekly or monthly (date-based intervals start at midnight UTC); if you set none, a new card gets a default limit of 500 USD per day.

What can go wrong?

The approval screen shows the agent's description instead of the real payee and amount. Read them from the payment request itself.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Before you pay for this, ask me to approve the exact purchase (merchant, amount, currency and what it's for) and wait for my yes or no.”

One-click setup

{
  "tool": "request_human_approval",
  "arguments": {
    "summary": "Buy 1 month of the Pro API plan from api.example.com for 20.00 USD.",
    "action": {
      "type": "purchase",
      "merchant_domain": "api.example.com",
      "amount_minor": 2000,
      "currency": "USD",
      "item": "pro-plan-1-month"
    },
    "expires_in_minutes": 30
  }
}

Rightshold records approval requests, your signed decisions and spending-limit checks. It doesn't hold funds, make or block payments, or stop an agent that never asks. Enforce the check in your tool runner, wallet or card controls.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'