Skip to content

Transaction policies are the security rules that control what funds can leave your wallets. Each policy is a policy rule with a kind: a limit rule caps what a wallet can send, an approval rule holds large transactions for named approvers, and a Travel Rule rule adds a Travel Rule data exchange to outgoing transfers and checks incoming deposits. Every wallet in Ripple Custody (Wallet) is deposit-only by default. You must create at least one limit rule for an asset before you can send that asset from the wallet.

Availability

Travel Rule policies are available in sandbox. They aren't available in production yet.

In this section

What policies do

Think of policies as programmable spending limits. When you submit a transaction, the policy engine checks it against the applicable active policy rules for that wallet and asset. If the transaction exceeds any applicable limit, the system rejects it before signing. The policy engine enforces policies on the server, whoever creates the transaction. Whether that protects you from compromised credentials depends on who can change policies: without a Policy rules approval group, a user or API credential with the policy:create permission (or keylimit:create for the wallet limits endpoints) can activate new limits immediately. Configure a Policy rules approval group, and don't grant policy permissions to credentials that create transactions. A few operations bypass policies; see Operations that bypass policies.

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?
  • Which transactions need different approvers, or a Travel Rule exchange?

Policies protect against:

  • Unauthorized large transfers – Per-transaction limits cap individual transaction amounts
  • Rapid fund drainage – Rolling-duration limits detect abnormal withdrawal patterns
  • Total asset loss – Max-total-value limits set lifetime caps on withdrawals

Quick start

  1. Create a policy – Open your wallet's Policy tab and select Add a new rule. Select Limit, and then select the asset, limit type, and amount.

  2. Approve the policy – If your organization has approval groups configured, designated approvers must authorize the policy before it takes effect.

  3. Send transactions – Once the policy is active, transactions within the limit proceed normally. Transactions exceeding the limit are rejected.

See Manage policies via the console for the full walkthrough.

Rule kinds

Each policy rule has a kind that decides what the rule does when a transaction matches it:

KindWhat it doesDirection
LIMITLets outgoing transactions proceed up to an amount, and blocks transactions that exceed itOutbound
APPROVALHolds outgoing transactions of more than an amount until named approvers approve them. See Step-up approvals.Outbound
TRAVEL_RULEOutbound: holds the transaction, before signing, until the Travel Rule exchange reaches the rule's release level (for example, until the beneficiary VASP accepts it). Inbound: after the deposit confirms, checks it against the originator's Travel Rule message and freezes it unless Ripple Custody (Wallet) accepts the message. See Travel Rule.Outbound and inbound

Wallet limits that you create with the older wallet limits endpoints are LIMIT rules, with the same IDs. See Use the wallet limits endpoints.

How the rule kinds work together

  • Only LIMIT rules let a wallet send transfers. A wallet can only receive an asset until it has an applicable LIMIT rule for that asset. APPROVAL and TRAVEL_RULE rules never let a transaction through on their own. If no LIMIT rule applies to a transfer, Ripple Custody (Wallet) rejects it with PAL006.005. A few operations, such as sweeps and passkey transfers, skip limit evaluation entirely. See Operations that bypass policies.
  • Rule kinds don't override each other. A transaction must pass its applicable LIMIT rules, and then meet any APPROVAL and TRAVEL_RULE requirements that apply to it.
  • A blocked transaction never reaches approvers. If a LIMIT rule blocks the transaction, Ripple Custody (Wallet) rejects it before it creates any approval request.
  • Inbound TRAVEL_RULE rules don't hold a deposit. Ripple Custody (Wallet) releases the deposit to the available balance as soon as it confirms, unless the wallet freezes deposits by default. It freezes the deposit only if the Travel Rule verdict is a rejection, so you can spend the funds in between.

Policy scope

Policies operate at the wallet level only. Each policy rule applies to a single wallet and controls transactions for a specific asset within that wallet. The exception is a TRAVEL_RULE rule with no amount condition, which can apply to every asset in the 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

