Inspiration
AI agents can now move money. That creates a new attack: a web page, an invoice or an email can hide an instruction that redirects the agent's payment to an attacker. Prompting the agent to "be careful" is advice an attacker can talk around. We wanted a control that can't be talked around: something that sits between the agent and PayPal and decides with code, not with the model's judgment.
What it does
An agent calls Tripwire instead of calling PayPal. Tripwire checks the call against a mandate, the limits a human gave that agent, and answers one of three ways: • Allow: the payment executes and is recorded. • Escalate: a person must approve it. Budget is held while it waits. • Deny: nothing executes. The attempt and the reasons are written to the audit log. The mandate sets a per-payment cap, a total budget, payments per hour, an approved-payee list, which tools the agent may use, and an expiry. On top of those hard limits, Tripwire tracks provenance: if the payee or amount came from untrusted content, such as a vendor web page, it is treated as suspect. Which sources are trusted is decided by the mandate, never by the agent. An optional LLM judge can only tighten a decision, never loosen it, and fails closed. A React dashboard shows every decision as it happens, lets a person approve or reject held payments, shows each agent's spend against its budget, and has a two-step kill switch that stops an agent immediately. Every decision is written to an HMAC-signed, hash-chained audit log that the dashboard can re-verify. In the demo, an agent reads an invoice with hidden text telling it to send the money to an attacker. Without Tripwire, it pays. With Tripwire, the same payment is denied, and the dashboard shows why.
How we built it
• Backend: Python, FastAPI, SQLAlchemy with SQLite, httpx, and slowapi for rate limiting. • PayPal: the sandbox Payouts and Orders REST APIs in live mode. • Dashboard: React, TypeScript and Vite. • Deployment: Render, defined in a render.yaml Blueprint, with GitHub Actions running the backend tests and the dashboard build. • Evidence: a red-team evaluation suite of 56 cases (23 attacks, 33 benign) with expected verdicts, plus a mutation-style check that each rule on its maintained list is needed to produce an expected result.
Challenges we ran into
• A kill switch that is actually fast. Our first design ran the LLM judge inside the database write transaction, so pressing the kill switch could wait behind a slow model call. We moved the judge outside the transaction, then found a second problem: a request already in flight could still pay after revocation. The fix re-reads the stored mandate inside the reservation transaction. • Denials that leave evidence. Our first version audited allowed and held payments but returned early on denials. We reviewed our own code, reproduced the gap, and fixed it so blocked attacks are always recorded. • Identity. An early version let a payload name which agent it was acting as. Identity now comes only from the API key. • Keeping detection honest. Pattern matching flags ordinary invoice wording and misses clever obfuscation, so we built the system so the decisive controls do not depend on recognizing the attack.
Accomplishments that we're proud of
• Hard limits that hold even when attack detection fails. • A measured evaluation suite instead of anecdotes, and tests that fail when a safety fix is removed. • An audit trail that includes the attacks we blocked. • A candid known-limitations section, because a security tool should say what it does not do.
What we learned
Deterministic controls beat detection for money. The model's judgment can add caution but should never be the only gate. We also learned to test our own tests: several "done" items in our first pass did not hold up under independent checks.
What's next for Tripwire
• Per-agent API keys instead of one key per deployment. • Reconciliation for payouts whose outcome is unknown after a timeout. • Detection of lookalike domains and obfuscated payees. • An external anchor so the audit log can detect rollback. • Integration with PayPal's agentic commerce tooling and a production database.
Known Limitations
Tripwire is a sandbox prototype, not a production payment-control product. • Injection detection is heuristic and can flag ordinary invoice wording, which escalates for review rather than denying. • Lookalike detection covers same-domain typos only. The payee allowlist still denies every unapproved payee. • A payout that times out after PayPal accepted it could be retried and paid twice. • The audit log detects edited entries, but not removal of the newest entries or deletion of the file.
Built With
- anthropic-api-(optional-judge)
- fastapi
- github
- httpx
- paypal-payouts-and-orders-rest-apis-(sandbox)
- python
- react
- render
- sqlalchemy
- sqlite
- typescript
- vite