DEV Community

L_X_1
L_X_1

Posted on • Originally published at policylayer.com

AI Agent Treasury Management: How to Structure Multi-Agent Wallets

Your AI agents need money to operate. They pay for API calls, execute trades, process refunds, and fund transactions. But how do you structure the treasury? One shared wallet? Individual wallets per agent? Something in between?

Get this wrong, and a single compromised agent drains everything. Get it right, and you have isolated blast radii with clear accountability.

The Treasury Problem

Most teams start with the simplest approach: one wallet, multiple agents.

┌─────────────────────────────────────────────┐
│           Shared Treasury Wallet            │
│              Balance: $500,000              │
├─────────────────────────────────────────────┤
│  Agent A  │  Agent B  │  Agent C  │  Agent D │
│  Trading  │  Refunds  │  Payroll  │  DeFi   │
└─────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Problems:

  1. No isolation: Agent A's bug can drain funds meant for Agent C's payroll
  2. No accountability: Which agent spent the $50k last Tuesday?
  3. No limits: Each agent has access to the full $500k
  4. Single point of failure: Compromise one agent, lose everything

The Solution: Tiered Treasury Architecture

A well-designed treasury uses multiple layers:

┌─────────────────────────────────────────────────────────┐
│                   Master Treasury                        │
│                    (Cold Storage)                        │
│                   Balance: $5,000,000                    │
│            Human-controlled, multisig required           │
└───────────────────────┬─────────────────────────────────┘
                        │ Manual refills only
        ┌───────────────┼───────────────┐
        ▼               ▼               ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│   Hot Wallet  │ │   Hot Wallet  │ │   Hot Wallet  │
│   Trading     │ │   Operations  │ │   DeFi        │
│   $100,000    │ │   $50,000     │ │   $200,000    │
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
        │                 │                 │
    ┌───┴───┐         ┌───┴───┐         ┌───┴───┐
    ▼       ▼         ▼       ▼         ▼       ▼
 Agent 1  Agent 2  Agent 3  Agent 4  Agent 5  Agent 6
 $10k/day $10k/day $5k/day  $5k/day  $50k/day $50k/day
Enter fullscreen mode Exit fullscreen mode

Key principles:

  1. Master treasury in cold storage — Human-controlled, requires multisig
  2. Hot wallets per function — Isolated pools for different use cases
  3. Agent limits per wallet — Daily caps enforced by PolicyLayer
  4. Manual refills only — Agents can never pull from master

Implementing with PolicyLayer

Step 1: Create Isolated Hot Wallets

// Each functional area gets its own wallet
const tradingWallet = await createWallet('trading-hot');
const opsWallet = await createWallet('operations-hot');
const defiWallet = await createWallet('defi-hot');

// Fund each from master treasury (manual process)
// Master -> Trading: $100,000
// Master -> Ops: $50,000
// Master -> DeFi: $200,000
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure Agent Policies

import { PolicyWallet, createEthersAdapter } from '@policylayer/sdk';

// Trading Agent 1 - Conservative strategy
const tradingAgent1 = new PolicyWallet(
  await createEthersAdapter(tradingWalletKey, rpcUrl),
  {
    apiKey: process.env.POLICYLAYER_API_KEY,
    metadata: {
      orgId: 'acme-corp',
      walletId: 'trading-hot',
      agentId: 'trading-agent-1',
      role: 'conservative-trader'
    }
  }
);

// Trading Agent 2 - Aggressive strategy (higher limits)
const tradingAgent2 = new PolicyWallet(
  await createEthersAdapter(tradingWalletKey, rpcUrl),
  {
    apiKey: process.env.POLICYLAYER_API_KEY,
    metadata: {
      orgId: 'acme-corp',
      walletId: 'trading-hot',
      agentId: 'trading-agent-2',
      role: 'aggressive-trader'
    }
  }
);
Enter fullscreen mode Exit fullscreen mode

Step 3: Set Per-Agent Limits

