Docs / Coinbase
Governing Coinbase agent wallets
Coinbase CDP gives an agent an MPC wallet with a real policy engine. Countersign compiles your declarative policy into CDP account policies enforced inside Coinbase's MPC signing service — so the cap holds even if a spend never touches Countersign.
Enforcement model: native session caps
On applyPolicy, the compiler creates a CDP account policy binding the agent's wallet. On freeze, it applies a deny-all policy and reads it back — an unconfirmed freeze is an error escalated to the controller, never a silent success.
| Policy field | Binds | Detail |
|---|---|---|
freeze | native | Deny-all CDP policy, read-back confirmed fail-closed |
dailyCap | native | Token-scoped Spend Permission |
allowlist / denylist | native | Counterparty criteria in the CDP policy (hex-validated by the compiler) |
venues | native | Bound to the account's network |
perTxCap | countersign-layer | CDP's ethValue criterion caps a transaction's native value; an ERC-20 amount lives in calldata, so token per-tx caps are enforced by the pre-flight guard. Native-gas assets (ETH) bind natively. |
approvalThreshold | countersign-layer | MPC caps enforce autonomously; inline human approval runs at the Countersign layer |
native = the rail itself enforces it, even if Countersign is bypassed or offline. countersign-layer = enforced fail-closed by the pre-flight guard and honestly labeled as such. Live, per-tenant version: GET /enforcement.
Proven live on Base Sepolia
- An in-policy spend signs and lands on-chain; an over-cap spend is blocked; after a freeze the next spend produces no transaction.
- The stronger test: a direct over-cap send that bypasses Countersign entirely is rejected by Coinbase itself — the policy lives in the MPC, not in a proxy.
- In the cross-vendor headline run, the Coinbase stop confirmed in ~1 ms of the freeze window.
Use it
// same policy language as every other rail
await cs.applyPolicy({ agentId: "payments-bot", policy: {
schemaVersion: 1, asset: "USDC",
perTxCap: "1000000", dailyCap: "5000000",
venues: ["base-sepolia"],
}});
const d = await cs.evaluate({ agentId: "payments-bot", amount: "400000",
asset: "USDC", venue: "base-sepolia" }); // pre-flight guard
Try it in 60 seconds — no account, no human
Self-serve key, an isolated sandbox tenant with a three-backend demo fleet, testnet only.
Get a free key → Watch the freeze GitHub