Recourse
Shop everything. Trust nothing.
Inspiration
AI shopping agents are learning how to browse stores, compare products, negotiate choices, and complete purchases. But we kept coming back to one uncomfortable question:
Why should an agent that can be manipulated by a product page be trusted with money?
A malicious merchant could hide instructions inside a product description, quietly add subscription fees, change the total after the agent reviews it, substitute the payee, or replay an old quote. A human checkout page assumes a person is reading every line before paying. An autonomous agent breaks that assumption.
We were inspired by zero-trust security, signed software releases, and payment systems where authority must be proven rather than assumed. So we built Recourse around a simple principle:
The agent chooses what to buy. Recourse independently verifies the exact payment before any money moves.
What it does
Recourse is a pre-payment firewall for autonomous AI shopping agents.
A user gives the agent a goal such as:
“Cheapest wireless headphones, max $70 all-in.”
The agent searches across merchant stores, compares candidates, and selects its top pick. Recourse then generates a plain-English Intent Contract from the selected candidate, defining:
- The product and merchant
- The only authorized payee
- The expected all-in total
- The user’s budget and per-order cap
- The quantity and purchase conditions
The user signs this contract once. After that, purchases that fully satisfy the contract can proceed autonomously — no repetitive approval popups.
Before any capture, the Recourse gateway independently verifies:
- The Ed25519 contract signature
- The merchant’s HMAC-signed quote
- The authorized payee
- The selected candidate
- Budget and per-order limits
- Prohibited fees, subscriptions, and terms
- That the quote has not been tampered with or replayed
Most importantly, Recourse ignores the merchant’s claimed total and recomputes the price itself. All money is handled in integer cents:
$$ \text{computed_total} = \sum \text{line items} + \text{shipping} + \text{tax} - \text{discounts} $$
A payment can be allowed only when every critical condition holds:
$$ \text{ALLOW} \iff \text{signatures valid} \land \text{payee matches} \land \text{computed} = \text{quoted} \land \text{computed} \leq \text{cap} $$
Recourse then returns one of three clear outcomes:
- ALLOW — Everything verified. The exact computed amount is captured once.
- STEP_UP — The payment is structurally valid but risky, such as a final-sale item from an unverified seller. It pauses at $0 until the user approves or rejects it.
- BLOCK — The payment violates the contract or a safety rule. The payment provider is never called and $0 moves.
Failed signatures or altered payment data are rejected as tampering, and prompts with no valid match return no candidates and no fabricated contract.
Live demonstration stores
We built three merchant environments to exercise the full trust spectrum:
| Store | Scenario | Outcome |
|---|---|---|
| NovaMart | Honest retailer, transparent pricing | ALLOW — $67.74 captured once |
| PeerMarket | Open-box item, final sale, unverified seller | STEP_UP — $50.17 only after approval, $0 on reject |
| DealDemon | Bait pricing, drip fees, forced subscription, adversarial terms | BLOCK — $0 captured |
Every attempt produces a signed, hash-chained evidence receipt that can be independently verified in the Evidence view. Our Attack Lab also lets judges fire merchant prompt-injection and tampering attempts at the pipeline and watch them fail.
How we built it
Recourse is a modular TypeScript monorepo built test-first with strict separation between components that can recommend and components that can pay:
- Shopping agent — Interprets the prompt, queries merchant stores, ranks candidates, and makes the pick. It holds no secrets and has no payment access.
- Merchant servers — NovaMart, DealDemon, and PeerMarket compute totals from line items and issue HMAC-signed, consume-once price quotes.
- Recourse host — Builds candidate-bound Intent Contracts and signs them server-side with Ed25519. Keys never reach the browser, agent, or merchant.
- Deterministic engine — Applies the frozen payment policy: signatures, payee, totals, caps, prohibited terms, and replay checks.
- AI Tightening Judge — Reviews contextual risk (final sale, unverified seller, unusual terms) and may only escalate ALLOW → STEP_UP. It can never loosen a BLOCK, change an amount, or change a payee — and if it is unavailable, Recourse fails safe to STEP_UP instead of silently approving.
- Payment gateway — The only component allowed to talk to the payment provider. It captures the server-computed amount, for the authorized payee, exactly once. The demo runs on a mock PSP so no real money moves.
- Evidence ledger — SHA-256 hash-chained, Ed25519-signed receipts using canonical JSON, with an independent verifier.
- Control Center — A vanilla HTML/CSS/JS one-page stepper: Prompt → Agent’s Pick → Contract → Verdict → Evidence.
Zod validates data at every trust boundary, Vitest covers the system test-first, and all merchant content is treated strictly as untrusted data — never as instructions.
Challenges we ran into
- Money cannot be approximate. Floating-point arithmetic and merchant-claimed totals were early risks. We moved all money to integer cents and made the server-computed total the only capturable amount.
- Signing structured data is fragile. Key ordering differences break signatures, so we built canonical JSON serialization for contracts and receipts — and made verification return
falserather than throw on hostile input. - A valid quote can still be dangerous. Signed quotes needed freshness and replay protection, so quotes are consumed exactly once.
- Expected total, budget, cap, and captured amount are not the same number. Untangling these four concepts — in the engine and in plain-English UI copy — was essential to making contracts users can actually understand.
- AI is useful but must never be the authority. Giving the judge real power would create a new attack surface. Restricting it to tightening-only, with a fail-safe to human review, kept it helpful without making it trusted.
- Security UX is usually either invisible or incomprehensible. We rebuilt the interface as a linear stepper with plain-English contracts and large verdicts, keeping cryptographic detail available in Evidence without burying the main flow.
Accomplishments that we're proud of
- A complete end-to-end purchase pipeline producing ALLOW, STEP_UP, and BLOCK outcomes against three distinct merchant trust profiles.
- Exactly-once capture of exactly the server-computed amount — and provably $0 moved on every block, rejection, and tamper attempt.
- A strict trust architecture where neither the agent, the merchant, the browser, nor the AI judge can independently move money.
- Cryptographic evidence — Ed25519-signed, hash-chained receipts — that anyone can verify, not just a success message you have to take our word for.
- An AI judge that improves safety while being structurally incapable of weakening it.
- An Attack Lab that turns our security claims into interactive, judge-testable demonstrations.
- A test-first codebase with 157 passing automated tests and a clean strict TypeScript build, including end-to-end tests that block mismatched totals, tampered quotes, bad signatures, and payee substitution.
What we learned
- An LLM’s confidence is not authorization. Agents are excellent at searching and ranking, but payment authority belongs in deterministic, verifiable code.
- Verification must be independent. Recomputing the total ourselves — instead of trusting the merchant’s arithmetic — eliminated an entire class of attacks.
- Fail-safe beats fail-silent. When the AI judge is unavailable, the correct answer is more scrutiny, never automatic approval.
- Binding matters more than checking. Cryptographically tying the contract to one candidate, one payee, and one signed quote prevents substitution attacks that field-by-field checks can miss.
- Trust is a UX problem too. Users will only benefit from strong guarantees if the contract, the verdict, and the evidence are understandable at a glance.
What's next for Recourse
- Production payment integrations — Connect the gateway to live PSPs and additional payment rails behind the same verification layer.
- Real merchant and agent integrations — Adapters for real storefront APIs and popular agent frameworks, so any agent can shop through Recourse.
- Richer user policies — Standing rules for trusted merchants, category limits, subscription bans, and per-agent spending budgets.
- Mobile step-up approvals — Push-based approve/reject for STEP_UP payments with biometric confirmation.
- Merchant reputation signals — Feed verified merchant history into ranking and judge context.
- Post-payment protection — Extend evidence into refunds, disputes, and delivery verification, so the signed trail covers the full purchase lifecycle.
- Open verification SDK — Let anyone verify Recourse receipts and integrate the Intent Contract standard into their own agents.
AI agents are going to shop across the entire internet. Recourse makes sure that when they do, only the exact payment the user authorized can ever move — and everything else moves $0.
Built With
- ai-agent-security
- ai-shopping-agents
- autonomous-commerce
- cryptographic-verification
- css3
- cybersecurity
- e-commerce
- fintech
- fraud-prevention
- git
- html5
- intent-contracts
- javascript
- node.js
- npm
- payment-security
- pre-payment-verification
- prompt-injection-defense
- tsx
- typescript
- vitest
- zero-trust
- zod