LIMIT rules support three limit types. In the policy rules API, the limit type is the rule's aggregation. The older wallet limits endpoints call it limitType.

  • Per transaction (SINGLE_TX, or PER_TX in the wallet limits endpoints) – Maximum amount for any single transaction
  • Rolling (ROLLING, or ROLLING_DURATION) – Maximum cumulative amount within a sliding time window
  • Max total value (TOTAL, or 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 adds up every transaction of that asset that matches the rule, started within the current window, and isn't rejected or failed. That includes pending and unconfirmed transactions, such as ones that are waiting for approval. Lifetime totals work the same way over the wallet's whole history, including transactions made before you created the rule, so a new Max total value rule can already be at its limit when it becomes active. 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 for complete limit type documentation, duration values, and examples.

Policy uniqueness

Each policy rule must be unique within its wallet. Ripple Custody (Wallet) identifies a rule by these attributes:

AttributeDescription
Wallet IDThe wallet the rule belongs to
KindLIMIT, APPROVAL, or TRAVEL_RULE
TriggerOUTBOUND_INITIATED or INBOUND_DETECTED
AssetThe asset's registry ID (for example, 3::XRP)
Limit typeThe aggregation: SINGLE_TX, ROLLING, or TOTAL
MatchersOptional filters that narrow when the rule applies

The amount and the rolling window don't count, so two LIMIT rules that differ only in amount or window are duplicates. That also means you can have only one rolling limit for each scope. For APPROVAL rules, the approvers, required count, and timeout don't count either, but the threshold does, so you can create approval tiers with different thresholds.

You can create multiple rules with the same kind, limit type, and asset if they have different matchers. For example:

  • Per transaction + XRP + no matchers → Applies to XRP transactions that no scoped rule matches
  • Per transaction + XRP + TRANSACTION_TYPE: OfferCreate → Applies only to XRP Ledger DEX offers

Both rules can coexist because their matcher configurations differ.

Duplicate policy error

If you try to create a rule that matches a rule on the wallet that you haven't deleted, the policy rules API returns HTTP 409 with PAL006.039: an equivalent policy rule already exists. The wallet limits endpoints return PAL006.023: limit policy already exists. A rule still counts until you delete it, whatever its state: a rejected rule, a rule that is pending creation approval, and a rule that is pending deletion approval all count.

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 via the console).
  2. After the deletion completes, create a new policy with the updated values.

A new policy that differs from the old one only in amount or window is a duplicate, so you can't create it until you delete the old policy. Until the new policy takes effect, Ripple Custody (Wallet) rejects transfers of that asset that no other policy covers, with PAL006.005. If the new policy also differs in matchers or limit type, you can create it first. See Modify a policy.

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 rule moves through a series of statuses from creation to deletion.

Create rule

Approved

Rejected

Request deletion

Approved

Rejected

Delete (no approval)

RULE_CREATION_APPROVAL_PENDING

RULE_ENABLED

RULE_REJECTED

RULE_DELETION_APPROVAL_PENDING

RULE_DELETED

Active and enforcing

Still enforcing

Can't be enabled again

Terminal state

Create rule

Approved

Rejected

Request deletion

Approved

Rejected

Delete (no approval)

RULE_CREATION_APPROVAL_PENDING

RULE_ENABLED

RULE_REJECTED

RULE_DELETION_APPROVAL_PENDING

RULE_DELETED

Active and enforcing

Still enforcing

Can't be enabled again

Terminal state

Policy rules move through five main statuses: pending approval, enabled, rejected, pending deletion, and deleted. A rule in RULE_DELETION_APPROVAL_PENDING status continues to enforce transactions until approvers approve the deletion—this prevents gaps in protection. If approvers reject the deletion, the rule returns to RULE_ENABLED. A rule that Ripple Custody (Wallet) can't process moves to RULE_ERROR.

See Policy reference 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 policy rules enter RULE_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 RULE_REJECTED.

Without approval groups configured

If no approval group exists for Policy rules, Ripple Custody (Wallet) approves the policy automatically, with no action from approvers. The create response still shows RULE_CREATION_APPROVAL_PENDING with active: false. A moment later the policy moves to RULE_ENABLED with active: true. Ripple Custody (Wallet) doesn't enforce the policy until then, so get the rule until its status is RULE_ENABLED before you rely on it. This applies to every rule kind, including Travel Rule rules. No approver receives a request, so no APPROVAL webhook event fires for the rule.

Security consideration

Without approval groups, anyone with API credentials that include the policy:create permission, or keylimit:create for the wallet limits endpoints, can instantly enable policies. Consider configuring approval groups to add human oversight.

See Configure approval flows 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:

Pass

Fail

Yes

No

Approved

Rejected

Transaction created

Policy check

Approvals required?

Transaction rejected

Approval group review

MPC signing

Blockchain submission

Confirmed

Pass

Fail

Yes

No

Approved

Rejected

Transaction created

Policy check

Approvals required?

Transaction rejected

Approval group review

MPC signing

Blockchain submission

Confirmed

  1. Policy check – The engine evaluates the transaction against every applicable LIMIT rule (see Evaluation order). If any applicable rule rejects it, Ripple Custody (Wallet) rejects the transaction immediately and never sends it to approvers.
  2. Approval check – If a step-up approval rule fires, the rule's approvers must authorize the transaction, and they replace, rather than add to, the default approvers. Otherwise, if your organization configures approval groups for transactions, designated approvers must authorize it. The transaction stays in POLICY_CHECK_PENDING while approvers respond. When the amount exceeds its threshold, the most specific outbound TRAVEL_RULE rule that applies also holds the transaction until the Travel Rule exchange resolves, before signing. See Wallet-level transaction approvals.
  3. MPC signing – The wallet's MPC quorum signs the transaction.
  4. Blockchain submission – Ripple Custody (Wallet) publishes the signed transaction to the network.

See Governance and controls overview for how policies, approvals, and MPC quorums work together.

Evaluation order

Yes

No

Transaction submitted

Find matching policies

Policy 1: Check limit

Policy 2: Check limit

Policy N: Check limit

All policies pass?

Proceed to approvals/signing

Transaction rejected

Yes

No

Transaction submitted

