# Define policy

{% hint style="danger" %}
**Default behavior.** A fresh default setup uses `AllPolicies` with no policies, so everything is permitted until you explicitly configure spending limits. If you switch to a specific `PolicySet` with no policies attached, every request is denied.
{% endhint %}

Define what should go through automatically. Manual approval is a separate step covered in [Manual approval](/agentpay-sdk/workflows/manual-approval.md). Policy is evaluated locally before signing - WLFI is not involved in any transfer of funds.

## What most users need

For a first setup, base policy means:

1. Pick the token you care about
2. Confirm its network mapping
3. Set `per-tx`, `daily`, and `weekly` limits
4. Save and apply

That is enough. Skip destination overrides, gas caps, and manual approval rules until later.

## Fastest path: use the TUI

```bash
agentpay admin tui
```

The TUI keeps everything visible: saved networks, saved tokens, current draft, and a clear apply step.

## The three TUI views

* `Tokens`: set token mappings and spending limits (this is where you spend most time)
* `Networks`: confirm or save chain key, chain ID, RPC URL, and active network
* `Bootstrap`: apply the saved token inventory to the wallet

<figure><img src="/files/0e8NVWdA5Xe4d7rHyg6L" alt="AgentPay Admin Policy Editor showing the Tokens view"><figcaption><p>Tokens is the main policy workspace. This is where most users define the default policy.</p></figcaption></figure>

<figure><img src="/files/dJ8o2DjyU6WiRtjsCnVp" alt="AgentPay Admin Policy Editor showing the Networks view"><figcaption><p>Networks holds the saved chain inventory and RPC URLs used for token metadata and policy expansion.</p></figcaption></figure>

<figure><img src="/files/NXmAV96IwqINWRJYxHPc" alt="AgentPay Admin Policy Editor showing the Bootstrap view"><figcaption><p>Bootstrap validates and applies the saved token policy set in one run.</p></figcaption></figure>

## Minimal TUI walkthrough

Use this order for the normal base-policy path:

1. Open `agentpay admin tui`.
2. If you need a new network or different RPC, go to `Networks`, fill in `Network Key`, `Network Chain ID`, `Network Name`, and `Network RPC URL`, then save it.
3. Go back to `Tokens`.
4. Select the token you want to configure, or create a new draft.
5. In `Network Multi-Select`, toggle each network you want with `Space`. Use `←`/`→` to move between saved networks.
6. In `Editing Network`, pick the specific network mapping you want to edit.
7. Mark `Native Asset` for native gas assets, or enter `Token Address` for an ERC-20.
8. Use `Fetch Metadata` after the network RPC is saved so the editor can populate token name, symbol, and decimals.
9. Fill in `Per-Tx Limit`, `Daily Limit`, and `Weekly Limit`.
10. Save the token.
11. Go to `Bootstrap` and apply the saved inventory.

That is the normal path.

For the built-in BSC reference profiles:

* `bnb` is recognized as the native gas asset on `bsc` (available as a TUI reference profile, but not pre-seeded into your config)
* `usd1` is pre-seeded on `eth` and `bsc` with no spending limits
* `bsc` is already seeded as a saved network

## Useful TUI keys

You do not need every key at once. These are the ones that matter for normal use:

* `Tab` / `Shift+Tab` or `[` / `]`: move between `Tokens`, `Networks`, and `Bootstrap`
* `Up` / `Down` or `j` / `k`: move between fields
* `Left` / `Right` or `h` / `l`: cycle a selectable field
* `Space`: toggle booleans and network membership selections
* `Enter`: run the action on the selected field
* `Ctrl+S`: bootstrap and apply the saved inventory
* `Ctrl+N`: start a new token or network draft
* `Ctrl+R`: reload saved data and discard the current dirty draft
* `Ctrl+O`: add a destination override (Tokens view)
* `Ctrl+M`: add a manual approval rule (Tokens view)
* `q` / `Esc` / `Ctrl+C`: quit
* `Home` / `End`: jump to the first or last field

`Ctrl+S` works from any view, not only from Bootstrap. When a token or network draft is dirty, `Ctrl+S` persists the draft and reapplies wallet policies in one step. There is no separate "save only" step for dirty drafts in the TUI.

Two action rules are worth remembering:

* `Save Token` saves the current token draft
* `Bootstrap` applies the saved token inventory to the wallet

If the saved view and the current draft do not match, the draft is not saved yet.

## Direct CLI examples

If you already know the exact values you want, you can define the same base policy directly.

Default BSC native asset policy:

```bash
agentpay admin token set-chain bnb bsc \
  --native \
  --decimals 18 \
  --per-tx 0.01 \
  --daily 0.2 \
  --weekly 1.4 \
  --json
```

Default BSC USD1 policy:

```bash
agentpay admin token set-chain usd1 bsc \
  --address 0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d \
  --decimals 18 \
  --per-tx 10 \
  --daily 100 \
  --weekly 700 \
  --json
```

These examples use token units for `--per-tx`, `--daily`, and `--weekly`.

## What to skip for now

Most users can ignore these on the first pass:

* destination-specific overrides
* advanced gas, fee, tx-count, or calldata caps
* manual approval rules

Add those only after the base policy is working.

{% hint style="info" %}
**Destination overrides can only tighten.** A destination override can reduce the per-tx, daily, or weekly limit for a specific recipient, but it cannot raise the limit above the matching token policy. This is a security invariant enforced by the policy engine.
{% endhint %}

## Policy evaluation model

