Inspiration

PayPal's Agent Toolkit and MCP server let an AI agent run a small business's payments: refunds, payouts, invoices, disputes. That's exactly the work owners want to hand off. But the agent reads customer emails, supplier invoices and web pages all day, and any of that text can try to give it orders. Payment-redirect scams (business email compromise) cost US businesses about $3.05 billion in 2025 (FBI IC3), and prompt injection is the top risk on OWASP's LLM list. A spending limit alone doesn't help either: an agent allowed to refund $50 at a time can refund $45 four times.

Today the choice is to hand the agent full API credentials, or keep a human in every loop. We wanted a middle ground: say yes to agents without giving them a blank cheque.

What it does

Warden is a firewall between any AI agent and PayPal. It exposes PayPal-style tools (create_refund, create_payout, cancel_sent_invoice, …) over MCP and REST, so an existing agent only needs a different URL.

The owner writes a mandate in plain English: "Refund customers up to $50 on your own; anything bigger, ask me. Pay our contractors up to $400 each. Never pay anyone new without asking me. No single payment over $500." Every tool call is then checked against five layers:

  1. The signed mandate: scope, caps, budget, trusted payees, velocity.
  2. Live PayPal facts: does the capture exist, how much is still refundable, is it under dispute?
  3. Provenance: where did this payee first appear? Everything the agent reads is tracked as untrusted. A payee that only appears in an email is tainted, a lookalike of a trusted payee is a redirect scam, and hidden text quarantines the session.
  4. Composition rules across calls: split payments, cancelling records right after moving money, scanning transactions then paying someone new.
  5. A Gemini intent check: would the owner want this exact action?

Three outcomes: allowed actions run on PayPal, held actions go to the owner's phone and run when they tap Approve, and blocked actions never reach PayPal. Every decision lands in a hash-chained, tamper-evident ledger shown live in an AG Grid dashboard, and signed PayPal webhooks mark payments as settled.

The demo is a fictional shop, Kestrel & Co., whose support inbox has six emails: a routine refund, a "we changed banks" payment-redirect scam, a customer email with hidden white-text instructions, a refund over the limit, a request to split a refund into small pieces, and a dispute answered with tracking evidence. All six run against the real PayPal sandbox.

How we built it

  • Backend: Python and FastAPI. A PayPal REST client covers Payments v2 (captures and refunds), Orders v2 (including shipment tracking), Payouts v1, Invoicing v2, Disputes v1 (including multipart evidence upload), Transaction Search and webhook signature verification. An offline simulator returns the same response shapes, so anyone can run it with no keys.
  • MCP: a Streamable HTTP server, tested with the official MCP Python SDK.
  • AI: Gemini compiles the mandate (cross-checked by a deterministic parser, where the stricter value always wins), runs the intent check, explains decisions in plain words, drafts dispute evidence, and powers a live function-calling demo agent. Gemini can only make a decision stricter, never looser. Every hard rule works with no API key.
  • Frontend: React and AG Grid, with a decision trace that reveals the hidden text the agent read, and a mobile approval page wired to ntfy push notifications.
  • Deploy: one Docker image on Render, running against the PayPal sandbox. "Reset demo" creates fresh sandbox payments with a test card, so every visitor gets a clean run.
  • Tests: 55 automated tests covering every scenario, the MCP protocol, PayPal request shapes and the Gemini paths, run in random order.

Challenges we ran into

  • Telling a harmless id from an attacker's payee in the same email. Warden weighs arguments by role: a refund can only go back to the original payer, so an order number from an email is low risk, while a payout address from an email is critical.
  • Attacks made of individually allowed steps. Four $45 refunds each pass a $50 limit. That led to the composition rules.
  • Keeping the model useful without letting it weaken policy. Gemini once read "$400 each" for a contractor as a cap on every payment. The stricter-wins merge kept it safe, and we tightened the prompt so it reads the mandate correctly.
  • Real PayPal behaves differently from the docs. Captures don't report refunded amounts, so we read them from the order. The dispute list can lag a new dispute by minutes. Sandbox accounts must be US-based for USD payments. Each one surfaced only when testing against the live sandbox.
  • Running on Gemini's free tier. At most one Gemini call per payment, a response cache, hard timeouts, and a daily cap. If Gemini is unavailable, Warden says so and keeps enforcing every rule.

Accomplishments that we're proud of

  • A hidden prompt injection and a payment-redirect scam are both blocked before reaching PayPal, while routine refunds and dispute responses still run without a human.
  • A real model falls for it too. The live Gemini agent paid the lookalike address in the scam email, and Warden blocked it. Some models resist these tricks; Warden doesn't rely on them resisting.
  • All six scenarios verified end to end on the real PayPal sandbox, including phone approvals and settlement webhooks.
  • One-line integration for any MCP agent.

What we learned

Payment safety for agents is mostly about provenance: knowing who asked for a payment matters more than how big it is. And an LLM is a good extra pair of eyes, but the rules that protect money have to work without it.

What's next for Warden: a PayPal firewall for AI agents

Per-agent mandates for teams, Payouts batch limits, and buyer-side agentic checkout (Orders v2 with vaulted payment methods) under the same policy engine.

Built With

Share this project:

Updates

Submission history