DELAY Tier Security: Time-Lock Your AI Agent's High-Risk Transactions
DELAY Tier Security: Time-Lock Your AI Agent's High-Risk Transactions
Giving an AI agent a wallet without guardrails is like giving a toddler a credit card — the agent will spend exactly what you let it, exactly when it decides to, with no one watching. If you're building systems where an AI agent controls real funds, the question isn't whether something will go wrong — it's whether your architecture is designed to catch it before the damage is done. WAIaaS gives you a concrete answer to that question: a 3-layer security model with a 7-stage transaction pipeline, default-deny policies, and a DELAY tier that puts a time-lock on high-risk transactions before they execute.
The Real Risk Isn't Hackers — It's Your Own Agent
Most developers thinking about AI agent security imagine an external attacker stealing a private key. That's a valid concern, but it's not the most common failure mode. The more likely scenario is subtler: your agent misreads an instruction, acts on a hallucinated price, gets manipulated through a prompt injection in an API response, or simply executes a valid transaction at exactly the wrong moment.
None of those scenarios look like an attack from the outside. The transaction is signed correctly. The address is valid. The policy check passes. And yet you've just lost money you didn't intend to move.
This is why the security architecture in WAIaaS isn't just about keeping attackers out — it's about giving you time to catch your own agent's mistakes. The DELAY tier is the most direct expression of that idea: mandatory waiting periods that give you a window to cancel before execution happens.
3 Layers Between Your Agent and Your Funds
Before diving into DELAY specifically, it helps to understand the broader security model. WAIaaS uses 3-layer security:
Layer 1: Session authentication and authorization. Your AI agent never touches a master password or private key. It authenticates with a session token (wai_sess_...) scoped to a specific wallet. Sessions have configurable TTL, max renewals, and absolute lifetime ceilings.
Layer 2: Time delay, approval requirements, and policy enforcement. This is where the DELAY tier lives. Every transaction runs through a 7-stage pipeline — validate, authenticate, check policy, wait (the DELAY stage), execute, confirm. Policy evaluation happens at stage 3. If a transaction hits the DELAY tier, it queues at stage 4 and doesn't move forward until the delay period expires or you cancel it.
Layer 3: Monitoring, notifications, and a kill switch. Even after a transaction executes, you have incoming transaction monitoring, real-time notifications, and the ability to revoke sessions immediately.
Three separate checkpoints. An agent that somehow bypasses one still hits the next.
How the Policy Engine Actually Works
WAIaaS uses 21 policy types and 4 security tiers: INSTANT, NOTIFY, DELAY, and APPROVAL.
The tiers work like this:
INSTANT — Execute immediately, no notification
NOTIFY — Execute immediately, send notification to you
DELAY — Queue for delay_seconds, then execute (cancellable during the window)
APPROVAL — Require explicit human approval before anything happens
The key thing to understand about DELAY is that it's not a soft suggestion — it's a hard queue. The transaction sits at stage 4 of the pipeline and cannot proceed to execution until the timer runs out. If you're watching (and WAIaaS can notify you when DELAY transactions queue), you have that entire window to cancel.
Critically, policies also follow default-deny enforcement. If you haven't explicitly whitelisted a token with ALLOWED_TOKENS, your agent can't transfer it. If you haven't added a contract address to CONTRACT_WHITELIST, your agent can't call it. This isn't "deny unknown things if a suspicious flag is set" — it's deny everything that hasn't been explicitly permitted.
Setting Up DELAY Tier With SPENDING_LIMIT
The most common way to configure DELAY is through the SPENDING_LIMIT policy. You define four thresholds, and every transaction gets assigned a tier based on its USD value:
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": 10,
"notify_max_usd": 100,
"delay_max_usd": 1000,
"delay_seconds": 900,
"daily_limit_usd": 5000,
"monthly_limit_usd": 20000
}
}'
With this configuration:
- A $7 transaction → INSTANT (executes immediately, no friction)
- A $50 transaction → NOTIFY (executes immediately, you get a notification)
- A $400 transaction → DELAY (queues for 15 minutes — you can cancel during that window)
- A $1,500 transaction → APPROVAL (blocked entirely until you explicitly approve it)
The delay_seconds field is what controls the time-lock. Set it to 900 and your agent has a 15-minute window during which you can cancel. Set it to 3600 and you have an hour. The right value depends on how actively you're monitoring and how time-sensitive your agent's operations are.
Layering Policies for Defense in Depth
SPENDING_LIMIT alone is powerful, but the real security posture comes from combining multiple policy types. Here's a realistic production setup for a trading agent:
Step 1: Define which tokens can move at all
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": "ALLOWED_TOKENS",
"rules": {
"tokens": [
{
"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"symbol": "USDC",
"chain": "solana"
}
]
}
}'
If your agent attempts to transfer any token not on this list, the transaction is denied at the policy stage — it never reaches DELAY or execution.
Step 2: Whitelist the contracts your agent should interact with
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": "CONTRACT_WHITELIST",
"rules": {
"contracts": [
{
"address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
"name": "Jupiter",
"chain": "solana"
}
]
}
}'
Step 3: Add rate limiting so a runaway agent can't spam 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": "RATE_LIMIT",
"rules": {
"maxTransactions": 10,
"period": "hourly"
}
}'
Now you have three independent controls: only the right tokens can move, only to the right contracts, with a maximum frequency, and any single transaction above your INSTANT threshold gets a time-lock.
Dry-Run Before You Trust
Before committing to a policy configuration in production, you can simulate any transaction against the current policy set using the dry-run API. The transaction runs through the full pipeline — including policy evaluation — but stops before execution:
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
}'
This is particularly useful when you're calibrating your SPENDING_LIMIT thresholds. Run a few representative transactions in dry-run mode and see which tier they hit before you commit. If a transaction that should be INSTANT is hitting DELAY, or a large transfer is coming back INSTANT when it should require approval, you can adjust the thresholds without any real funds at risk.
Authentication: Three Roles, Three Levels of Trust
The security model also separates concerns across three distinct authentication methods, each with different capabilities:
# 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>"
Your AI agent only ever holds a sessionAuth token. It cannot create new sessions, modify policies, or approve its own transactions. Policy changes require the master password. Transaction approval — when something hits the APPROVAL tier — requires an owner signature, which is a cryptographic signature from the actual key that owns the funds.
When a transaction queues in the DELAY tier and you decide it should require explicit approval before executing, that approval comes through 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>"
WAIaaS supports 3 signing channels for owner approval: push-relay, Telegram, and wallet notification channel — so you can receive and act on pending transactions from wherever you're working.
Gas Conditions and the Full Pipeline Picture
One more safety mechanism worth knowing: gas conditional execution. Transactions can be configured to execute only when the gas price meets a specified threshold. This runs as part of the 7-stage pipeline and means your agent won't accidentally execute a large swap during a gas spike that makes the transaction economically irrational.
The pipeline stages are: validate → authenticate → policy → wait → execute → confirm. The DELAY tier operates at the wait stage — it's not a bolt-on feature, it's a first-class stage in every transaction's lifecycle.
Quick Start: Add DELAY Tier to Your Agent in 5 Steps
Start WAIaaS using Docker or the CLI:
docker compose up -d # or waiaas startCreate a wallet for your agent (masterAuth):
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"}'Set a SPENDING_LIMIT policy with your DELAY threshold and delay window (see the example above with
delay_max_usd: 1000anddelay_seconds: 900).Add ALLOWED_TOKENS and CONTRACT_WHITELIST policies to enforce default-deny on what the agent can touch.
Create a session token for your agent and hand it only the
wai_sess_...token — the agent never needs, and never gets, anything else: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>"}'
From here, your agent can send transactions, check balances, and execute DeFi actions — all through the session token, all subject to the policies you've defined.
What Errors Look Like When Policies Block a Transaction
When a transaction is denied by a policy, the response is explicit about what happened:
{
"error": {
"code": "POLICY_DENIED",
"message": "Transaction denied by SPENDING_LIMIT policy",
"domain": "POLICY",
"retryable": false
}
}
This isn't a generic 403. The error domain is POLICY, the code is specific, and retryable: false tells your agent not to retry the same transaction — it needs a human decision before anything changes.
What's Next
The DELAY tier is one piece of a broader security architecture. WAIaaS also provides ERC-4337 Account Abstraction for gasless transactions, WalletConnect integration for owner approval flows, and 45 MCP tools so you can connect AI agents through Claude Desktop or any MCP-compatible framework without writing custom integration code. If you want to go deeper on the policy engine, the OpenAPI spec at /doc and the interactive Scalar UI at /reference document all 21 policy types and their rule schemas in full.
Start with the source on GitHub, or read more about what WAIaaS is and how to deploy it at the official site.
- GitHub: https://github.com/minhoyoo-iotrust/WAIaaS
- Official site: https://waiaas.ai