DEV Community

Cover image for 21 Policy Types + 4 Security Tiers: Complete AI Agent Risk Management
Wallet Guy
Wallet Guy

Posted on

21 Policy Types + 4 Security Tiers: Complete AI Agent Risk Management

21 Policy Types + 4 Security Tiers: Complete AI Agent Risk Management

Giving an AI agent a wallet without guardrails is like giving a toddler a credit card — the agent might have the best intentions, but without hard limits, one bad decision can drain your funds in seconds. If you're building applications where AI agents control crypto wallets, the security architecture you choose isn't a configuration detail. It's the difference between a working product and a catastrophic loss event.

Why This Actually Matters

The promise of autonomous AI agents handling on-chain operations is real. Agents that rebalance DeFi positions, pay for API calls, execute trades, and manage multi-chain assets without constant human intervention can genuinely reduce overhead and enable new product categories. But "autonomous" and "unsupervised" are not the same thing. An agent that can send arbitrary transactions to arbitrary addresses, approve unlimited token spending, or take leveraged perpetual positions without constraint is not a product — it's a liability.

The core challenge is that crypto transactions are irreversible. A policy violation in a traditional financial system gets reversed and flagged. An on-chain transfer that shouldn't have happened is permanent. Your security model needs to account for this asymmetry, which means shifting enforcement as far left as possible — before transactions execute, not after.

WAIaaS approaches this with three distinct layers of security, a policy engine with 21 policy types across 4 security tiers, and a default-deny enforcement model. This post breaks down exactly how those mechanisms work.

Layer 1: Three Auth Roles, Separated by Purpose

The first layer is authentication separation. WAIaaS uses three distinct auth methods, each with a specific scope:

# masterAuth — system administrator (wallet creation, session management, policies)
-H "X-Master-Password: my-secret-password"

# sessionAuth — AI agent (transactions, balance queries, DeFi actions)
-H "Authorization: Bearer wai_sess_eyJhbGciOiJIUzI1NiJ9..."

# ownerAuth — fund owner (transaction approval, kill switch recovery)
-H "X-Owner-Signature: <ed25519-or-secp256k1-signature>"
-H "X-Owner-Message: <signed-message>"
Enter fullscreen mode Exit fullscreen mode

The three roles are:

  • masterAuth uses Argon2id password hashing. This is the system administrator role — it creates wallets, manages sessions, and sets policies. Your AI agent never holds this credential.
  • sessionAuth uses JWT HS256 tokens. This is what your AI agent actually uses at runtime. Session tokens have per-session TTL, maxRenewals, and absoluteLifetime configuration, so a compromised or runaway session has a bounded lifespan.
  • ownerAuth uses SIWS/SIWE signatures (ed25519 or secp256k1). This is the fund owner — the human who approves high-value transactions or recovers from a compromised state.

The separation matters because it prevents privilege escalation. An AI agent holding only a session token cannot create new wallets, modify policies, or approve its own transactions. Those operations require credentials the agent was never given.

Layer 2: The Policy Engine — 21 Types, 4 Tiers, Default-Deny

The second layer is where most of the runtime risk management happens. WAIaaS implements 21 policy types organized into 4 security tiers. Every transaction goes through a 7-stage pipeline (validate → auth → policy → wait → execute → confirm), and the policy stage is where enforcement happens.

Default-Deny Is Not a Setting — It's the Default

This is the most important thing to understand about the policy engine. When ALLOWED_TOKENS or CONTRACT_WHITELIST is not configured, those transaction types are blocked by default. Your agent cannot interact with tokens or contracts you haven't explicitly allowed. There is no opt-in required to enable this behavior — you have to explicitly opt-out by configuring what's permitted.

The 4 Security Tiers

Every policy that evaluates transaction amounts assigns one of four tiers:

INSTANT   — Execute immediately, no notification
NOTIFY    — Execute immediately, send notification to owner
DELAY     — Queue for delay_seconds, then execute (cancellable window)
APPROVAL  — Require explicit human approval via WalletConnect/Telegram/Push
Enter fullscreen mode Exit fullscreen mode

The SPENDING_LIMIT policy is the clearest illustration of how tiers compose:

curl -X POST http://127.0.0.1:3100/v1/policies \
  -H "Content-Type: application/json" \
  -H "X-Master-Password: my-secret-password" \
  -d '{
    "walletId": "<wallet-uuid>",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'
