Skip to main content

Overview

Policies are rules-based controls that govern account and project operations in the CDP SDK. They allow you to accept or reject specific blockchain operations based on customizable criteria, providing security, compliance, and operational controls for your application.

What are Policies?

A policy is a collection of rules that are evaluated when operations like transactions or signatures are requested. Each rule specifies:
  • Operation type - What operation the rule applies to (e.g., sendEvmTransaction, signSolMessage)
  • Action - Whether to accept or reject matching operations
  • Criteria - Conditions that must be met for the rule to match
import { CdpClient } from "@coinbase/cdp-sdk";

const cdp = CdpClient.configureFromJson({
  filePath: "~/Downloads/cdp_api_key.json",
});

// Create a policy that limits ETH transfers to 0.1 ETH
const policy = await cdp.policies.createPolicy({
  scope: "account",
  description: "Limit ETH transfers to 0.1 ETH",
  rules: [
    {
      action: "reject",
      operation: "sendEvmTransaction",
      criteria: [
        {
          type: "ethValue",
          ethValue: "100000000000000000", // 0.1 ETH in wei
          operator: ">",
        },
      ],
    },
  ],
});

console.log(`Policy ID: ${policy.id}`);

Policy Scope

Policies can be applied at two levels:

Project-Level Policies

Apply to all accounts in your project. Only one project-level policy can exist at a time. Use cases:
  • Organization-wide security controls
  • Compliance requirements
  • Default restrictions for all operations
  • Network restrictions (e.g., only allow mainnet)
const projectPolicy = await cdp.policies.createPolicy({
  scope: "project",
  description: "Project-wide security controls",
  rules: [/* ... */],
});

Account-Level Policies

Apply to specific accounts. Multiple account-level policies can exist, each attached to different accounts. Use cases:
  • Per-user spending limits
  • Role-based access controls
  • Account-specific restrictions
  • Feature flags per account
const accountPolicy = await cdp.policies.createPolicy({
  scope: "account",
  description: "Account spending limit",
  rules: [/* ... */],
});

// Attach to account
const account = await cdp.evm.createAccount({
  name: "Limited Account",
  policyIds: [accountPolicy.id],
});
When an account has both a project-level and an account-level policy, both policies are evaluated. If either policy rejects an operation, it will be blocked.

Policy Types

EVM Transaction Policies

