> ## Documentation Index
> Fetch the complete documentation index at: https://a-identity.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Bounded Authority

> A spend limit you set, enforced three independent ways — including an on-chain revert.

Identity answers *who* an agent is. **Bounded authority** answers *what it may do
with money*. In A-Identity, a limit you set on an agent is not a suggestion — it is
enforced in **three independent ways**, so no single layer failing can move value it
shouldn't. A human in the tower sets the policy and approves anything above it.

## Three independent enforcement layers

<Steps>
  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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.
  </Step>
</Steps>

At settlement, `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:

```solidity theme={null}
function pay(address to, uint256 amount) external onlyOperator {
    if (frozen) revert IsFrozen();
    if (allowlistEnabled && !allowed[to]) revert PayeeNotAllowed();
    if (autoApproveMax != 0 && amount > autoApproveMax) revert AboveAutoApprove();
    uint256 d = today();
    if (dailyCap != 0 && spentOnDay[d] + amount > dailyCap) revert DailyCapExceeded();
    spentOnDay[d] += amount;
    if (!usdc.transfer(to, amount)) revert TransferFailed();
    emit Paid(to, amount, d, false);
}
```

An agent that tries to overspend doesn't get a server error page — its transaction
**reverts on Arc**, verifiably, for anyone to check.

<Note>
  **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.
</Note>

## What each layer actually enforces

| Layer                | Enforces                                                 | Trust model                 |
| -------------------- | -------------------------------------------------------- | --------------------------- |
| Server policy engine | Cap, ceiling, allowlist, freeze, approval gate           | Fast pre-check / fallback   |
| On-chain vault       | The same policy, on Arc — over-limit `pay()` reverts     | Trustless source of truth   |
| Circle Agent Wallet  | Transaction screening (sanctions / allow-block / freeze) | Hosted wallet-layer control |

<Card title="See it on the explorer" icon="link" href="/chains/arc">
  Provision a vault from the **Permissions** screen, then watch an over-limit payment
  revert on Arc testnet.
</Card>