Enter fullscreen mode Exit fullscreen mode

With this configuration: transactions under $100 execute immediately, $100–$500 execute immediately but notify you, $500–$2,000 queue for 15 minutes (during which you can cancel), and anything above $2,000 requires your explicit approval before it moves. The daily_limit_usd field caps aggregate daily spend regardless of individual transaction amounts.

This graduated response is what lets you give an agent real operational latitude for routine work while keeping a human in the loop for material decisions.

The Full 21 Policy Types

Here's what you actually have available:

SPENDING_LIMIT          — Amount-based 4-tier security
WHITELIST               — Allowed recipient addresses
TIME_RESTRICTION        — Allowed transaction hours
RATE_LIMIT              — Max transactions per period
ALLOWED_TOKENS          — Token transfer whitelist (default-deny)
CONTRACT_WHITELIST      — Contract call whitelist (default-deny)
METHOD_WHITELIST        — Allowed function selectors
APPROVED_SPENDERS       — Token approval whitelist (default-deny)
APPROVE_AMOUNT_LIMIT    — Max approve amount, block unlimited
APPROVE_TIER_OVERRIDE   — Force tier for APPROVE transactions
ALLOWED_NETWORKS        — Network restriction
X402_ALLOWED_DOMAINS    — x402 payment domain whitelist
LENDING_LTV_LIMIT       — Max loan-to-value ratio for DeFi lending
LENDING_ASSET_WHITELIST — Allowed lending assets
PERP_MAX_LEVERAGE       — Max perpetual futures leverage
PERP_MAX_POSITION_USD   — Max position size in USD
PERP_ALLOWED_MARKETS    — Allowed perpetual markets
REPUTATION_THRESHOLD    — ERC-8004 onchain reputation threshold
ERC8128_ALLOWED_DOMAINS — ERC-8128 HTTP signing domains
VENUE_WHITELIST         — Allowed trading venues
ACTION_CATEGORY_LIMIT   — DeFi action category limits
Enter fullscreen mode Exit fullscreen mode

A few of these deserve specific attention from a risk management perspective.

APPROVE_AMOUNT_LIMIT and APPROVED_SPENDERS address one of the most common DeFi attack vectors: unlimited token approvals. An agent that can issue approve(spender, type(uint256).max) to arbitrary addresses is a standing invitation to drain your wallet if any integrated protocol is compromised. APPROVE_AMOUNT_LIMIT blocks unlimited approvals outright, and APPROVED_SPENDERS restricts approval targets to an explicit whitelist with per-spender max amounts — both enforced by default-deny.

PERP_MAX_LEVERAGE and PERP_MAX_POSITION_USD constrain what an agent can do in perpetual futures markets. A trading agent with access to Hyperliquid (one of the 15 integrated DeFi protocols) could theoretically take on extreme leverage without these guardrails. These two policies put a hard ceiling on both the leverage multiplier and the absolute USD position size.

LENDING_LTV_LIMIT is the DeFi lending equivalent. If your agent is managing positions on Aave v3 or Kamino, this policy prevents it from borrowing to a loan-to-value ratio that would put the position at liquidation risk under normal market conditions.

TIME_RESTRICTION and RATE_LIMIT** are simpler but often overlooked. Restricting transactions to business hours and capping transactions per period are cheap controls that significantly reduce the blast radius if an agent behaves unexpectedly. An agent that can only send 10 transactions per hour during UTC business hours, even if fully compromised, causes bounded damage.

X402_ALLOWED_DOMAINS handles a specific use case: agents that autonomously pay for API calls using the x402 HTTP payment protocol. Without this policy, an agent could theoretically be prompted into paying arbitrary endpoints. With it, auto-payments are restricted to domains you've explicitly approved.

Layer 3: Human Approval Channels

When a transaction is assigned the APPROVAL tier, it doesn't fail — it waits. The third security layer is the set of channels through which you, as the fund owner, receive the approval request and respond.

WAIaaS includes three signing channels: push-relay, Telegram, and WalletConnect. When an approval-tier transaction is queued, you receive a notification through your configured channel with the transaction details. You approve or reject it using ownerAuth — the cryptographic signature tied to your wallet address, not a password that could be intercepted.