This section is reference material. You do not need it to set up a working policy.

### All policies must pass

Every applicable policy must pass independently. If any one denies a request, the request is denied.

### Scope filters

Each policy carries three scope filters - **Assets**, **Recipients**, **Networks** - each set to `All` or a specific set of IDs. A policy only applies when all three match the request. Requests outside every policy's scope hit `NoApplicablePolicies` and are denied.

### Policy attachment

Each agent key sees either `AllPolicies` (every enabled policy, including future ones) or a named `PolicySet` (explicit list of policy IDs), controlled by `policyAttachment` in the wallet profile.

### Calldata decoding

For `broadcast` requests containing ERC-20 `transfer`, `approve`, Permit2 `permit`, or EIP-3009 `transferWithAuthorization` / `receiveWithAuthorization` calldata, the engine decodes the inner recipient and amount and applies per-transaction spending limits. Requests with both ERC-20 calldata and a native value are rejected.

## Additional policy types

Beyond the three base spending limits (`PerTxMaxSpending`, `DailyMaxSpending`, `WeeklyMaxSpending`) and `ManualApproval`, the SDK policy engine also supports:

* `DailyMaxTxCount` - daily transaction count limit
* `PerTxMaxFeePerGas` - gas price ceiling per transaction
* `PerTxMaxPriorityFeePerGas` - priority fee ceiling per transaction
* `PerTxMaxCalldataBytes` - calldata size limit per transaction
* `PerChainMaxGasSpend` - per-chain gas budget

These can be configured through the TUI or via `agentpay admin setup` flags such as `--daily-max-tx-count`, `--per-tx-max-fee-per-gas-wei`, `--per-tx-max-priority-fee-per-gas-wei`, `--per-tx-max-calldata-bytes`, and `--max-gas-per-chain-wei`.

## Shared config vs live wallet state

The `agentpay admin token set-chain`, `agentpay admin chain add`, and similar editors update the local shared config in `~/.agentpay/config.json`. They do **not** change the live daemon wallet by themselves.

`agentpay config show --json` prints that local shared config snapshot. Treat it as a saved source-of-truth draft, not as proof that the current daemon policy attachment already changed.

To apply shared-config edits to the live wallet, use `agentpay admin tui` and save the draft there, or rerun `agentpay admin setup --reuse-existing-wallet`.

To inspect the concrete contents behind wallet `attachedPolicyIds`, read the IDs from `agentpay config show --json`, then query the daemon directly with `agentpay admin list-policies --policy-id <UUID>`.

## Spend window accounting

Spend window policies are signing-budget controls, not post-settlement accounting. A request counts against daily/weekly usage once the daemon successfully approves and signs it, including completed manual approvals, even if the signed transaction is broadcast later or ultimately fails on-chain.

## Policy rejection messages

When a request is denied, the CLI prints a message from the policy engine. Common examples:

| Message pattern                                                                                 | Meaning                                                                                            | Fix                                                                                   |
| ----------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `no enabled policies attached to this agent key`                                                | No policies are attached to this wallet profile                                                    | Attach policies via TUI Bootstrap or `--attach-bootstrap-policies` during setup       |
| `no policy scope allows recipient/asset/network for this action`                                | Policies exist but none match the request's asset + recipient + network                            | Add a policy whose scope covers the requested asset, recipient, and chain             |
| `policy <id> rejected request: per transaction max <limit> < requested <amount>`                | The request exceeds the per-transaction spending limit                                             | Raise `Per-Tx Limit` for that token or reduce the transfer amount                     |
| `policy <id> rejected request: window usage <used> + requested <amount> > max <limit>`          | The request would exceed the daily or weekly spending window                                       | Wait for the window to reset or raise the daily/weekly limit                          |
| `policy <id> rejected request: gas max <limit> < requested <gas>`                               | Gas budget exceeded                                                                                | Raise `PerChainMaxGasSpend` or reduce gas usage                                       |
| `policy <id> rejected request: tx_count usage <used> + 1 > max <count>`                         | Daily transaction count limit reached                                                              | Wait for the daily window to reset or raise `DailyMaxTxCount`                         |
| `policy <id> rejected request: max_fee_per_gas_wei <limit> < requested <requested>`             | Max fee per gas limit exceeded                                                                     | Raise `PerTxMaxFeePerGas` or lower the gas price                                      |
| `policy <id> rejected request: max_priority_fee_per_gas_wei <limit> < requested <requested>`    | Priority fee limit exceeded                                                                        | Raise `PerTxMaxPriorityFeePerGas` or lower the priority fee                           |
| `policy <id> rejected request: calldata max bytes <limit> < requested <requested>`              | Calldata size limit exceeded                                                                       | Raise `PerTxMaxCalldataBytes` or reduce calldata                                      |
| `policy <id> rejected request: missing required transaction metadata (<metadata>)`              | Required tx metadata missing                                                                       | Ensure the transaction includes the required metadata fields                          |
| `policy <id> rejected request: amount max <limit> < requested <amount>`                         | Transfer exceeds a manual approval rule's maximum - hard-denied without entering the approval flow | Reduce the transfer amount or raise `Approval Max Amount` in the manual approval rule |
| `policy <id> requires manual approval for requested amount <amount> within range <min>..=<max>` | The request matched a manual approval rule                                                         | Approve or reject via CLI                                                             |

When you are ready to introduce a human approval step, continue to [Manual approval](/agentpay-sdk/workflows/manual-approval.md).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.worldlibertyfinancial.com/agentpay-sdk/workflows/policy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
