DEV Community

L_X_1
L_X_1

Posted on • Originally published at policylayer.com

Custodial vs Non-Custodial: The Key Architecture Decision for AI Agent Wallets

Where should your AI agent's private keys live? This single decision determines your security model, regulatory exposure, liability structure, and operational complexity.

Get it wrong, and you either lose control of your funds or become responsible for custodying millions in customer assets.

The Two Models

Custodial: You Hold the Keys

In a custodial model, a service provider holds private keys on behalf of your agents.

┌─────────────────────────────────────────────────────┐
│                 Custodial Provider                   │
│                                                      │
│   ┌─────────┐    ┌─────────┐    ┌─────────┐        │
│   │ Agent A │    │ Agent B │    │ Agent C │        │
│   │  Keys   │    │  Keys   │    │  Keys   │        │
│   └─────────┘    └─────────┘    └─────────┘        │
│                                                      │
│   [HSM]  [Insurance]  [Compliance]  [Audit]        │
└─────────────────────────────────────────────────────┘
              ▲
              │ API calls
              │
┌─────────────────────────────────────────────────────┐
│                  Your Application                    │
│   Agent A        Agent B        Agent C             │
│   (no keys)      (no keys)      (no keys)           │
└─────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Examples: Fireblocks, Anchorage, BitGo, Copper

Non-Custodial: Agents Hold Their Own Keys

In a non-custodial model, your infrastructure controls the private keys directly.

┌─────────────────────────────────────────────────────┐
│                  Your Infrastructure                 │
│                                                      │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐│
│   │  Agent A    │  │  Agent B    │  │  Agent C    ││
│   │  + Keys     │  │  + Keys     │  │  + Keys     ││
│   │  + Policy   │  │  + Policy   │  │  + Policy   ││
│   └─────────────┘  └─────────────┘  └─────────────┘│
│                                                      │
│   [Your HSM/KMS]  [Your Controls]  [Your Audit]    │
└─────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Examples: Self-hosted wallets with PolicyLayer, MPC solutions you operate

The Trade-offs

Factor Custodial Non-Custodial
Key security Provider's responsibility Your responsibility
Regulatory burden Provider handles licensing May need your own licenses
Insurance Usually included You arrange separately
Latency API round-trip (50-200ms) Local signing (<10ms)
Control Limited to provider's features Full control
Vendor lock-in High (keys with provider) Low (your keys)
Cost Basis points on AUM Fixed infrastructure cost
Liability Shared with provider Entirely yours

When to Choose Custodial

You Should Use Custodial If:

1. You're holding customer funds

If your agents manage funds that belong to your users (not your company), custodial providers offer:

  • Regulatory compliance (MSB, MTA licenses)
  • Insurance against theft
  • Professional-grade security
  • Audit trails for regulators
// Customer funds → Custodial provider
const customerWallet = new CustodialProvider({
  apiKey: process.env.FIREBLOCKS_API_KEY,
  vaultId: 'customer-funds-vault'
});

// Agent requests withdrawal on behalf of customer
await customerWallet.createTransaction({
  amount: withdrawalAmount,
  destination: customerAddress,
  // Provider enforces their own limits
});
Enter fullscreen mode Exit fullscreen mode

2. You lack crypto security expertise

Key management is hard. HSMs, key ceremonies, backup procedures, rotation policies—one mistake and funds are gone forever.

Custodial providers employ teams of security specialists. Unless you can match that, outsource it.

3. You need institutional-grade insurance

Most custodians offer $100M+ insurance policies. Getting equivalent coverage independently is expensive or impossible.

4. Regulatory clarity is essential

If you're a regulated entity (bank, broker, fund), using a licensed custodian simplifies compliance. The custodian handles the crypto-specific regulations.

When to Choose Non-Custodial

You Should Use Non-Custodial If:

1. You're managing your own company's funds

If agents are spending your treasury (not customer funds), you don't need a licensed custodian. You're just managing your own money.

// Company funds → Self-custody with PolicyLayer
const companyWallet = new PolicyWallet(
  await createEthersAdapter(companyPrivateKey, rpcUrl),
  {
    apiKey: process.env.POLICYLAYER_API_KEY,
    metadata: {
      orgId: 'acme-corp',
      walletId: 'operations-treasury'
    }
  }
);

// Agent operates with policy-enforced limits
await companyWallet.send({
  chain: 'ethereum',
  asset: 'usdc',
  to: vendorAddress,
  amount: paymentAmount
});
Enter fullscreen mode Exit fullscreen mode

2. Latency matters

Custodial APIs add 50-200ms per transaction. For high-frequency trading or time-sensitive operations, that's too slow.

Non-custodial signing happens locally in under 10ms.

3. You need full control

Custodial providers decide:

  • Which chains they support
  • Which tokens they allow
  • What limits they impose
  • When they're available (maintenance windows)

Non-custodial means you control every aspect.

4. Cost scales with volume

Custodial pricing is typically basis points on AUM or per-transaction fees. At high volumes, this gets expensive.

Non-custodial has fixed infrastructure costs regardless of volume.

The PolicyLayer Approach: Non-Custodial + Controls

PolicyLayer is designed for the non-custodial model. You keep your keys; we provide the policy enforcement layer.

