"transaction denied: No policies found for wallet", HTTP 403). Inbound deposits are independent of policies: an on-chain address can always receive crypto regardless of the wallet’s governance.
Policies are versioned, mutable resources. You attach them to wallets, and a wallet can have multiple policies layered on top of one another. The policy engine evaluates all attached policies for every transaction and applies the result.
Anatomy of a Policy
A policy is three things:- A signer group that governs the policy itself. Future mutations of the policy — adding rules, deleting it, updating limits — must be signed by members of this group via the endorsed-request flow. It can be the same group attached to the wallet, or a separate admin group for stricter compartmentalization.
- One or more rules. Each rule has a
rule_type, anaction(allowordeny), and adefinitionwhose shape depends on the rule type. - Metadata. A human-readable
nameand optionaldescription.
Rule Types
There are three rule types. Each evaluates a different aspect of the transaction.approval_threshold
Requires a minimum number of valid signatures from the policy’s signer group.
threshold— minimum number of signers required.- The rule always applies to every transaction (it’s a count check, not a conditional).
- If the threshold is met → emit the rule’s
action(allow or deny). If not met → emit the inverted action.
approval_threshold with threshold: 1 and action: allow.
amount_threshold
Requires a minimum number of approvals once a transaction reaches a value you name. Useful for tiered approval — small transfers single-sig, large transfers multi-sig.
asset— required; there is no way to omit it.idis the asset symbol —USDC,USDT, orRD— and is stored upper case. A missing asset, or anidthat is empty orany, is rejected with400. You may also passname, a display label that plays no part in matching and can be left out entirely.min_amount— integer,0or greater, in the asset’s smallest unit. USDC has 6 decimals, so the10000000000above is 10,000 USDC.threshold— number of approvals required,1or greater. Athresholdof0is rejected with400.- The rule applies only when the transaction moves
assetand its amount is at or abovemin_amount. Belowmin_amountthe rule does not apply (does not contribute allow or deny). - The rule matches on the asset symbol, so it governs that asset on every network unless the stored asset names one. Amounts are compared in the asset’s smallest unit.
- When the rule applies: if the transaction carries at least
thresholdapprovals → emit the rule’saction. If it carries fewer → emit the inverted action. So the example above allows a transfer of 10,000 USDC or more only when two signers approve, and denies it otherwise.
address_list
Restricts which on-chain destinations a wallet can send to. Allow-list (only these) or deny-list (block these).
- The rule applies only when the destination address is in the
addresseslist. - For an allow-list, set
action: allowand pair with a default-deny in another rule (or rely on the policy engine’s default-deny on no-applicable-policy). - For a deny-list, set
action: denyand the listed addresses are blocked outright.
Evaluation Order
For a given transaction, the policy engine:- Loads every policy attached to the wallet. If zero policies, return
denyimmediately ("No policies found for wallet"). - For each policy, evaluates each rule in turn. A rule produces one of: applied + allow, applied + deny, or not-applicable.
- Aggregates per policy: if any rule denies → policy = deny. Else if any rule allows → policy = allow. Else (no rule applied) → policy = not-applicable.
- Aggregates across policies: if any policy denies → transaction = deny. Else if any policy allows → transaction = allow. Else (no applicable policy) → transaction = deny (default).
Lifecycle
Policy creation itself is not endorsed — it’s a regular API request authenticated only by your API key. Once the policy exists, every subsequent mutation goes through the endorsed-request flow: canonicalize the intent per RFC 8785 JCS, sign with ECDSA P-256, encode as DER + base64.
Practical Examples
”Default permissive” — single signature, no restrictions
For sandbox testing or low-risk accounts:“Tiered approval by amount” — single-sig under $10k, dual-sig above
amount_threshold rule does not apply, so a single signature is enough. At or above it the rule applies and emits allow only once two signers have approved — with one signature it emits the inverted action, and deny wins.
”Sanctions deny-list” — block specific addresses outright
Related
- Common Flows — Create a Policy — happy-path curl walk-through.
- Wallet Transaction Signing — endorsed-request flow for mutating an existing policy or attaching/detaching to a wallet.
- Wallets — architectural overview of signer groups, policies, and intents.