# Approve a pending transaction using ownerAuth
curl -X POST http://127.0.0.1:3100/v1/transactions/<tx-id>/approve \
  -H "X-Owner-Signature: <ed25519-or-secp256k1-signature>" \
  -H "X-Owner-Message: <signed-message>"
Enter fullscreen mode Exit fullscreen mode

The WalletConnect integration is particularly relevant here — it means you can approve transactions from a standard Web3 wallet interface without running any additional software.

Simulate Before You Execute

One more mechanism worth highlighting: the dry-run API. Before any transaction executes, your agent (or your infrastructure) can simulate it to see what would happen:

curl -X POST http://127.0.0.1:3100/v1/transactions/send \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer wai_sess_<token>" \
  -d '{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'
Enter fullscreen mode Exit fullscreen mode

Setting dryRun: true runs the transaction through the full pipeline — including policy evaluation — without executing it on-chain. This is useful for testing policy configurations before deploying them, and for agents that want to check whether a transaction would be approved before committing to it.

Quick Start: Setting Up Security-First

Here's the minimal path to a security-configured agent:

Step 1: Install and initialize

npm install -g @waiaas/cli
waiaas init
waiaas start
Enter fullscreen mode Exit fullscreen mode

Step 2: Create a wallet

curl -X POST http://127.0.0.1:3100/v1/wallets \
  -H "Content-Type: application/json" \
  -H "X-Master-Password: my-secret-password" \
  -d '{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'
Enter fullscreen mode Exit fullscreen mode

Step 3: Configure your baseline policies — spending limit, allowed tokens, and contract whitelist at minimum. Without ALLOWED_TOKENS and CONTRACT_WHITELIST, your agent is operating under default-deny for those transaction types, which is actually the safe starting state.

# Spending limit with 15-minute delay window for mid-size transactions
curl -X POST http://127.0.0.1:3100/v1/policies \
  -H "Content-Type: application/json" \
  -H "X-Master-Password: my-secret-password" \
  -d '{
    "walletId": "<wallet-uuid>",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Step 4: Create a session for your agent

curl -X POST http://127.0.0.1:3100/v1/sessions \
  -H "Content-Type: application/json" \
  -H "X-Master-Password: my-secret-password" \
  -d '{"walletId": "<wallet-uuid>"}'
Enter fullscreen mode Exit fullscreen mode

Step 5: Give the session token (and only the session token) to your agent. The agent cannot modify policies, create new sessions, or approve its own transactions with this credential.

What a Policy Violation Looks Like

When a transaction is blocked by policy, the response is explicit about why:

{
  "error": {
    "code": "POLICY_DENIED",
    "message": "Transaction denied by SPENDING_LIMIT policy",
    "domain": "POLICY",
    "retryable": false
  }
}
Enter fullscreen mode Exit fullscreen mode

The domain and code fields are structured, so your agent can handle policy denials programmatically — logging them, alerting a human operator, or adjusting its strategy — rather than treating them as generic errors.

The Architecture in Summary

Three layers, working together:

  1. Auth separation ensures your agent never holds credentials that could modify its own constraints or approve its own high-value transactions.
  2. The policy engine enforces 21 policy types with default-deny on critical transaction categories, and assigns every evaluated transaction to one of four security tiers that determine whether it executes immediately, notifies you, waits, or requires approval.
  3. Human approval channels (WalletConnect, Telegram, push notifications) give you a cryptographically authenticated path to approve or reject queued transactions without requiring you to be directly connected to the system.

None of this eliminates risk entirely — no security architecture does. But it makes the risk surface explicit, bounded, and auditable, which is the realistic goal when you're deploying autonomous agents against live funds.

What's Next

The policy configuration covered here is the security foundation. From there, you'll want to look at how WAIaaS integrates with AI agent frameworks via its 45 MCP tools, and how the TypeScript and Python SDKs let you build agents that handle policy-tier responses gracefully. The GitHub repository has the full source for all 21 policy types and the transaction pipeline stages, and the interactive API reference at /reference once you're running lets you explore every endpoint with live requests.

If you're serious about deploying AI agents with wallets in production, start with the policy engine — it's the part you can't retrofit after something goes wrong.

→ WAIaaS on GitHub — open-source, self-hosted, full source available
→ WAIaaS official site — documentation and quickstart guides

Top comments (0)