Control EVM transaction operations with various criteria:
Restrict transactions based on ETH value:
{
  action: "reject",
  operation: "sendEvmTransaction",
  criteria: [
    {
      type: "ethValue",
      ethValue: "1000000000000000000", // 1 ETH in wei
      operator: ">", // Reject transactions > 1 ETH
    },
  ],
}
Operators: >, >=, <, <=, ==
Allow or block specific recipient addresses:
{
  action: "accept",
  operation: "sendEvmTransaction",
  criteria: [
    {
      type: "evmAddress",
      addresses: [
        "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
        "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      ],
      operator: "in", // Only allow these addresses
    },
  ],
}
Operators: in, not in
Restrict operations to specific networks:
{
  action: "reject",
  operation: "sendEvmTransaction",
  criteria: [
    {
      type: "evmNetwork",
      networks: ["ethereum", "base"],
      operator: "not in", // Reject testnets
    },
  ],
}
Supported networks: base, base-sepolia, ethereum, ethereum-sepolia, optimism, arbitrum, polygon, avalanche, bnb, zora
Control contract interactions based on function calls and parameters:
{
  action: "reject",
  operation: "sendEvmTransaction",
  criteria: [
    {
      type: "evmData",
      abi: "erc20", // Or provide custom ABI
      conditions: [
        {
          function: "approve",
          params: [
            {
              name: "spender",
              operator: "not in",
              values: ["0x..."], // Blocked spenders
            },
          ],
        },
      ],
    },
  ],
}
Known ABIs: erc20, erc721, erc1155 or provide custom ABI
Limit transactions based on USD value:
{
  action: "reject",
  operation: "sendEvmTransaction",
  criteria: [
    {
      type: "netUSDChange",
      changeCents: 10000, // $100.00
      operator: ">",
    },
  ],
}
Note: USD values are calculated based on real-time price feeds

Message Signing Policies

Control message and typed data signing:
// Restrict EIP-191 message signing
{
  action: "accept",
  operation: "signEvmMessage",
  criteria: [
    {
      type: "evmMessage",
      match: "^I authorize.*", // Regex pattern
    },
  ],
}

// Restrict EIP-712 typed data signing
{
  action: "accept",
  operation: "signEvmTypedData",
  criteria: [
    {
      type: "evmTypedDataVerifyingContract",
      addresses: ["0x..."], // Allowed contracts
      operator: "in",
    },
  ],
}

Smart Account Policies

Control user operations for Account Abstraction:
{
  action: "reject",
  operation: "sendUserOperation",
  criteria: [
    {
      type: "ethValue",
      ethValue: "500000000000000000", // 0.5 ETH
      operator: ">",
    },
  ],
}

Solana Policies

Control Solana transactions and signatures:
{
  action: "reject",
  operation: "sendSolTransaction",
  criteria: [
    {
      type: "solValue",
      solValue: "1000000000", // 1 SOL in lamports
      operator: ">",
    },
  ],
}
{
  action: "accept",
  operation: "sendSolTransaction",
  criteria: [
    {
      type: "solAddress",
      addresses: ["7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV"],
      operator: "in",
    },
  ],
}
{
  action: "reject",
  operation: "sendSolTransaction",
  criteria: [
    {
      type: "programId",
      programIds: ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
      operator: "not in", // Block specific programs
    },
  ],
}

Supported Operations

OperationDescriptionAccount Type
signEvmTransactionSign EVM transactionsServer Account
sendEvmTransactionSend EVM transactionsServer Account
signEvmMessageSign EIP-191 messagesServer Account
signEvmTypedDataSign EIP-712 typed dataServer Account
signEvmHashSign arbitrary message hashesServer Account
prepareUserOperationPrepare ERC-4337 user opsSmart Account
sendUserOperationSend ERC-4337 user opsSmart Account
signSolTransactionSign Solana transactionsSolana Account
sendSolTransactionSend Solana transactionsSolana Account
signSolMessageSign Solana messagesSolana Account

Managing Policies

List Policies

const policies = await cdp.policies.listPolicies();

for (const policy of policies.policies) {
  console.log(`${policy.id}: ${policy.description}`);
  console.log(`Scope: ${policy.scope}`);
  console.log(`Rules: ${policy.rules.length}`);
}

Update Policies

const updated = await cdp.policies.updatePolicy({
  policyId: policy.id,
  description: "Updated description",
  rules: [
    // New rules
  ],
});
You cannot change a policy’s scope after creation. To change scope, delete and create a new policy.

Delete Policies

await cdp.policies.deletePolicy({ policyId: policy.id });

Use Cases

Implement per-account or project-wide spending limits:
  • Limit ETH/token transfers per transaction
  • Cap USD value of transactions
  • Control gas spending for smart accounts
Only allow transactions to approved addresses:
  • Treasury management (only send to known wallets)
  • Vendor payments (approved recipient list)
  • Internal transfers (company wallet allowlist)
Govern smart contract interactions:
  • Block dangerous functions (e.g., delegatecall)
  • Limit token approvals to specific spenders
  • Control NFT minting and transfers
Meet regulatory and security requirements:
  • Restrict testnet usage in production
  • Block sanctioned addresses
  • Enforce network restrictions
  • Prevent phishing via message signing controls

Policy Evaluation

When an operation is requested:
  1. All applicable policies are checked (project + account level)
  2. Rules are evaluated in order within each policy
  3. First matching rule determines the outcome
  4. If no rules match, the operation is allowed by default
  5. If any policy rejects, the entire operation is rejected
Order your rules from most specific to most general. The first matching rule wins!

Best Practices

  • Begin with restrictive policies in development
  • Gradually relax restrictions as you understand your needs
  • Test thoroughly on testnet before applying to mainnet accounts
  • Use project-level policies for organization-wide rules
  • Use account-level policies for user-specific restrictions
  • Combine multiple criteria for fine-grained control
  • Log rejected operations to understand policy effectiveness
  • Review and update policies regularly
  • Respond to security incidents by adjusting policies
  • Use descriptive policy descriptions
  • Maintain internal documentation of policy purposes
  • Communicate policy changes to affected teams

Limitations

  • Maximum 10 rules per policy
  • Maximum 300 addresses per address criterion
  • Project scope allows only one policy per project
  • Policy descriptions limited to 50 characters
  • Policies are evaluated synchronously and may add slight latency

Next Steps

Accounts

Learn about account types and policies

Transactions

Understand transaction lifecycle

Policy Management Guide

Step-by-step policy implementation

API Reference

Full API documentation for policies

Build docs developers (and LLMs) love