Off-chain interaction policies are guardrails you configure per agent from your backend (via @abstraxn/agent-kit). Agent Kit evaluates them before every MCP tool call — agents and LLMs cannot bypass them. Use interaction policies to restrict what on-chain actions an agent may attempt (contracts, calldata, recipients, amounts). For paid MCP tool budgets (x402), use spend policy instead. Operators can view policies in the dashboard under All agents → Policies (read-only). Create and update policies from your server via the SDK.

Interaction policy vs spend policy

Interaction policySpend policy
ScopeAll MCP tools when rules applyPaid x402 tools only
Configured viacreateInteractionPolicy, listInteractionPolicies, …updateSpendPolicy
Denial code-32404-32403
Example ruleMax 0.5 ETH per transfer$5 daily x402 budget
Enforcement order on tools/call:
  1. Interaction policy — all enabled policies must pass (AND).
  2. Spend policy — USD budget for paid tools.
  3. Tool execution — reads run directly; writes may need backend signing.

Who configures policies

Call policy CRUD from your server only — use your dashboard application API key or the agent’s agent.apiKey. Never expose these keys in the browser.
Map your authenticated user → agent.id from SDK quickstart, then attach one or more policies per agent.

Rule types

All rules are per-chain (for example ethereum, base, polygon). You can combine multiple rule types in a single policy.
RulePurposeExample
contractWhitelistOnly listed contract/mint addressesUSDC only on Ethereum
methodWhitelistOnly matching calldata patterns (* = hex wildcard)ERC-20 transfer(address,uint256)
recipientBlacklistBlock listed recipientsKnown scam addresses
nativeAmountLimitsMin/max native transfer amountMax 0.5 ETH
tokenAmountLimitsMin/max per token symbol or contractMax 1000 USDC
Policy fields:
FieldDefaultMeaning
enabledtrueWhen false, policy is skipped
hardBlocktrueWhen false, violations are advisory (logged but call proceeds)
If an agent has no enabled policies, all tool calls are allowed (subject to spend policy and signing).

SDK — create and manage policies

import { AgentKitClient } from '@abstraxn/agent-kit';

const agentKit = new AgentKitClient({
  apiKey: process.env.ABSTRAXN_API_KEY!,
});

const policy = await agentKit.createInteractionPolicy('agent-uuid-here', {
  name: 'transfer-guardrails',
  enabled: true,
  hardBlock: true,
  rules: {
    recipientBlacklist: [{
      chain: 'ethereum',
      addresses: ['0xBadAddress000000000000000000000000000001'],
    }],
    nativeAmountLimits: [{
      chain: 'ethereum',
      max: '0.5',
    }],
    contractWhitelist: [{
      chain: 'ethereum',
      addresses: ['0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'], // USDC
    }],
    methodWhitelist: [{
      chain: 'ethereum',
      contract: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
      // Full calldata pattern — length must match; * = any hex digit
      calldataPatterns: ['0xa9059cbb' + '*'.repeat(128)],
    }],
    tokenAmountLimits: [{
      chain: 'ethereum',
      token: 'USDC',
      max: '1000',
    }],
  },
});

const { items, total } = await agentKit.listInteractionPolicies('agent-uuid-here');

const one = await agentKit.getInteractionPolicy('agent-uuid-here', policy.id);

await agentKit.updateInteractionPolicy('agent-uuid-here', policy.id, {
  enabled: false,
});

await agentKit.deleteInteractionPolicy('agent-uuid-here', policy.id);

SDK methods

MethodPurpose
createInteractionPolicy(agentId, input)Create a policy
listInteractionPolicies(agentId)List all policies for an agent
getInteractionPolicy(agentId, policyId)Fetch one policy
updateInteractionPolicy(agentId, policyId, input)Update name, rules, or flags
deleteInteractionPolicy(agentId, policyId)Remove a policy

Authentication

CredentialScope
Application API key (dashboard Overview)All agents under your app
Per-agent agent.apiKey (from createAgent)That agent only

REST API

Same operations are available over REST if you prefer not to use the SDK:
MethodPath
POST/agents/:agentId/policies
GET/agents/:agentId/policies
GET/agents/:agentId/policies/:policyId
PATCH/agents/:agentId/policies/:policyId
DELETE/agents/:agentId/policies/:policyId
Base URL matches your Agent Kit host (same host as MCP without /mcp).

MCP denial (-32404)

When a tool call breaks a policy with hardBlock: true, MCP returns JSON-RPC error -32404:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32404,
    "message": "Interaction policy denied",
    "data": {
      "interactionPolicy": {
        "violations": [
          {
            "policyId": "uuid",
            "policyName": "transfer-guardrails",
            "reason": "recipient_blacklisted",
            "message": "Recipient 0x… is blacklisted",
            "hardBlock": true
          }
        ]
      }
    }
  }
}
Violation reason values:
ReasonMeaning
contract_not_whitelistedTarget contract not in contractWhitelist
method_not_whitelistedCalldata does not match any methodWhitelist pattern
recipient_blacklistedRecipient in recipientBlacklist
native_amount_below_minNative value below nativeAmountLimits.min
native_amount_above_maxNative value above nativeAmountLimits.max
token_amount_below_minToken amount below tokenAmountLimits.min
token_amount_above_maxToken amount above tokenAmountLimits.max
invalid_policy_configMalformed policy rules
See Troubleshooting — interaction policy denied for common fixes.

Method whitelist tips

  • Patterns are full hex calldata strings — include the 4-byte selector and encoded arguments.
  • Use * as a wildcard for any hex digit (0-9, a-f).
  • Pattern length must match the calldata you expect (pad with * for dynamic fields like addresses).
Example: ERC-20 transfer(address,uint256) selector is 0xa9059cbb, followed by 32-byte padded address and 32-byte amount — 136 hex chars after 0x for the arguments portion.

Which tools are evaluated

Interaction policy runs on MCP tools/call when the tool implies an on-chain interaction — for example transfer, token moves, and paid tools that settle on-chain. Read-only tools such as get_balance and discover_services are generally unaffected unless the tool extracts chain interaction context from arguments. When in doubt, test with a restrictive policy in dev and inspect -32404 violations in your dashboard activity logs.

Security checklist

  • Configure policies from your backend — not the browser.
  • Use multiple policies only when you need separate rule sets; remember all enabled policies must pass (AND).
  • Start with hardBlock: true in production; use advisory mode (hardBlock: false) only for shadow testing.
  • Pair policies with spend policy and ERC-8004 identity for full agent accountability.

Next steps