> ## Documentation Index
> Fetch the complete documentation index at: https://docs.idem.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure Agent Policy Rules to Control Automated Transactions

> Learn how to create and manage policy rules that control what agent-originated transactions are permitted in the Idem Ledger API.

Policy rules define the boundaries within which automated agents — API keys holding the `AGENTS_EXECUTE` scope — are permitted to operate. Each rule matches on one or more criteria such as agent key prefix, token type, chain, transaction amount, or specific accounts. Rules are evaluated by **PolicyGuard**, a stateless per-tenant evaluator that runs before any agent-originated write. Any transaction that falls outside the active rules is rejected before it reaches the ledger, and the evaluation itself is recorded to the HMAC-signed agent audit log.

## Rule types

Idem supports six policy rule types. Each type is a narrow, single-purpose constraint — to combine constraints (for example, "cap the amount **and** restrict the token"), create one rule per constraint; `PolicyGuard` evaluates all active rules for a tenant/agent together, and an intent must satisfy every one of them.

| `type`                         | Required fields                     | What it enforces                                                                                                                                   |
| ------------------------------ | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MAX_DEBIT_PER_SESSION`        | `amount`                            | Total DEBIT across the intent's lines, added to prior debits this session, must not exceed `amount`.                                               |
| `MAX_DEBIT_PER_HOUR`           | `amount`                            | Same as above, but the running total is scoped to a rolling one-hour window.                                                                       |
| `REQUIRE_HUMAN_APPROVAL_ABOVE` | `amount`                            | Any single DEBIT line strictly exceeding `amount` is flagged for human approval before it can execute.                                             |
| `FORBIDDEN_ACCOUNT_PAIR`       | `debitAccountId`, `creditAccountId` | The intent may not simultaneously debit `debitAccountId` and credit `creditAccountId` in the same transaction.                                     |
| `ALLOWED_TOKENS`               | `tokens` (non-empty)                | Every on-chain line must use a token in `tokens`. A fiat-only intent is rejected while this rule is active — an allowlist implies on-chain intent. |
| `ALLOWED_CHAINS`               | `chains` (non-empty)                | Every on-chain line must use a chain in `chains`. Same fiat-only caveat as above.                                                                  |

All rule types accept an optional `agentKeyPrefix` to scope the rule to a subset of agents (see below).

## Create a policy rule

Send a `POST` request to `/api/v1/admin/policy-rules` to define a new rule. Because each rule type is single-purpose, restricting an agent to "up to 1,000 USDC/USDT on EVM" takes three separate rules — one for the amount cap and one for each allowlist:

```bash theme={null}
# Cap session debits at 1000
curl -X POST https://api.your-domain.com/api/v1/admin/policy-rules \
  -H "Authorization: Bearer $IDEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "MAX_DEBIT_PER_SESSION",
    "agentKeyPrefix": "sk_live_agent_",
    "amount": "1000.00"
  }'

# Restrict to USDC/USDT
curl -X POST https://api.your-domain.com/api/v1/admin/policy-rules \
  -H "Authorization: Bearer $IDEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "ALLOWED_TOKENS",
    "agentKeyPrefix": "sk_live_agent_",
    "tokens": ["USDC", "USDT"]
  }'

# Restrict to EVM
curl -X POST https://api.your-domain.com/api/v1/admin/policy-rules \
  -H "Authorization: Bearer $IDEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "ALLOWED_CHAINS",
    "agentKeyPrefix": "sk_live_agent_",
    "chains": ["EVM"]
  }'
```

A successful response returns the created rule including its assigned `id` and `createdAt` timestamp:

```json theme={null}
{
  "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "type": "MAX_DEBIT_PER_SESSION",
  "agentKeyPrefix": "sk_live_agent_",
  "params": {
    "amount": "1000.00"
  },
  "createdAt": "2024-03-01T12:00:00Z"
}
```

## Rule fields

| Field             | Type      | Description                                                                                                                                                      |
| ----------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`            | string    | **Required.** One of the six rule types above.                                                                                                                   |
| `agentKeyPrefix`  | string    | A prefix string matched against the agent's API key. Only agents whose key begins with this value are subject to the rule. Omit to apply the rule to all agents. |
| `amount`          | string    | Required by `MAX_DEBIT_PER_SESSION`, `MAX_DEBIT_PER_HOUR`, and `REQUIRE_HUMAN_APPROVAL_ABOVE`. A decimal string (e.g., `"1000.00"`).                             |
| `debitAccountId`  | UUID      | Required by `FORBIDDEN_ACCOUNT_PAIR`.                                                                                                                            |
| `creditAccountId` | UUID      | Required by `FORBIDDEN_ACCOUNT_PAIR`.                                                                                                                            |
| `tokens`          | string\[] | Required (non-empty) by `ALLOWED_TOKENS`. Accepted values: `USDC`, `USDT`, `BRZ`, `PYUSD`.                                                                       |
| `chains`          | string\[] | Required (non-empty) by `ALLOWED_CHAINS`. Accepted values: `EVM`, `SOLANA`, `TRON`.                                                                              |

Only supply the fields required by the `type` you're creating — the API rejects a request that's missing a required field for its type.

## List policy rules

To view all active policy rules for your tenant, send a `GET` request to `/api/v1/admin/policy-rules`:

```bash theme={null}
curl https://api.your-domain.com/api/v1/admin/policy-rules \
  -H "Authorization: Bearer $IDEM_API_KEY"
```

The response is an array of `PolicyRuleResponse` objects, each containing the rule `id`, `type`, `agentKeyPrefix`, `params`, and `createdAt`.

## Delete a policy rule

To remove a policy rule, send a `DELETE` request with the rule's ID:

```bash theme={null}
curl -X DELETE "https://api.your-domain.com/api/v1/admin/policy-rules/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" \
  -H "Authorization: Bearer $IDEM_API_KEY"
```

A successful deletion returns `204 No Content` with an empty response body. Deletion takes effect immediately. Any agent transactions submitted after the deletion will no longer be evaluated against the deleted rule. If other rules remain active, those continue to apply.

## Required scope

All policy rule operations — listing, creating, and deleting — require the **ADMIN** scope. This scope should be held only by highly privileged keys used by your platform administrators, not by agent or service account keys.

<Tip>
  Use `agentKeyPrefix` to scope rules to a specific set of agents without needing a separate rule per key. For example, if you have a group of payment-processing agents whose keys all begin with `sk_live_agent_pay_`, a single rule with `"agentKeyPrefix": "sk_live_agent_pay_"` covers all of them. You can then create a separate, more permissive rule for a different group — such as internal settlement agents with a distinct prefix — without any overlap.
</Tip>