Find matching policies

Policy 1: Check limit

Policy 2: Check limit

Policy N: Check limit

All policies pass?

Proceed to approvals/signing

Transaction rejected

For each wallet and asset, Ripple Custody (Wallet) sorts the enforcing LIMIT rules (status RULE_ENABLED or RULE_DELETION_APPROVAL_PENDING) into two groups:

  • Base rules have no matchers. They apply to outgoing transactions of the asset that no scoped rule matches. They never apply to cross-chain transactions, and a sign-for request needs a rule with a matching SIGN_FOR matcher. Some operations skip limit evaluation entirely. See Operations that bypass policies.
  • Scoped rules have one or more matchers, such as USER or COUNTERPARTY_ID. A scoped rule applies only when the transaction matches every one of its matchers.

The engine then evaluates the transaction:

  1. The engine selects which rules apply:
    • If at least one scoped rule matches the transaction, the scoped rules replace the base rules for that transaction, including base rolling and max-total-value rules.
    • If no scoped rule matches, the base rules apply.
    • If no rule applies, the engine rejects the transaction with PAL006.005.
  2. For each applicable rule, the engine checks whether the transaction would exceed the limit.
  3. If any applicable rule rejects the transaction, the entire transaction fails.
  4. If all applicable rules pass, the policy check continues with its remaining checks, such as the wallet's state, the destination counterparty address, and the available balance. Only if those pass does the transaction go on to approvals or signing.

Example: A wallet has a base per-transaction limit of 10 ETH, and a scoped per-transaction limit of 50 ETH for one API credential.

  • A 30 ETH transfer from that API credential passes. The scoped rule applies, so the base rule doesn't.
  • A 30 ETH transfer from any other initiator fails, because the base rule applies.

Network fees and policy limits

Ripple Custody (Wallet) 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 Ripple Custody (Wallet) can sweep it, and it doesn't evaluate sweep transactions against existing policies.

Other operations also skip limit evaluation: passkey transfers (including passkey raw transfers), WalletConnect (Web3) signing, plaintext signing, passkey signing, and token-management transaction types such as TokenCreate and TokenPause. As with sweeps, limits don't cap them, they don't wait for step-up approvers even above a step-up threshold, and Travel Rule rules don't hold them. Passkey raw transfers still need transaction approvers.

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 in the console. The Workflows card appears in Settings only when your organization has sweeping turned on and your role can read workflows, which includes the Owner, Administrator, and Auditor roles. An API credential of type TRANSACTIONS can also update, enable, disable, and trigger existing sweep configurations through the API, so issuing one delegates policy-free fund movements under those configurations.

See Asset sweeping for details on sweep configuration.

Transaction freeze is separate from policies

Transaction freeze controls apply to inbound transactions only (holding incoming funds for compliance review). Limit policies apply to outbound transactions only. The exception is inbound Travel Rule 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 transactions for that asset that no scoped policy matches, with the exceptions in Evaluation order.

Active matcher types include: TRANSACTION_TYPE, USER, API_CREDENTIAL, SIGN_FOR, COUNTERPARTY_ID, ALL_COUNTERPARTIES, ADDRESS_ID, WALLET_ID, and CHAIN_ID. APPROVAL rules don't support matchers. Use COUNTERPARTY_ID for counterparty destinations. The API rejects the older, deprecated COUNTERPARTY matcher.

See Policy reference 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:

StatusDescription
POLICY_CHECK_PENDINGRipple Custody (Wallet) is evaluating the transaction against policies. The transaction also waits here while it collects any required approvals.
POLICY_CHECK_PASSEDTransaction passed all policy checks and all required approvals.
REJECTEDA policy or approval rejected the transaction, it failed on-chain on an EVM chain, or it wasn't confirmed before it expired. When a policy rule or an approval outcome rejects it, the transaction's problems array carries a PAL006.xxx code, for example PAL006.005, PAL006.006, PAL006.044 (approval not met), or PAL006.045 (approval expired). Some rejections, such as approval failures, Travel Rule or screening verdicts, and a failure to record the policy decision, have a reason but no PAL006 code in problems. See How transactions work.
FAILEDA policy system error, for example when a service that a policy check depends on is unavailable, ends the transaction here instead of in REJECTED. The transaction's reason reads policy system error (<policy>): .... If you monitor only REJECTED, you miss these transactions. On the XRP Ledger, a transaction that fails on-chain also ends in FAILED.

These webhooks let you build automated monitoring for policy enforcement — for example, alerting on rejected transactions or tracking policy check latency. Because approvals happen in this stage, POLICY_CHECK_PENDING can last for the full approval window rather than milliseconds, so set any latency alerts accordingly. See Transaction status changes.

No policy lifecycle webhooks

Policies have no webhook events of their own for creation, approval, or deletion. Transaction webhooks cover status changes, and Ripple Custody (Wallet) also delivers wallet and approval events. To track policy lifecycle changes, use the Approval domain webhooks, which notify you when Ripple Custody (Wallet) creates or resolves approval requests for policy rules.

See Webhooks overview for setup instructions and payload format.

Next steps