# Policy concepts

Transaction policies are the security rules that control what funds can leave your wallets. Every wallet in Wallet-as-a-Service is **deposit-only by default**. You must create at least one policy for an asset before you can send that asset from the wallet.

Think of policies as programmable spending limits. They automatically evaluate every outgoing transaction and block any that would exceed your configured limits. This protects your assets even if someone gains unauthorized access to your API credentials or user accounts.

**Policies answer these questions:**

- How much can leave in a single transaction?
- How much can leave over a period of time?
- What is the maximum that can ever leave?
- Who can initiate transactions, and to where?


This page explains the core concepts you need to understand before creating and managing policies.

## Policy scope

Policies operate at the **wallet level only**. Each policy applies to a single wallet and controls transactions for a specific asset within that wallet.

No vault-level or organization-level policies
You can't create a policy that applies to multiple wallets simultaneously. If you need the same limit across ten wallets, you must create ten separate policies—one for each wallet.

Multi-chain EVM wallets
If your organization uses separate wallets for different EVM chains (for example, one Ethereum wallet and one Arbitrum wallet), policies on one wallet do **not** apply to the other—even if both wallets hold the same asset (ETH). You must create policies independently on each wallet.

## Limit types

Wallet-as-a-Service supports three limit types:

- **Per transaction (`PER_TX`)** – Maximum amount for any single transaction
- **Rolling duration (`ROLLING_DURATION`)** – Maximum cumulative amount within a sliding time window
- **Max total value (`CONSTANT`)** – Lifetime cap on total withdrawals


You can combine multiple limit types on the same wallet for layered protection.

How rolling windows work
When you attempt a transaction, the system calculates how much has already left the wallet within the current window. If your new transaction would push the total over the limit, the system rejects it immediately. As older transactions "roll off" the window, capacity becomes available again.

