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

# Declarative rules

> How rules written as conditions work: granular scopes, the layer fallback, allow style versus deny style, transaction and operation rules, and approvals.

> [!NOTE]
>
> Declarative rules are in **early access** and are not enabled by default. [Talk to us](https://www.dynamic.xyz/talk-to-us) if you'd like to participate.

Declarative rules describe what a request must look like (a condition) and what happens when it does (an outcome), instead of using fixed legacy rule types such as an allowlist or a value limit. The condition is a small tree of comparisons. Because you build the condition yourself, one rule can combine the chain, the network, the token, the amount, the destination, and what the wallet has already spent recently. For example, a single rule can say "on Ethereum mainnet, deny any transfer of more than 5,000 USDC to an address outside this list".

Each rule says "when this condition is true, do this", where "this" is allow, deny, or require approval. Rules live in [policy layers](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/policy-layers.md): the business account layer, the wallet layer, and the signer layer. Every layer that covers a wallet is checked, and a request goes through only if no layer refuses it. A layer can therefore only narrow what the other layers permit.

Rules written with the legacy rule types keep working unchanged. A layer holds either legacy rules or declarative rules, never both.

## The fallback

The fallback is what a layer does when none of its rules match a transaction. There are two choices:

* **Allow (the default).** With no fallback, a transaction that matches nothing goes through.
* **Deny.** You add a final catch-all deny rule whose condition is always true, and a transaction that matches nothing is refused.

The fallback covers transactions only. Wallet actions, such as exporting a private key, are permitted unless a rule denies them.

## Deny style and allow style

The fallback decides how the rest of the layer has to be written.

| | Deny style | Allow style |
| - | - | - |
| The rules name | What is forbidden | What is permitted |
| Rules use | Deny | Allow |
| Fallback | None | Deny |
| Anything not mentioned | Goes through | Is refused |
| Good for | Carving a few exceptions out of an open wallet | Locking a wallet to a known job |

Choose deny style when the wallet should generally work and you want to block specific things, such as an address, a large amount, or an unwanted token. Choose allow style when the wallet does one job and everything else should fail, such as paying USDC to a fixed list of vendors.

### Why the two styles do not mix

The two styles are not compatible, because of how the engine decides. A deny rule can only refuse, and an allow rule can only rescue a transaction from the fallback. Neither one does anything outside its own condition.

* **A deny fallback under deny rules refuses everything.** Take a wallet whose only rule is "deny anything above 5 ETH" and add a deny fallback. A 1 ETH transfer does not match the rule, so nothing permits it, and the fallback refuses it. The layer now refuses the very transfers the rule was written to let through.
* **Allow rules without a deny fallback permit everything.** Take a wallet whose only rule is "allow up to 100 USDC" and remove its deny fallback. A 10,000 USDC transfer does not match the rule, but an allow rule never forbids anything on its own, so the default fallback permits it.

### How a layer decides

The order you write rules in does not matter. If any deny rule matches, the transaction is refused, because a matching deny always beats a matching allow. Otherwise, if any allow rule matches, the transaction is permitted. Otherwise, the fallback decides.

Require approval is a third outcome. A matching approval rule holds a transaction the layer would otherwise permit until enough approvers sign off. It never permits anything by itself, so in allow style it only applies to transactions that an allow rule also permits.

## Transaction rules and operation rules

Every rule belongs to one of two phases.

| | Transaction rules | Operation rules |
| - | - | - |
| Cover | Money moving on a chain | Wallet actions: exporting the private key, revoking delegated access, signing from the client |
| Can look at | Chain, network, assets and amounts, destinations, spending over a recent window | Only which action is being attempted |
| Outcomes | Allow, deny, require approval | Deny, require approval |
| Fallback | Optional deny fallback | None |

An operation rule is a single comparison on the action, with no transaction details available. Of the wallet actions, only exporting the private key can require approval. A spend limit over time can only deny.

## Approvals

An approval rule names who may approve, how many approvals are needed, and optionally a deadline, which defaults to 30 days. The person who made the request does not count toward the total. Approvers are identified by role: `owner`, `admin`, `viewer`, or any role your business account defines, where a custom role also counts as the built-in role it inherits. Dynamic does not check that a role exists, so naming a role nobody holds means the request can never be approved. Approval rules are available on the layers of business-account wallets.

## Where each layer is written

| Layer | Who writes it | API | SDK |
| - | - | - | - |
| Environment | An environment admin | [Environment layer](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/environment-layer.md) | Not available |
| Business account | A business-account owner or admin | [Account layer](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/account-layer.md) | [Declarative rules for business accounts](https://www.dynamic.xyz/docs/javascript/reference/business-accounts/policies/declarative-rules.md) |
| Wallet | The wallet owner, or a business-account owner or admin for a business-account wallet | [Wallet layer](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/wallet-layer.md) | [Manage declarative rules](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/manage-policies-declarative.md) |
| Signer | The signer, the wallet owner, or a business-account owner or admin | [Signer layer](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/signer-layer.md) | [Manage declarative rules](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/manage-policies-declarative.md) |

## Next steps

> **[Rule anatomy](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/rule-anatomy.md)**
>
> Rule fields, the fallback rule, and approval requirements.

> **[Rule examples](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/rule-examples.md)**
>
> A ready-made rule for each common case, and two whole layers.

> **[Advanced conditions](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/advanced-conditions.md)**
>
> Operators, lists, matching every item, and combined flows.

> **[Policy layers](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/policy-layers.md)**
>
> How the business account, wallet, and signer layers combine.


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