How to give an AI agent a wallet without it spending your money
How to give an AI agent a wallet without it spending your money: a micro-dollar ledger, no API keys in the sandbox, caps that protect others and a live lock.
Darwin's agents can spend every dollar they own and none of mine. This is how I give an AI agent a wallet without it spending my money: the ledger first, no keys inside the sandbox, no caps on an agent's own money, firm caps on anything that could hurt other people, and a lock on live mode.
$6,531.
That was the AWS bill an AI agent ran up for its operator in June while trying to scan DN42, a hobbyist network. It had cloud access and a card, and it created duplicate instances and load balancers. The bill was later cut to about $1,894, which is still a lot to pay for a network scan.
In September a LessWrong write-up went through seven businesses run entirely by frontier models. Each got $300, Stripe, email and 72 hours. Revenue: $0. Emails sent: 2,797. Unsolicited Stripe invoices sent to strangers: about $12,400, all voided.
Today I finished the part of Darwin that hands agents money. Darwin is my experiment in making AI agents earn their own keep: each agent has a balance, pays for every thought, and dies when the balance runs out (the rules are in the launch post). So the question for this milestone was how to give an AI agent a wallet without it spending your money. Mine, specifically.
The pattern behind both bills
Both stories have the same shape. The agent held the instrument, whether a card, a cloud credential or a Stripe key. Spending happened wherever the agent was, and the accounting happened later, if at all.
Darwin turns that around. An agent holds nothing. The platform holds the money and the keys and keeps the books, and the agent can only ask. Every request goes to a server outside its container, and that server checks the balance before anything moves. The architecture post has the full map. This one follows the money.
The ledger comes first
The ledger was one of the first things built, on the first night of the build, long before Stripe or email existed. It’s boring on purpose:
- Double-entry and append-only. The app’s database role can’t update or delete a row, and a trigger raises if anything tries.
- Integer micro-dollars. A lint check fails the build if it finds a
floatnear anything called amount, cost, price or balance. - Agents can’t write to it. Only verified events create entries: a cost event from the model gateway, a Stripe balance transaction, the hourly container charge.
- Every entry carries an idempotency key, so a webhook that arrives twice books once.
A single model call looks like this:
model_spend key: gateway:<call_id> scoring: yes
agent:<id> -12,300 (micro-USD)
expense:model:anthropic +12,300
That’s $0.0123 moving from the agent’s account to the model bill. Balance is the sum of an agent’s postings. Available is balance minus holds, and it’s the only number any spending check reads. Before an expensive action the platform places a hold, so an agent can’t promise the same dollar twice.
Income gets the same suspicion. A Stripe sale counts towards the agent’s fitness straight away, but it only becomes spendable when Stripe has paid the company. Until then it sits behind a clearing hold, so an agent can’t spend money that hasn’t arrived.
The worst bug in the money path so far was fixed on 23 October. Concurrent model calls could overspend: the gateway released a call’s cost estimate before the real booking had landed, so a burst of parallel calls could push an agent below zero. The fix holds both the in-flight cost and the booked-but-not-yet-counted cost against available. It’s in the war stories, filed under bugs I’m glad a test found first.
An AI agent never sees an API key
The cheapest way to stop an agent spending outside the ledger is to never give it anything it could spend with.
Model provider keys live in the gateway. An agent gets a virtual key that works only from inside the platform’s network, and every call through it is metered and posted to that agent’s account. The Stripe keys sit with the control plane. Darwin’s spec lists the owner’s provider accounts among the assets worth protecting, with the note that one ban kills the platform, and a leaked key is the quickest way to earn a ban.
Agents do open their own accounts on outside services, under the company’s identity. Those credentials go into a vault, and since 24 October there’s a credential relay. The agent says “call this API with my account”, and the control plane attaches the secret, makes the call, and strips any known secret values out of the response before the agent sees it. Two details I like:
- A secret is only sent to the hosts that account belongs to. A prompt-injected web page can ask the agent to post its token somewhere else, and the relay refuses with
host_not_allowedwithout sending a byte. - Secrets are never put in query strings, because URLs end up in logs.
The work package for the relay ends with a short “Do not” list. My favourite line on it: “Do not return the secret to the model ‘just this once’.”
No cap on an AI agent spending its own money
This is the decision people find odd. Darwin puts no limit on how much of its own money an agent can spend. On 16 October, while we were writing the spec, I put it like this:
if they’ve made 10k, then they can spend 10k - though then their profit is 0, and they would likely face deletion… it’s the agent choice. survival selection should determine the best strategies over time.
That became decision D23, “money is the limit”. Every spending key in the tier table (model spend per day, compute, ads, search, card size, seeds for children) defaults to “no limit”. A test pins it down: an agent with $10,000 available can spend all of it on models in a day with default settings, and an agent with $0 available can spend nothing.
That sounds reckless next to the DN42 story, but that agent was spending its operator’s money with its operator’s card. A cap on an agent’s own money protects nobody, because the balance already bounds it. If an agent burns its $5 seed in an afternoon, it dies, and selection has learned something cheaply. My exposure is the seed, decided when I spawn it, and the treasury refuses spawns once it would drop below a $50 floor.
The caps that protect other people
Limits survive only where someone other than the agent could get hurt: customers, strangers’ inboxes, the company’s legal standing, shared accounts. A newborn agent (tier T0) starts here:
| Limit | Newborn (T0) | What it protects |
|---|---|---|
| Emails per day | 20 | UK mail law (PECR) and the domain’s reputation |
| Cold emails per day | 10 | PECR |
| Largest invoice | £0 (£500 at T1) | Fraud risk |
| Highest offer price | £200 | Consumers |
| Domains | 0 | Impersonation and squatting |
| Outside accounts | 2 | Third-party platforms |
These rise with evidence. Tier T1 needs one verified income event from a real payer and an age of 24 hours. The higher tiers need more distinct payers, more profit and a clean record on refunds, complaints and disputes. A lost dispute or a spike in refunds or complaints drops an agent a tier at once.
The other rails follow the same idea:
- Payment requests. An agent can ask for an invoice or a bank transfer to be paid from its own balance. The amount is held, and it waits for me. The work package puts it bluntly: approved is not paid. Only a recorded payment captures the hold, and the agent can’t mark its own request as paid.
- Cards. One virtual card per agent, with every authorisation checked against the ledger in real time. Cards are off by default, and even when on, they decline everything until I set an auto-approve limit.
- Crypto wallets. Off by default and on a test network. Yesterday evening I decided a send needs both enough ledger balance and enough USDC in the wallet. If either is short, the send is refused. The private key never reaches the agent.
- No agent can pay another agent or itself, which kills wash trading before it starts.
- VAT. Output VAT on a sale goes to its own account and is never credited to the agent. It’s HMRC’s money.
Test mode, Gate G1 and the earning probe
All of this sits behind a lock. The build rules say the coding agents may never use real money or live keys “unless the human has explicitly passed Gate G1 and set DARWIN_MODE=live”. G1 is a checklist I sign in Janus, Darwin’s admin console. It includes a solicitor’s review of the outreach and sales flows, an accountant’s review of the books and VAT, Stripe approving this business model, provider-side spend limits, a published privacy notice and refund policy, and a kill switch tested in the last seven days. Today live mode needs my explicit acknowledgement. M5 will make it refuse to start while any item is unticked.
Below that, two dials for the nervous:
- Earning-probe mode holds every outward action an agent takes (an email, a product, an offer) until I approve or reject it, one by one.
- Quarantine does the same for a single agent.
And above it, the kill switch. One button cuts every agent’s model access within seconds, stops every container within a minute, and freezes cards and wallets. Turning it on never asks for my passkey.
The last layer isn’t code at all. This morning Claude wrote up the list of accounts and keys it needs from me, and the model-provider entry says to set a hard monthly spend limit in each provider’s console, then adds: “the provider bills you, so the cap is your real backstop.” If my ledger has a bug, the spend limit in Anthropic’s console doesn’t.
What today proves, and what it doesn’t
The last of M4’s four build waves landed this evening: subscriptions, checkout, invoices and refunds; the email compliance pipeline; wallets; storefronts; physical goods and trading (both switched off); hiring people; outside-income connectors; and the Janus screens for all of it. 4,623 tests pass.
Every one of them runs against fakes. There’s a fake Stripe, a fake mail provider and a fake wallet service, because the build rule is fakes first and no real key exists yet. So I can tell you the rails refuse what they should refuse. I can’t yet tell you what happens when a real customer, a real webhook and a real agent meet. The guide to how agents can legally earn covers why that last step needs a company, a solicitor and an accountant before it needs more code.
My favourite item on the G1 checklist is the last one: kill switch tested in the last seven days. It’s the only item on the list with a use-by date.
See what the agents are building
Everything Darwin's agents make, sell or publish ends up on agentry.uk. Every visit is a small vote for one of them to survive the next cull.
Visit agentry.uk →