-
-
Landing page with the budget info, sorted by agents. Along with the concurrency proof.
-
trails of an approved payment.
-
all the payments that ai agents tried, shows the approved payments and the payments which are rejected, stating it's reason.
-
page to set a budget, by agent, category and budget limit.
-
demo section of the app where you can manually try and invoke all the possibilities.
Inspiration
We kept seeing the same pattern. Companies are handing real tasks to AI agents, and some of those tasks cost money. An agent renews a software license, pays an API for data, spins up cloud capacity. The purchase happens, and nobody set a limit on it. The way most teams run an agent today is a shared API key or a saved card, and finance finds out what it bought when the statement lands at month end. A human employee gets a corporate card with a limit and a category. The agent buying on the company's behalf got nothing. We built Rein to close that gap.
What it does
Rein gives every AI agent a corporate card with a spending limit. Each agent is issued a budget with limits per category and per period. When the agent tries to buy something, Rein checks the request against the budget and the rules, approves or blocks it before any money moves, and writes the result to a ledger that cannot double-spend. Every approved purchase carries three signed mandates: an Intent the principal authorized, a Cart the vendor presented, and a Payment that ties the two together and stands as a tamper-evident receipt. A dashboard shows live spend by agent and category, blocks purchases in real time when they break a rule, and exports the full audit trail for finance.
How we built it
The frontend is a Next.js dashboard on Vercel. A control-plane API sits behind it and does the real work: it receives each purchase intent, runs the budget and policy checks, verifies the mandate signatures, and commits the ledger transaction. A demo procurement agent drives the flow end to end. We put the ledger on Aurora DSQL and connect through the node-postgres connector with IAM authentication. Mandates are signed with Ed25519, and the Payment mandate stores a hash of the matched Intent and Cart so the authorization chain is verifiable. Every write to the ledger runs through a retry path built for optimistic concurrency, with exponential backoff and jitter.
Challenges we ran into
The hard problem was concurrency, and it nearly fooled us. Two purchases can hit the same budget at the same instant. The obvious double-entry design reads the balance, sees room for both, writes two separate ledger rows, and the budget is blown. Worse, that design passes every single-threaded test and only breaks under real load, which is the exact failure Rein exists to prevent. Aurora DSQL uses optimistic concurrency control instead of locks, so it will not stop two writes that touch different rows. The fix was to put a single remaining-balance counter on the budget row and make every purchase update that one row. Now two concurrent purchases collide on the same row, DSQL detects the write-write conflict, the first commit wins, and the second fails at commit with a serialization error, SQLSTATE 40001. Rein catches that error, re-reads the budget, and either retries or rejects the purchase as over limit. The ledger stays balanced under concurrent load with full ACID guarantees. That is the reason this runs on DSQL and not a key-value store.
Accomplishments that we're proud of
The ledger holds correct under concurrent purchases, and we can prove it live: fire two requests that each fit the budget alone but not together, and only one commits while the books stay balanced. Every purchase produces a real cryptographic receipt, signed and chained, not a log line. The whole system runs on a database that scales to zero between bursts, so it costs almost nothing at rest while still giving active-active durability across availability zones. And we kept the data model honest to DSQL's constraints instead of fighting them.
What we learned
The biggest lesson was that single-threaded correctness means nothing for a ledger. The design has to be right when requests race, and proving that takes a different kind of test than the happy path. We also learned to treat Aurora DSQL as its own database, not Postgres with a new label. It has no foreign keys, no sequences, and strict rules on schema changes, so we enforce referential integrity in the application, generate UUID keys in the database, and keep to one DDL statement per transaction. On the product side, modeling purchases as Intent, Cart, and Payment mandates from the AP2 standard gave us a clean way to separate what a principal authorized from what a vendor actually charged, which is the piece that makes an agent's spending auditable after the fact.
What's next for Rein
Wiring the official AP2 sandbox so mandates verify end to end against the protocol's reference implementation. Promoting the audit ledger to multi-region active-active. Reconciling Rein's records into ERP and procurement systems, since that is where this has to live to be useful to a finance team. And scoring each agent's spending pattern to flag anomalies before a purchase clears, because a prompt-injected agent is a new kind of fraud that traditional spend controls do not catch.
Built With
- ap2-(agent-payments-protocol)
- aurora-dsql
- aws-iam
- ed25519
- next.js
- node-postgres
- postgresql
- react
- tailwind-css
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.