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

# Policies

> On this page, we'll go through setting up transaction policies to control what your users' wallets are allowed to sign.

Policies are environment-wide rules that Portal enforces directly in the MPC signing path, before any signature is produced. Unlike checks you might add in your own application layer, a blocked transaction never gets signed at all. There's no signature for a client to work around or replay.

Policies are managed from the Policies page on the [Portal Admin Dashboard](https://app.portalhq.io).

## The transaction amount limit rule

Policy Engine v1 ships with one rule kind: a transaction amount limit. For each policy you choose:

* A **name** (up to 64 characters), which appears in the error when the policy blocks a transaction
* A **chain**
* A **token** — the chain's native asset, a listed stablecoin, or a custom token (contract address on EVM/Tron, or mint address on Solana) along with its decimals
* A **per-transaction cap**, entered in display units (e.g. `0.5` ETH, `100` USDC)

Any single transaction that moves more than the cap for that chain and token is blocked.

## Supported chains

* **EVM chains** — Ethereum, Sepolia, Polygon, Base, and Monad (mainnet and testnet) out of the box; amount extraction works on any `eip155` chain
* **Solana** — mainnet and devnet
* **Tron** — mainnet, Shasta, and Nile testnets

## How enforcement behaves

All enabled policies in an environment are evaluated for every transaction. If any policy's rule matches, the transaction is blocked; if none match, the transaction proceeds. There's no allowlist mode in this version. Policies are purely additive blockers.

When a policy blocks a transaction, the request fails with HTTP `400` and no signature is ever produced. Both `POST /v1/assets/send` and `POST /v1/sign` return the same body:

```json theme={null}
{
  "id": "POLICY_AMOUNT_LIMIT_EXCEEDED",
  "message": "amount exceeds limit (<policy name>)"
}
```

That is the raw Enclave MPC API response body; Portal SDKs expose the same fields through their own error handling. Match on the [`POLICY_AMOUNT_LIMIT_EXCEEDED`](/resources/error-codes) identifier rather than on the message text. Responses also carry a legacy numeric `code`, which is deprecated.

## Managing policies on the dashboard

Step 1: Click on "Policies" in the left sidebar, under Configuration.

Step 2: Click "Create policy," choose a chain and token, set your per-transaction cap, and save. Each policy holds one rule.

Once created, a policy appears in your list with a toggle and a delete action:

* **Toggle** — enable or disable the policy without deleting it. Disabled policies are not evaluated.
* **Delete** — permanently remove the policy.

## Scope & caveats

Policy Engine v1 is intentionally scoped. A few things to keep in mind:

* **Per-transaction only.** Limits are compared against a single transaction's amount. Velocity or cumulative limits (e.g. "no more than \$1,000 per day") are on the roadmap but not yet available.
* **Direct transfers are covered, not everything that moves value.** Token limits inspect direct `transfer`/`transferFrom` calls on EVM and Tron, and SPL transfers on Solana, both `TransferChecked` and plain `Transfer` sent from a wallet's associated token account. Value moved through arbitrary contract calls, approve-then-pull flows, or non-standard token accounts is not currently inspected.
* **Raw-signed payloads can't be policy-checked.** If your integration signs an opaque hash rather than a structured transaction, Portal has no transaction contents to evaluate against a policy, by design.

If your use case depends on any of the above, reach out to your Portal contact to discuss options.
