Coinbase Policy Engine API
The Policy Engine APIs evaluate policies (a set of rules) to govern the behavior of accounts or projects, such as enforce allowlists and denylists. - A **policy** is a collection of `rules` with defined criteria. - Each **rule** contains a specified `action`, `operation`, and `criteria`: - An `action` can either `accept` or `reject` a transaction if the criteria in the rule are met. - `criteria` is an array of logical expressions. All parameters must evaluate to true for the action to be applied. - An `operation` corresponds to a CDP v2 API: - `signEvmTransaction` or `signSolTransaction` for signing transactions (to set a transaction limit). - `sendEvmTransaction` for signing a transaction, and sending it to a supported network. - `signEvmHash` for signing an arbitrary 32 byte hash. - `signEvmMessage` for signing an [EIP-191](https://eips.ethereum.org/EIPS/eip-191) message. - `prepareUserOperation` for preparing user operations on a smart account. - `sendUserOperation` for sending user operations using a smart account. - `signEndUserEvmTransaction` or `signEndUserSolTransaction` for signing end user transactions (to set a transaction limit). - `sendEndUserEvmTransaction` for signing an end user transaction, and sending it to a supported EVM network. - `sendEndUserSolTransaction` for signing an end user transaction, and sending it to a supported Solana network. - `signEndUserEvmMessage` for signing an end user [EIP-191](https://eips.ethereum.org/EIPS/eip-191) message. - `signEndUserEvmTypedData` for signing end user [EIP-712](https://eips.ethereum.org/EIPS/eip-712) typed data. - `signEndUserSolMessage` for signing an end user Solana message. - A **rule** indicates how an operation should behave, specifying whether a request with defined criteria should be accepted or rejected. ## Policy Scope Policies can be applied at the project and/or account level: - **Project-level policy**: A `project`-level policy applies to all accounts in a CDP Project. Only one project-level policy can be applied to accounts within a CDP Project at any given time. - **Account-level policy**: An `account`-level policy applies to one or more accounts. An account can have at most one account-level policy at any given time. Thus, a single account can be assigned at most two policies at any given time: one project-level policy and one account-level policy. **Note:** End user operation rules (e.g., `signEndUserEvmTransaction`, `sendEndUserSolTransaction`) currently only apply for policies with the `project` scope. Scope is specified in the `scope` field of a policy: ```json { "description": "Project-level policy", "scope": "account", ... ``` ## Policy Evaluation A rule *targets* an operation when its `operation` field equals the requested operation. A rule *matches* when it targets the operation and all of its criteria are met (logical **AND**). Reject-over-accept precedence does not depend on rule order. For matching rules with the same action, the first in policy order applies. **Project-level policies** are evaluated first, followed by **account-level policies**. Within a policy, any matching `reject` rule rejects the request. Otherwise, any matching `accept` rule accepts it. If no rule in the project-level policy matches, the account-level policy is evaluated the same way, if one exists. A decision in the project-level policy is final. A `reject` rule overrides an `accept` rule only within the same policy, so an account-level `reject` rule does not override a matching project-level `accept` rule. If neither policy makes a decision, the request is accepted when no rule in either policy targets the operation, and rejected when at least one rule targets it. For example, this project-level policy accepts `signEvmTransaction` requests up to 2000000000000000000 wei, but rejects any request to `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`. A request to that address for 1 ETH matches both rules and is rejected regardless of their order. ```json { "description": "Project-level policy", "scope": "project", "rules": [ { "action": "accept", "operation": "signEvmTransaction", "criteria": [ { "type": "ethValue", "ethValue": "2000000000000000000", "operator": "", }, ], }, { "action": "reject", "operation": "signEvmTransaction", "criteria": [ { "type": "netUSDChange", "changeCents": 10000, "operator": ">", }, ], }, ], } ``` ### Limiting USDC Spend This policy restricts USDC transactions on the Base network to transfers of 10,000 tokens or less. It applies to both signing and sending transactions to the USDC contract address, using the ERC20 ABI to validate that only `transfer` function calls with a `value` parameter under the specified limit are permitted. ```json { "description": "Limit USDC Spend", "scope": "account", "rules": [ { "action": "accept", "operation": "sendEvmTransaction", "criteria": [ { "type": "evmNetwork", "networks": ["base"], "operator": "in" }, { "type": "evmAddress", "addresses": ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"], "operator": "in" }, { "type": "evmData", "abi": "erc20", "conditions": [ { "function": "transfer", "params": [ { "name": "value", "operator": "<=", "value": "10000" } ] } ] } ] }, { "action": "accept", "operation": "signEvmTransaction", "criteria": [ { "type": "evmAddress", "addresses": ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"], "operator": "in" }, { "type": "evmData", "abi": "erc20", "conditions": [ { "function": "transfer", "params": [ { "name": "value", "operator": "<=", "value": "10000" } ] } ] } ] } ] } ```.