See [Policy reference](/pt-br/products/wallet/user-interface/policies/policies-reference#limit-types) for complete limit type documentation, duration values, and examples.

## Policy uniqueness

Each policy must be unique within its wallet. The system identifies a policy by four attributes:

| Attribute | Description |
|  --- | --- |
| Wallet ID | The wallet the policy belongs to |
| Limit type | `PER_TX`, `ROLLING_DURATION`, or `CONSTANT` |
| Symbol | The asset symbol (for example, `ETH`, `BTC`, `USDC`) |
| Matchers | Optional filters that narrow when the policy applies |


You can create multiple policies with the same limit type and symbol **if they have different matchers**. For example:

- `PER_TX` + `ETH` + no matchers → Applies to all ETH transactions
- `PER_TX` + `ETH` + `TRANSACTION_TYPE: WITHDRAWAL` → Applies only to ETH withdrawals


Both policies can coexist because their matcher configurations differ.

Duplicate policy error
If you try to create a policy that matches an existing policy's wallet, limit type, symbol, and matchers, the API returns error `PAL006.023: limit policy already exists`.

## Policy immutability

Policies are immutable. You can't edit an existing policy's limit amount, duration, or matchers.

**To modify a policy:**

1. Delete the existing policy (see [Manage policies](/pt-br/products/wallet/user-interface/policies/policies-manage#delete-a-policy-via-the-ui)).
2. Create a new policy with the updated values.


Why policies are immutable
Immutability provides a clear audit trail. Every policy change creates a new record with its own approval history, making it easy to track who authorized what and when.

## Policy lifecycle

Every policy moves through a series of states from creation to deletion.

```mermaid
stateDiagram-v2
    direction TB

    [*] --> LIMIT_CREATION_APPROVAL_PENDING: Create policy

    LIMIT_CREATION_APPROVAL_PENDING --> LIMIT_ENABLED: Approved
    LIMIT_CREATION_APPROVAL_PENDING --> LIMIT_REJECTED: Rejected

    LIMIT_ENABLED --> LIMIT_DELETION_APPROVAL_PENDING: Request deletion

    LIMIT_DELETION_APPROVAL_PENDING --> LIMIT_DELETED: Approved

    LIMIT_REJECTED --> [*]
    LIMIT_DELETED --> [*]

    note right of LIMIT_ENABLED
        Active and enforcing
    end note
    note right of LIMIT_DELETION_APPROVAL_PENDING
        Still enforcing
    end note
    note right of LIMIT_REJECTED
        Terminal state
    end note
    note right of LIMIT_DELETED
        Terminal state
    end note
```

Policies move through five statuses: pending approval, enabled, rejected, pending deletion, and deleted. A policy in `LIMIT_DELETION_APPROVAL_PENDING` status continues to enforce transactions until approvers approve the deletion—this prevents gaps in protection.

See [Policy reference](/pt-br/products/wallet/user-interface/policies/policies-reference#policy-statuses) for the complete status reference.

## Approval requirements

Whether a policy requires approval depends on your organization's approval group configuration.

### With approval groups configured

If your organization has an approval group for **Policy rules**, new policies enter `LIMIT_CREATION_APPROVAL_PENDING` status. Designated approvers must authorize the policy before it takes effect.

The policy activates after the required number of approvers authorize it (for example, 2 of 3 approvers). If the approval threshold becomes mathematically impossible to reach (for example, too many approvers skip), the policy moves to `LIMIT_REJECTED`.

### Without approval groups configured

If no approval group exists for Policy rules, the policy **automatically activates** immediately after creation. It transitions directly to `LIMIT_ENABLED` with `active: true`.

Security consideration
Without approval groups, anyone with API credentials that include `keylimit:create` scope can instantly enable policies. Consider configuring approval groups to add human oversight.

See [Approvals](/pt-br/products/wallet/user-interface/security-controls/approvals) to configure approval groups for your organization.

## Policy evaluation

When you submit a transaction, the policy engine evaluates it against all active policies for that wallet and asset. Policy checks are one stage in the full transaction pipeline.

### Where policies fit in the transaction pipeline

Policy evaluation is the first check after a user or API credential creates a transaction. The full pipeline is:

```mermaid
flowchart TD
    TX[Transaction created] --> PC[Policy check]
    PC -->|Pass| AP{Approvals required?}
    PC -->|Fail| REJ[Transaction rejected]
    AP -->|Yes| AG[Approval group review]
    AP -->|No| SIG[MPC signing]
    AG -->|Approved| SIG
    AG -->|Rejected| REJ
    SIG --> BC[Blockchain submission]
    BC --> CONF[Confirmed]

    style REJ fill:#ffcccc
    style CONF fill:#ccffcc
```

1. **Policy check** – The engine evaluates the transaction against all matching policies. If any policy rejects it, Wallet-as-a-Service rejects the transaction immediately and never sends it to approvers.
2. **Approval check** – If your organization configures approval groups for transactions, designated approvers must authorize the transaction.
3. **MPC signing** – The wallet's MPC quorum signs the transaction.
4. **Blockchain submission** – Wallet-as-a-Service publishes the signed transaction to the network.


See [Signing & approvals overview](/pt-br/products/wallet/user-interface/security-controls/security-controls-overview) for details on approvals and MPC quorums.

### Evaluation order

```mermaid
flowchart TD
    A[Transaction submitted] --> B{Find matching policies}
    B --> C[Policy 1: Check limit]
    B --> D[Policy 2: Check limit]
    B --> E[Policy N: Check limit]

    C --> F{All policies pass?}
    D --> F
    E --> F

    F -->|Yes| G[Proceed to approvals/signing]
    F -->|No| H[Transaction rejected]

    style H fill:#ffcccc
    style G fill:#ccffcc
```

1. The engine finds the `LIMIT_ENABLED` policies for the transaction's wallet and asset.
2. The engine selects which policies apply:
  - If one or more policies **with matchers** match the transaction, those policies apply, and policies without matchers don't. This includes rolling and max-total-value policies without matchers.
  - If no policy with matchers matches, the policies **without matchers** apply.
  - If no policy applies, the engine rejects the transaction.
3. For each applicable policy, the engine checks whether the transaction would exceed the limit.
4. If **any** applicable policy rejects the transaction, the entire transaction fails.
5. If **all** applicable policies pass, the transaction proceeds to the next stage (approvals or signing).


**Example:** A wallet has a 10 ETH per-transaction policy with no matchers, and a 50 ETH per-transaction policy for one API credential. A 30 ETH transfer from that API credential passes, because only the matching 50 ETH policy applies. The same transfer from any other initiator fails the 10 ETH policy.

### Network fees and policy limits

Wallet-as-a-Service checks policy limits against the **transaction amount only** and excludes network fees (gas on EVM chains, transaction fees on XRP Ledger) from the limit calculation. For example, if you have a PER_TX limit of 10 ETH and send exactly 10 ETH, the policy check passes — the gas cost doesn't push the transaction over the limit.

### Operations that bypass policies

Policy checks don't cover all outgoing fund movements. **Asset sweeping bypasses policies entirely.** A wallet doesn't need any policies in place before Wallet-as-a-Service can sweep it, and Wallet-as-a-Service doesn't evaluate sweep transactions against existing policies.

This means policies alone don't prevent all fund movement from a wallet. If you need to restrict sweeping, manage sweep configurations separately through **Settings > Workflows**. Only owners and administrators can configure sweeping operations.

See [Asset sweeping](/pt-br/products/wallet/user-interface/wallets/asset-sweeping) for details on sweep configuration.

Transaction freeze is separate from policies
[Transaction freeze controls](/pt-br/products/wallet/user-interface/transactions/manage-transactions#freeze-and-unfreeze-transactions) apply to **inbound** transactions only (holding incoming funds for compliance review). Limit policies apply to **outbound** transactions only. The exception is inbound [Travel Rule](/pt-br/products/wallet/user-interface/travel-rule/travel-rule-overview) policy rules, which can freeze deposits that arrive without an accepted Travel Rule message.

### Matcher evaluation

Matchers filter which transactions a policy applies to. A transaction must match **all** matchers on a policy for that policy to apply. If a policy has no matchers, it applies to **all** transactions for that asset.

Active matcher types include: `TRANSACTION_TYPE`, `USER`, `API_CREDENTIAL`, `SIGN_FOR`, `COUNTERPARTY_ID`, `ADDRESS_ID`, `WALLET_ID`, and `CHAIN_ID`. Use `COUNTERPARTY_ID` for new policies; reserve the older `COUNTERPARTY` matcher for backward compatibility.

See [Policy reference](/pt-br/products/wallet/user-interface/policies/policies-reference#matchers) for detailed matcher documentation and examples.

## Monitoring policy checks with webhooks

If you have webhooks configured for the **TRANSACTION** domain, you receive notifications as transactions move through the policy check stage. The relevant statuses are:

| Status | Description |
|  --- | --- |
| `POLICY_CHECK_PENDING` | Wallet-as-a-Service is evaluating the transaction against policies. With Policy Engine v2, the transaction also waits here while it collects any required approvals. |
| `POLICY_CHECK_PASSED` | Transaction passed all policy checks. With Policy Engine v2, the transaction also passed all required approvals. |
| `REJECTED` | A policy or approval rejected the transaction. The transaction's `problems` array carries a `PAL006.xxx` reason code. |


These webhooks allow you to build automated monitoring for policy enforcement — for example, alerting on rejected transactions or tracking policy check latency. After Ripple enables Policy Engine v2 in your environment, `POLICY_CHECK_PENDING` can last for the full approval window rather than milliseconds, so adjust any latency alerts accordingly. See [Policy Engine v2: transaction status changes](/pt-br/products/wallet/changelogs/policy-engine-v2-transaction-status-changes).

No policy lifecycle webhooks
Webhook notifications cover **transaction** status changes only. There are no webhook events for policy creation, approval, or deletion. To track policy lifecycle changes, use the [Approval domain](/pt-br/products/wallet/user-interface/integrations/overview#approval-domain) webhooks, which notify you when Wallet-as-a-Service creates or resolves approval requests for policy rules.

See [Webhooks overview](/pt-br/products/wallet/user-interface/integrations/overview) for setup instructions and payload format.

## What to read next

- [Policy reference](/pt-br/products/wallet/user-interface/policies/policies-reference) – Complete reference for all limit types, matchers, and configuration options
- [Manage policies](/pt-br/products/wallet/user-interface/policies/policies-manage) – Step-by-step guide to create, modify, and delete policies
- [Policy best practices](/pt-br/products/wallet/user-interface/policies/policies-best-practices) – Recommended patterns and common configurations