Inspiration

AI agents can now buy products, pay invoices and manage subscriptions, but giving each agent its own unrestricted payment integration creates real risk. Three agents that each stay within their own limit can jointly overspend an organization's budget. An agent can change an order after a human approved it, or replay an old approval. And when merchant, user and organization rules conflict, nobody can say afterwards why a payment was allowed.

We wanted the missing layer between agents and payment providers: define financial authority once, enforce it consistently, and keep an auditable record of every decision.

What it does

PACT (Policy and Authorization Control Tower) is a financial governance runtime for AI agents. An agent such as Claude Code asks PACT for permission through MCP. PACT then:

  1. Evaluates policy. A deterministic, fail-closed engine composes system, organization, user, merchant and agent rules. It returns ALLOW, DENY or REQUIRE_APPROVAL with exact reason codes, never an LLM guess.
  2. Reserves a shared budget. All agents draw from one ledger with atomic reservations.
  3. Asks a human. The admin dashboard shows the exact transaction and every policy finding. Approval is bound to that order's hash.
  4. Issues a restricted grant. It is single-use, hashed, and bound to one merchant, order, amount and currency.
  5. Executes through PayPal Sandbox. Only the execution gateway can reach PayPal, and it re-checks the grant and the live order first.
  6. Records everything in a tamper-evident, hash-chained audit log.

No agent-facing tool can approve a payment. Replays and post-approval order changes are rejected and audited. We also built a Merchant Lab storefront where you can watch an agent's cart and each order's authorization timeline update live.

How we built it

  • Core: Python with SQLAlchemy. Concurrency safety comes from BEGIN IMMEDIATE and conditional SQL updates: a test with 20 contenders for room for exactly 5 lets exactly 5 win.
  • Interfaces: a FastAPI REST API, an MCP server that holds only an agent key (no database, no PayPal secrets, no approval rights), and an operator CLI (pact demo, doctor, approve).
  • PayPal: an Orders v2 adapter limited to Sandbox URLs, plus a clearly labelled simulation adapter ("Simulation (not PayPal)").
  • UI: React, Vite and Tailwind. The admin dashboard has Overview, Approval Centre, Policies and an Audit Explorer. The storefront has the catalogue, live cart and order pages.
  • Quality: 1,256 tests, including end-to-end tests through the real PayPal adapter on a mock transport, a security test matrix with a threat model, and CI for both Python and the dashboard.
  • Process: we built it with Claude Code, splitting independent work across parallel agents with disjoint file ownership.

Challenges we ran into

  • PayPal Sandbox behaviour. INR is rejected for our account type, so we settle in USD. The checkout can show a guest card form that rejects test cards instead of a login. Buyers must use a Personal Sandbox account that differs from the business account.
  • Payments that wait on a human. A payment can sit in checkout for a long time, hold budget, or fail permanently when the buyer clicks "Cancel and return". We hit each of these and tracked them as issues, fixing the gateway paths (order not found, capture recursion, non-terminal cancel, checkout timeout) before the demo.
  • Provider timeouts. A timeout can't be treated as failure or success. The request moves to UNKNOWN and is reconciled against the provider, never retried blindly.
  • Keeping the agent powerless. Every route, tool and log needed checking so that no agent path can approve, edit policy or read a secret. The security test matrix covers this.

Accomplishments that we're proud of

  • A complete governed purchase on PayPal Sandbox: Claude requests a keyboard, PACT requires approval, a human approves, the grant is consumed once, PayPal captures the payment, and the request ends EXECUTED with a real capture id. The audit chain verified across 459 events.
  • Shared budgets that hold up under concurrency, so the last request is denied by the global budget even when it is within its own agent's cap.
  • Replay and modification attempts are rejected and visible in the audit explorer.
  • An agent-facing surface with 16 tools, none of which can approve.
  • A threat model with documented findings and a test for each, written alongside the code.

What we learned

  • Authorization must be bound to the exact transaction, not just to an agent or a session.
  • Money and approvals need explicit state machines. The "unknown outcome" state matters more than the happy path.
  • Payment sandboxes have their own edge cases, and a simulation adapter is useful but must never be passed off as the real provider.
  • Writing the threat model and tests early found real bugs, such as a public cancel link that could fail a live payment.

What's next for PACT

  • Fix the remaining documented findings: the public cancel link, security headers and rate limiting on authentication.
  • Deploy a hosted instance with PostgreSQL support and a hardened admin login.
  • More payment providers behind the same adapter interface, and a policy editor with versioning, previews and diffs.
  • Per-agent spending analytics and alerts, and SDKs beyond MCP.
  • Complement agent payment protocols such as AP2 and PayPal Agent Ready: PACT governs the decision and the audit trail, and those protocols move the money.

PACT is a sandbox reference implementation, not a certified financial security product. It processes no real money.

Built With

Share this project:

Updates

posted an update —

PACT update: first real PayPal Sandbox payment, end to end

PACT is a financial governance runtime for AI agents. It sits between an agent and the payment provider and decides whether a payment may happen, under which limits and with whose approval.

This week it ran its first full governed purchase on the PayPal Sandbox:

  1. Claude Code asked to buy a $79 mechanical keyboard through MCP.
  2. PACT's policy engine required human approval, because the amount was above the user threshold.
  3. I approved the exact order in the admin dashboard.
  4. PACT issued a single-use grant bound to that order, merchant, amount and currency.
  5. PayPal Sandbox captured the payment, and PACT recorded the capture id.
  6. The audit log, a hash chain of 459 events, verified as intact.

What's new since the last update:

  • Admin dashboard: overview, approval centre showing every policy finding, policy editor and an audit explorer.
  • Merchant Lab storefront: catalogue, a live cart that updates while the agent shops, and an order page that walks through approval, grant and payment as it happens. You can also buy as a human, governed by the same PACT rules.
  • Shared budgets: several agents draw from one org budget, so the last request is denied by the global budget even when it is within its own agent's cap.
  • Replay and tamper protection: a reused grant or a changed order is rejected and audited.
  • Tests and security: 1,256 tests, end-to-end acceptance tests that run the real PayPal adapter against a mock, and a security test matrix with a threat model.
  • PayPal fixes: handling for expired orders, capture errors and abandoned checkouts.

No agent tool can approve a payment. The AI proposes, and deterministic code decides.

PACT is a sandbox reference implementation and processes no real money. Code: https://github.com/MohanPrasand/PACT

Next: tightening the remaining security findings, deployment, and more payment providers behind the same adapter interface.

Submission history