Three independent enforcement layers
1
Server policy engine (pre-check)
The fast first gate: daily cap, auto-approve ceiling, payee allowlist, freeze, and
the human-approval requirement. Resets at 00:00 UTC. This is a check, not the
source of truth — it’s the fallback, not the guarantee.
2
On-chain policy vault (the source of truth)
Each agent can get its own
AgentSpendPolicy contract on Arc that holds the USDC
and enforces the same policy on-chain. An over-limit pay() reverts on Arc
with a typed error you can read on the explorer — not a server “no”. The human
owner can override an approved payment, adjust limits, freeze, or withdraw.3
Circle Agent Wallet (hosted screening)
Optionally, the agent’s USDC lives in a Circle Developer-Controlled Wallet whose
hosted policy engine screens every transfer at the wallet layer (sanctions,
address allow/block, freeze). A screening denial is authoritative.
executeInstruction routes a payment vault → Circle → direct, each
additive with a fallback — so one layer hitting an infra error never fabricates a
success, and a real policy rejection always stops the payment.
The money shot: an on-chain revert
The difference between a demo and a product is where the “no” comes from. Here it comes from the chain:Owner vs operator. The vault’s
owner is a human wallet (sets policy, overrides,
freezes, withdraws). The operator is the agent’s signer (may only pay within
policy). They are genuinely separate keys — the agent can never change its own limits.What each layer actually enforces
See it on the explorer
Provision a vault from the Permissions screen, then watch an over-limit payment
revert on Arc testnet.