21 Policy Types for AI Agent Security: How WAIaaS Puts Guardrails on Crypto Wallets
Giving an AI agent a wallet without guardrails is like giving a toddler a credit card — the intent might be good, but the outcomes can be catastrophic. AI agent security in crypto is not a solved problem, and most developers building autonomous on-chain agents are one misconfigured prompt away from watching their funds disappear. WAIaaS is an open-source, self-hosted Wallet-as-a-Service that approaches this problem seriously: default-deny policies, 3-layer authentication, and explicit human approval channels sit between your agent and your funds at all times.
The Real Risk of Autonomous Agents with Wallets
Autonomous AI agents are increasingly useful for on-chain tasks — arbitrage, yield farming, portfolio rebalancing, paying for API access. But the moment an agent has signing authority over a wallet, you have created a new attack surface. The agent can be manipulated through prompt injection. A bug in your logic can trigger unintended transactions. A compromised session token can be replayed. And unlike a web app where a bad action might corrupt a database you can restore, an on-chain transaction is final.
The security question is not "do you trust your AI?" — it is "what is the blast radius if it goes wrong?" Good security design answers that question before anything gets deployed.
WAIaaS answers it with three concrete layers: authentication controls who can issue commands, a policy engine controls what those commands are allowed to do, and a human approval channel controls whether high-risk actions actually execute. Let's walk through each.
Layer 1: Three Authentication Methods, Three Principals
WAIaaS separates concerns across three distinct principals, each with its own authentication method:
# 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>"
The master password (hashed with Argon2id) is a system-level credential used only to create wallets, configure policies, and manage sessions. Your AI agent never sees it.
The session token (JWT HS256) is what your agent actually uses. It is scoped to a single wallet, carries a TTL, a maximum renewal count, and an absolute lifetime ceiling. If the token is compromised, the blast radius is bounded — the attacker cannot create new wallets, cannot modify policies, and cannot approve their own transactions.
The owner authentication (Ed25519 or secp256k1 signature from the fund owner's wallet) is the kill switch and approval channel. It cannot be faked by the agent. It requires the actual owner to sign a message with their private key, which means it requires a human being.
This separation is not cosmetic. It means that a fully compromised agent session still cannot drain funds beyond what the policy engine allows, and still cannot approve its own high-value transactions.
Layer 2: The Policy Engine — 21 Types, 4 Tiers, Default-Deny
This is the core of WAIaaS security. The policy engine enforces rules on every transaction before it executes, and it is default-deny: if you have not explicitly configured ALLOWED_TOKENS or CONTRACT_WHITELIST, transactions that involve tokens or contracts are blocked.
There are 21 policy types organized around different risk vectors:
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
The Spending Limit: Four Tiers of Risk
The SPENDING_LIMIT policy is the most fundamental control. It maps transaction amounts to four security tiers:
INSTANT — Execute immediately, no notification
NOTIFY — Execute immediately, send notification
DELAY — Queue for delay_seconds, then execute (cancellable)
APPROVAL — Require human approval via WalletConnect/Telegram/Push
Here is how you create a spending limit policy:
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
}
}'
With this configuration: a $50 transfer goes through immediately. A $300 transfer goes through but you get a notification. A $1,200 transfer is queued for 15 minutes — giving you a window to cancel it if it was a mistake or an attack. A $3,000 transfer requires you to explicitly approve it with your owner signature. Nothing above $5,000 in a single day executes regardless of tier.
This is not a vague "security feature." It is a precise, auditable rule that you can reason about.
Default-Deny Token Whitelist
One of the most important policies is ALLOWED_TOKENS. Without it configured, your agent cannot transfer tokens — any token transfer is blocked by default. You must explicitly declare which tokens the agent is permitted to move:
{
"tokens": [
{
"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"symbol": "USDC",
"chain": "solana"
}
]
}
Same logic applies to CONTRACT_WHITELIST (which contracts the agent can call), APPROVED_SPENDERS (which addresses the agent can grant token approvals to), and ALLOWED_NETWORKS (which chains the agent can operate on at all).
The default-deny posture means you are opting in to capabilities, not opting out of risks. That is the correct direction for security design.
DeFi-Specific Risk Controls
WAIaaS integrates 15 DeFi protocols including Aave v3, Hyperliquid, Jupiter, Kamino, and Pendle. Each category of DeFi activity has specific policy controls:
-
LENDING_LTV_LIMITcaps the loan-to-value ratio for lending positions, preventing your agent from over-leveraging collateral on Aave or Kamino. -
PERP_MAX_LEVERAGEandPERP_MAX_POSITION_USDbound perpetual futures exposure on Hyperliquid and Drift — an agent cannot open a 50x leveraged position if you have capped leverage at 5x. -
PERP_ALLOWED_MARKETSrestricts which perpetual markets the agent can trade, so an agent configured for BTC/USD perpetuals cannot suddenly start trading illiquid altcoin contracts. -
VENUE_WHITELISTrestricts which DEXes or trading venues the agent can route through. -
ACTION_CATEGORY_LIMITlets you set rate limits per DeFi action category — for example, limiting how many lending actions can occur per day regardless of individual amounts.
Approve Transaction Controls
Token approvals (APPROVE) are one of the most exploited mechanisms in DeFi. APPROVE_AMOUNT_LIMIT blocks the agent from issuing unlimited token approvals — a common attack vector where a malicious contract drains all of a token indefinitely. APPROVE_TIER_OVERRIDE lets you force all approval transactions to require human sign-off regardless of the dollar amount, which is a sensible default for most setups.
x402 and HTTP Payment Policies
WAIaaS supports the x402 HTTP payment protocol, which lets agents automatically pay for API calls. X402_ALLOWED_DOMAINS is a whitelist of domains the agent is permitted to pay automatically. Without this policy configured, the agent cannot make x402 payments to any domain. With it, you can allow *.openai.com and api.example.com while blocking everything else.
Layer 3: Human Approval Channels
When a transaction hits the APPROVAL tier — either by exceeding spending limits or by matching a policy that always requires approval — it is queued and waits. The owner must actively approve it. WAIaaS supports three signing channels for this: push relay, Telegram, and WalletConnect notification.
Approving a pending transaction looks like this:
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>"
This requires a cryptographic signature from the owner's key. It cannot be spoofed by the agent. It cannot be automated away. A human being with access to the owner's private key must sign the approval message. The delay tier works similarly — transactions are queued for delay_seconds and then execute automatically, but they can be cancelled during that window if you catch something wrong.
The Transaction Pipeline
Every transaction — regardless of type — passes through a 7-stage pipeline before execution: validate, auth, policy, wait, execute, confirm. The policy stage runs after authentication and before any waiting or execution, which means a policy violation is caught early and returns an error immediately:
{
"error": {
"code": "POLICY_DENIED",
"message": "Transaction denied by SPENDING_LIMIT policy",
"domain": "POLICY",
"retryable": false
}
}
There is also a dry-run mode for simulating transactions before committing them — useful for testing policy configurations without moving real funds:
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
}'
And there is gas conditional execution — transactions can be configured to execute only when gas price meets a threshold, preventing your agent from sending transactions during fee spikes.
Quick Start: Deploying a Secured Agent Wallet
Here is the minimal path to a secured agent wallet:
Step 1: Start WAIaaS
git clone https://github.com/waiaas/WAIaaS.git
cd WAIaaS
docker compose up -d
Step 2: Create a wallet and session
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"}'
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>"}'
Step 3: Configure a spending limit policy
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
}
}'
Step 4: Configure allowed tokens (remember: default-deny)
Set an ALLOWED_TOKENS policy listing every token your agent is permitted to transfer. Without this, token transfers are blocked.
Step 5: Give the session token to your agent, keep the master password out of it
Your agent gets wai_sess_<token>. Your master password stays in your environment config, never in the agent's context.
What's Next
The Admin Web UI at /admin provides a visual policy editor and DeFi positions dashboard if you prefer not to manage policies through the REST API. For integrating with Claude or other MCP-compatible AI agents, waiaas mcp setup --all registers all wallets automatically and gives you a ready-to-paste Claude Desktop config.
Explore the full codebase and self-host your own instance at github.com/waiaas/WAIaaS, and read the full documentation at waiaas.ai. Security questions and contributions are welcome — this is open source, and the policy engine behavior is auditable in the code.
Top comments (0)