┌─────────────────────────────────────────────────────┐
│                  Your Infrastructure                 │
│                                                      │
│   ┌──────────────────────────────────────────────┐  │
│   │                PolicyLayer                    │  │
│   │   ┌────────────────────────────────────┐    │  │
│   │   │  Gate 1: Intent Validation         │    │  │
│   │   │  - Spending limits                 │    │  │
│   │   │  - Recipient whitelist             │    │  │
│   │   │  - Transaction frequency           │    │  │
│   │   └────────────────────────────────────┘    │  │
│   │   ┌────────────────────────────────────┐    │  │
│   │   │  Gate 2: Execution Verification    │    │  │
│   │   │  - Fingerprint match               │    │  │
│   │   │  - Single-use token                │    │  │
│   │   └────────────────────────────────────┘    │  │
│   └──────────────────────────────────────────────┘  │
│                         ▲                            │
│                         │                            │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐│
│   │  Agent A    │  │  Agent B    │  │  Agent C    ││
│   │  + Keys     │  │  + Keys     │  │  + Keys     ││
│   └─────────────┘  └─────────────┘  └─────────────┘│
│                                                      │
│   [Your KMS]                                        │
└─────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

What this gives you:

  • Keys never leave your infrastructure
  • Hard spending limits enforced before signing
  • Full audit trail of all transactions
  • Kill switch for emergencies
  • No basis-point fees on volume

What this doesn't give you:

  • Insurance (arrange separately)
  • Regulatory licensing (only needed for customer funds)
  • Key management (you handle this)

Hybrid Approach: When to Use Both

Some organisations use both models:

┌─────────────────────────────────────────────────────┐
│                      Customer Funds                  │
│                   (Custodial - Fireblocks)          │
│                                                      │
│   Withdrawals │ Deposits │ Cold Storage             │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│                    Company Operations                │
│                 (Non-Custodial + PolicyLayer)        │
│                                                      │
│   Trading │ DeFi │ Payments │ Refunds               │
└─────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Use custodial for:

  • Customer funds (regulatory requirement)
  • Long-term cold storage
  • Large institutional holdings

Use non-custodial for:

  • Operational treasury
  • High-frequency trading
  • DeFi interactions
  • Internal payments

Implementation: Non-Custodial with PolicyLayer

Step 1: Set Up Key Management

Store private keys securely using a KMS:

import { KMSClient, DecryptCommand } from '@aws-sdk/client-kms';

async function getPrivateKey(): Promise<string> {
  const kms = new KMSClient({ region: 'us-east-1' });

  const response = await kms.send(new DecryptCommand({
    CiphertextBlob: Buffer.from(process.env.ENCRYPTED_PRIVATE_KEY, 'base64'),
    KeyId: process.env.KMS_KEY_ID
  }));

  return Buffer.from(response.Plaintext!).toString('utf-8');
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Create Policy-Wrapped Wallet

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

const privateKey = await getPrivateKey();
const adapter = await createEthersAdapter(privateKey, rpcUrl);

const wallet = new PolicyWallet(adapter, {
  apiKey: process.env.POLICYLAYER_API_KEY,
  metadata: {
    orgId: 'acme-corp',
    walletId: 'trading-hot',
    agentId: 'arbitrage-bot'
  }
});
Enter fullscreen mode Exit fullscreen mode

Step 3: Configure Policy Limits

{
  "agentId": "arbitrage-bot",
  "limits": {
    "perTransactionLimit": "10000000000",
    "dailyLimit": "100000000000",
    "hourlyLimit": "25000000000",
    "maxTxPerHour": 100
  },
  "recipientWhitelist": [
    "0x...dex-router-1",
    "0x...dex-router-2"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Execute with Controls

// Every transaction goes through policy checks
const result = await wallet.send({
  chain: 'ethereum',
  asset: 'usdc',
  to: dexRouter,
  amount: tradeAmount
});

// PolicyLayer enforces:
// ✓ Amount within per-transaction limit
// ✓ Daily spend within budget
// ✓ Recipient in whitelist
// ✓ Transaction frequency acceptable
Enter fullscreen mode Exit fullscreen mode

Security Comparison

Custodial Security Model

Attack Vector Protection
Key theft HSMs, MPC, insurance
Insider threat Background checks, separation of duties
API compromise Rate limits, IP whitelisting, 2FA
Provider hack Insurance, distributed infrastructure

Non-Custodial + PolicyLayer Security Model

Attack Vector Protection
Key theft Your KMS/HSM, your security practices
Agent compromise Policy limits cap damage
Prompt injection Deterministic policy blocks bad transactions
Replay attacks Single-use tokens, fingerprinting

Key insight: Non-custodial doesn't mean "no controls." It means you implement the controls yourself—and PolicyLayer provides the enforcement layer.

Decision Framework

Do your agents handle customer funds?
├── YES → Use custodial provider
│         (Regulatory requirement, insurance needed)
│
└── NO → Agents manage company treasury
         │
         Is latency critical (under 50ms)?
         ├── YES → Non-custodial + PolicyLayer
         │
         └── NO → Do you have crypto security expertise?
                  ├── YES → Non-custodial + PolicyLayer
                  └── NO → Consider custodial for simplicity
Enter fullscreen mode Exit fullscreen mode

Related Reading


Ready to add controls to your non-custodial agents?

Top comments (0)