Skip to Content

Permission an AI agent

An AI agent that acts onchain is a role member with a special property: you must assume that its key will misbehave. Prompt injection, software defects, and key theft all end in the same event — the agent sends a transaction that you did not want.

The Roles Modifier is built for this case. It enforces the limits at the account level, onchain. The role defines what the agent’s key can do at all. Design the role so that a fully compromised agent stays affordable.

Rules in the agent’s prompt are requests. The agent can ignore them. The Roles Modifier enforces its rules onchain, on every call. Use both layers, but only trust the second one.

Prerequisites: a Safe with a Roles Modifier, set up as in the Roles quickstart.

An agent runtime has no browser for the sign-in of bun pull. Write an existing API key to .env as ZODIAC_API_KEY instead. The key writes workspace drafts only; onchain changes still need the Safe signature.

The pattern

  1. Give the agent its own address.
  2. Assign a dedicated role with pinned venues.
  3. Meter the role with allowances.
  4. Route high-impact actions through a Delay Modifier.
  5. Watch the role and prepare the revoke transaction.

Step 1: give the agent its own address

The agent signs with an address that exists only for this purpose: an externally owned account whose key lives in the agent runtime, or a smart account. Do not reuse the address for anything else.

Never give an agent a Safe owner key, and never make the agent’s address an owner. An owner signs for everything. A role member can only use its role.

Step 2: assign a dedicated role

Create a separate role, for example agent_ops. Do not add the agent to a role that humans use — you want to tune and revoke it independently.

Scope the role to the exact venues and functions the agent needs, with conditions that pin recipients to the Safe. Presets from DeFi Kit carry safe defaults for common protocols:

import { defikit } from '@zodiaceco/sdk/actions' import type { Permissions } from '@zodiaceco/sdk' export default [ defikit.aave_v3.deposit({ label: 'Lend on Aave', market: 'Core', targets: ['WETH', 'USDC'], }), ] satisfies Permissions

For token swaps, use order-based venues: the SDK’s swap() action creates permissions for CoW Protocol order signing with pinned sell and buy token lists. To find the minimal permission set for a new workflow, record a real session with Zodiac Pilot and derive the permissions from the recording.

Step 3: meter the role with allowances

An allowance limits how fast an agent can spend. Give an agent role two meters:

  • A budget. Meter transfer and deposit amounts with WithinAllowance, for example 10,000 USDC per day. See Allowances for the exact values.
  • A rate limit. Meter the number of calls with CallWithinAllowance, for example 10 calls per hour. A looping agent then stops early, before it drains a budget.

An allowance limits amounts, not destinations. Always combine it with conditions on the recipient, such as EqualToAvatar.

Step 4: route high-impact actions through a Delay

Point the target of the agent’s Roles Modifier at a Delay Modifier. Every action then waits in a queue, and the Safe owners can cancel it during the cooldown. The Delay quickstart shows the setup.

When the agent needs both speed and reach, split the lanes: deploy two Roles Modifiers. The fast lane targets the Safe and carries only low-risk permissions. The slow lane targets the Delay Modifier and carries the high-impact permissions. The agent is a member of both roles.

Step 5: watch the role and prepare the revoke

  1. Subscribe to the TransactionAdded event of the Delay Modifier and to the execution events of the Safe. Alert a human on every queued transaction.
  2. Prepare the kill switch before you need it: a signed-but-unsent Safe transaction with assignRoles(agentAddress, [roleKey], [false]). One execution removes all power of the agent.
  3. Rehearse the revoke once, like the cancel path of the Delay Modifier.

Test before you connect funds

Run the agent against a test Safe on a testnet or a fork first. Give it the real role configuration and let it work. Every ConditionViolation revert in the test log is a permission you must decide on — widen the role or change the agent, before real assets are behind it.

Limits, and the road ahead

Conditions check calldata, not outcomes. A role cannot see prices or slippage. Prefer venues where the order parameters carry the protection, and keep budgets small enough that a bad trade stays affordable.

Roles v3 develops features that fit agent setups: session keys, roles that expire, and a WithinRatio operator for slippage protection. See the v3 preview — the plans can change.

Next steps

Last updated on