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

# Programmable Compliance

> How Metal enforces payment policies through policy contracts, proofs over private data, and signed offchain decisions

Metal lets institutions make their compliance policies part of payment
execution. A sending institution can restrict where value goes, while a
receiving institution can apply its own conditions for accepting it. Those
policies can use information recorded onchain, private data, or decisions from
an offchain service.

For public MIP20 transfers, institutions can use policy contracts to enforce
their rules. MIP410 connects policy to private payments through proofs,
allowing institutions to keep their rules and the information they evaluate
private.

## Policy at both ends of a payment

The two sides of a payment can enforce different rules. For example, the
sender's policy could limit the amount of an outgoing payment. The recipient's
policy could accept payments only from approved senders. Each institution
applies its own rules to its side of the payment.

### MIP20: send and receive policies

An institution uses a send policy contract to control spending from its
accounts. It can require evidence, such as a signed screening result, for
outgoing payments. Receive policy can restrict incoming senders, tokens,
amounts, and payment frequency.

A policy refusal can prevent the payment or put incoming funds in quarantine,
leaving the intended recipient unpaid.
[Send and Receive Policies](https://docs.metalntwx.com/learn/mip20/handlers-and-policy.md) explains where
policy contracts apply, how their checks execute, and what each transfer
outcome means.

### MIP410: private sender and recipient policies

MIP410 lets institutions apply payment policies while keeping the payment
details private. Each participating virtual asset service provider (VASP) has a
policy registered with the pool. The sender VASP prepares two proofs for
initiation, each establishing a different part of the payment's validity:

* The **sender proof** shows that the sender is authorized to spend the input
  notes, that the payment and any change preserve their value, and that the
  protocol's sender sanctions check passes.
* The **policy-wrapper proof** establishes that the sender VASP's registered
  policy approves the same payment. This applies the institution's own rules,
  such as payment limits or required records.

The pool verifies both proofs before creating a hold that reserves the notes.
The recipient VASP then evaluates the pending payment and proves that its
policy permits acceptance or rejection in a later transaction.

Acceptance spends the reserved notes and creates new notes for the recipient
and any change. Rejection makes the original notes available again without
spending them. The interval between initiation and resolution gives the
recipient time to receive private payment information and prepare its decision.

![The sender's payment and policy proofs for initiation. The sender proof checks spending authority, value conservation, and protocol sanctions rules. The sender VASP's policy proof checks its registered rules. The pool verifies both and reserves the notes in a hold. In a later transaction, the recipient VASP supplies proofs to accept or reject. Acceptance spends the notes and creates new ones. Rejection releases the input locks.](https://mintcdn.com/nexus-ed339086/RqZ8DjiF3RN_92qp/images/compliance/mip410-policy.svg?fit=max\&auto=format\&n=RqZ8DjiF3RN_92qp\&q=85\&s=8ee3a7fcedc33ffd4f82d2b819b33260)

Rejecting a payment is itself a policy decision that needs a valid proof. A
failed proof leaves the hold pending. If it expires without a decision,
[reclaim](https://docs.metalntwx.com/learn/mip410/shielded-payments.md#expiry-and-reclaim) makes the original
notes available again through a separate transaction.

The pool verifies that the VASP's registered policy permits this stage of the
payment. At initiation, the wrapper verifies registry membership and approval
without establishing that the signer serves the sender. At resolution, it
binds the approval to the hold's recipient VASP. The policy and its private
inputs remains hidden during verification.
[Privacy-Preserving Policy](https://docs.metalntwx.com/learn/mip410/privacy-preserving-policy.md) explains
how this works.

When value enters or leaves the shielded pool through shielding or unshielding,
MIP20 receive policy applies to the
[public transfer](https://docs.metalntwx.com/learn/mip20/handlers-and-policy.md#mip410-boundary). Shielding
and unshielding do not require a VASP policy wrapper.

## Combining checks into a policy

Policy primitives are reusable checks an institution can combine in one policy.
For example, an outgoing payment might need an approved destination, an amount
below a limit, and a signed decision from a screening service.

| Policy primitive | What it establishes |
| - | - |
| Allowlist and blocklist checks | A party is on an approved list or absent from a blocked list. |
| Amount and asset checks | A payment satisfies the rule for its token and amount. |
| Signature verification | A decision was signed by an accepted offchain service. |
| Record commitments | Private records are tied to the payment by a cryptographic value derived from them. |
| Proof verification | A check passed using private data without publishing that data. |

For MIP20, an institution can implement these checks in a send policy contract.
MIP410 policies express them in a circuit, a program whose execution can be
verified with a zero-knowledge proof. One policy may limit outgoing payment
amounts, while another requires a Travel Rule record for incoming payments
above a chosen amount. These rules express each institution's conditions for
sending or accepting value.

### Checking a sanctions list privately

MIP410 includes a sanctions check in its payment proofs. The pool's authority
maintains a list of identifiers for sanctioned shielded identities. A
cryptographic value called a Merkle root represents the list used for the
check. The proof establishes that the identifier being checked is absent from
that list. The circuit calculates the identifier from the payment's private
inputs, tying the check to the identity involved.

The pool checks that the proof uses a root it accepts. It can then enforce
the check without publishing the screened identity with the
payment. The proof establishes absence from that specific list.

An institution's policy can also check its own private list. The choice of
list matters as much as the check: an empty replacement would let everyone
pass. Specifying the list in the policy, or verifying its source, prevents that
replacement while allowing the list and the screened identity to remain
hidden.

## Connecting offchain decisions to execution

Offchain policy services bring an institution's private information into
payment decisions. Their required checks happen during payment preparation,
before the payment is submitted. A service evaluates customer records, risk
models, or the result of a manual review and signs a decision for the proposed
payment.  The sender then initiates the payment by calling the send policy
contract with the signed decision. The contract verifies that decision against
the outgoing rules before calling MIP20 to transfer funds. Missing required
evidence or an invalid signature makes the call revert. MIP20 then checks the
recipient's receive policy and credits the recipient if the rules accept the
payment.

![During payment preparation, an offchain service checks private records and signs a decision. The sender then calls the send policy contract, which verifies the decision before calling MIP20. The token calls the receive policy contract to check the recipient's rules. If accepted, the recipient receives the payment.](https://mintcdn.com/nexus-ed339086/RqZ8DjiF3RN_92qp/images/compliance/offchain-decision.svg?fit=max\&auto=format\&n=RqZ8DjiF3RN_92qp\&q=85\&s=6d88f8870ee959366e3eb20de1159b3a)

The send policy contract checks that the signature ties the decision to the
payment it describes. Changing the amount or recipient makes that approval
invalid. An expiry time can limit how long the decision remains valid, while a
record of its use prevents it from being used again. Together, these checks
let the contract enforce a decision made in another system while keeping the
underlying records there.

A signature establishes that the expected service signed the decision. A
zero-knowledge proof can also establish that a program performed its checks
correctly using private data. MIP410 uses this second mechanism to verify each
VASP's registered policy alongside the payment itself.

The information made public depends on how the decision is verified. Signed
evidence supplied to a policy contract for a MIP20 payment is public transaction
data, so the decision is visible even when its source records stay offchain.
A MIP410 policy proof can keep the data it checks and its internal results
private. The pool sees the proof and the cryptographic commitments linking it
to the payment.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.