{
  "policies": [
    {
      "agentId": "trading-agent-1",
      "limits": {
        "perTransactionLimit": "1000000000",
        "dailyLimit": "10000000000",
        "hourlyLimit": "2500000000"
      }
    },
    {
      "agentId": "trading-agent-2",
      "limits": {
        "perTransactionLimit": "5000000000",
        "dailyLimit": "25000000000",
        "hourlyLimit": "10000000000"
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Even though both agents share the trading wallet, each has independent limits. Agent 1 can spend $10k/day. Agent 2 can spend $25k/day. Neither can exceed the wallet's total balance.

Budget Allocation Strategies

Strategy 1: Fixed Daily Budgets

Assign each agent a fixed daily limit. Simple and predictable.

{
  "agentId": "refund-bot",
  "limits": {
    "dailyLimit": "5000000000",
    "perTransactionLimit": "500000000"
  }
}
Enter fullscreen mode Exit fullscreen mode

Pros: Easy to understand, predictable costs
Cons: May underutilise budget on slow days, may hit limits on busy days

Strategy 2: Percentage-Based Allocation

Allocate budgets as percentage of wallet balance.

const walletBalance = await getWalletBalance(opsWallet);
const agentBudget = walletBalance * 0.1; // 10% of wallet per agent

await updateAgentPolicy('refund-bot', {
  dailyLimit: agentBudget.toString()
});
Enter fullscreen mode Exit fullscreen mode

Pros: Scales with treasury size
Cons: Requires dynamic policy updates, more complex

Strategy 3: Use-Case Budgets

Different limits for different operations.

{
  "agentId": "operations-bot",
  "limits": {
    "dailyLimit": "50000000000",
    "perTransactionLimit": "1000000000"
  },
  "operationLimits": {
    "refund": {
      "perTransactionLimit": "500000000",
      "dailyLimit": "10000000000"
    },
    "payroll": {
      "perTransactionLimit": "10000000000",
      "dailyLimit": "100000000000"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Pros: Fine-grained control per operation type
Cons: More complex policy configuration

Treasury Monitoring

Real-Time Dashboard

Track all agent spending in one view:

// Fetch treasury status
const treasuryStatus = await policyLayer.getTreasuryStatus({
  orgId: 'acme-corp'
});

console.log('Treasury Overview:');
for (const wallet of treasuryStatus.wallets) {
  console.log(`\n${wallet.name}:`);
  console.log(`  Balance: $${wallet.balance}`);
  console.log(`  Today's Spend: $${wallet.todaySpent}`);
  console.log(`  Active Agents: ${wallet.agents.length}`);

  for (const agent of wallet.agents) {
    const utilisation = (agent.todaySpent / agent.dailyLimit) * 100;
    console.log(`    ${agent.id}: ${utilisation.toFixed(1)}% of daily limit`);
  }
}
Enter fullscreen mode Exit fullscreen mode

Alerts

Configure alerts for treasury events:

await policyLayer.configureAlerts({
  orgId: 'acme-corp',
  alerts: [
    {
      type: 'wallet_balance_low',
      threshold: '10000000000', // $10k
      channels: ['slack', 'email']
    },
    {
      type: 'agent_daily_limit_approaching',
      threshold: 80, // percent
      channels: ['slack']
    },
    {
      type: 'unusual_spending_pattern',
      sensitivity: 'high',
      channels: ['pagerduty']
    }
  ]
});
Enter fullscreen mode Exit fullscreen mode

Emergency Procedures

Scenario 1: Single Agent Compromised

// Kill one agent immediately
await policyLayer.killSwitch.activate({
  scope: 'agent',
  agentId: 'compromised-agent',
  reason: 'Suspected compromise'
});

// Other agents continue operating
Enter fullscreen mode Exit fullscreen mode

Blast radius: Limited to that agent's remaining daily budget.

Scenario 2: Wallet Compromised

// Kill entire wallet (all agents using it)
await policyLayer.killSwitch.activate({
  scope: 'wallet',
  walletId: 'trading-hot',
  reason: 'Wallet key suspected compromised'
});

// Immediately rotate wallet keys
// Transfer remaining funds to new wallet
Enter fullscreen mode Exit fullscreen mode

Blast radius: Limited to that hot wallet's balance.

Scenario 3: Full Treasury Emergency

// Kill switch for entire organisation
await policyLayer.killSwitch.activate({
  scope: 'org',
  orgId: 'acme-corp',
  reason: 'Full security incident'
});

// All agent transactions blocked
// Master treasury unaffected (human-controlled)
Enter fullscreen mode Exit fullscreen mode

Blast radius: All hot wallets frozen. Master treasury safe.

Treasury Refill Process

Hot wallets need periodic refilling. Never automate this.

Manual Refill Checklist

## Hot Wallet Refill - [Date]

### Pre-Refill Checks
- [ ] Review past 7 days of agent activity
- [ ] Verify no anomalous spending patterns
- [ ] Confirm agent policies are current
- [ ] Check alert history for any flags

### Refill Decision
- [ ] Trading Wallet: Current $X, Refill to $Y
- [ ] Operations Wallet: Current $X, Refill to $Y
- [ ] DeFi Wallet: Current $X, Refill to $Y

### Approval
- [ ] Treasury Manager approval
- [ ] Multisig transaction signed
- [ ] Funds confirmed in hot wallets

### Post-Refill
- [ ] Update balance tracking
- [ ] Clear any low-balance alerts
Enter fullscreen mode Exit fullscreen mode

Never Automate Master → Hot Transfers

If an agent could trigger a refill from master treasury, a compromised agent could drain everything through repeated refill requests.

❌ Bad: Agent triggers refill when low
✅ Good: Human reviews and initiates refill
Enter fullscreen mode Exit fullscreen mode

Audit Trail

Every treasury movement should be logged:

interface TreasuryAuditEntry {
  timestamp: string;
  action: 'agent_spend' | 'refill' | 'policy_change' | 'kill_switch';
  walletId: string;
  agentId?: string;
  amount?: string;
  previousBalance: string;
  newBalance: string;
  authorisedBy: string; // agent ID or human user
  policyDecision?: {
    allowed: boolean;
    reason?: string;
  };
}
Enter fullscreen mode Exit fullscreen mode

Query audit history for compliance:

const auditLog = await policyLayer.getAuditLog({
  orgId: 'acme-corp',
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  filters: {
    walletId: 'trading-hot',
    minAmount: '1000000000' // $1k+
  }
});
Enter fullscreen mode Exit fullscreen mode

Related Reading


Ready to structure your agent treasury?

Top comments (0)