Security
Local custody model, key encryption, Security Guard (red/yellow-line rules), baseline verification, anomaly detection, and audit chain.
Security Model
AgentsWallets security is built on two independent layers: password-protected private keys (prevents unauthorized access) and Policy Engine (prevents authorized agents from going rogue).
Layer 1: Master password — who can use the wallet
All private keys are encrypted locally with AES-256-GCM + scrypt. Without the master password, local files are useless — even if someone gains access to the device.
There are three ways to unlock a wallet, each designed for a different use case:
Manual mode (personal use):
aw unlock
# Interactive password prompt → 15-minute session
# Must re-enter after expiryKeychain mode (personal use, more convenient):
aw keychain save
# Saves password to macOS Keychain on first entry
# Subsequent aw unlock reads from Keychain automaticallyEnvironment variable mode (agent automation):
export AW_MASTER_PASSWORD="your-password"
aw unlock --json
# Agent unlocks automatically via env var, no interaction neededAll three methods require explicit user authorization. The only difference is when and how the user authorizes. The environment variable mode is the user explicitly saying: "I allow this agent to use my wallet."
Layer 2: Policy Engine — what the wallet can do
Even when an agent has wallet access, every transaction is validated locally by the Policy Engine:
- per_tx_limit — maximum amount per transaction
- daily_limit — cumulative 24-hour spending cap
- max_tx_per_day — maximum number of transactions per day
- allowed_tokens — restrict operations to specific tokens
- allowed_addresses — only allow transfers to whitelisted addresses
Policies are enforced locally — rejected transactions never reach the chain.
Example: Suppose you set per_tx_limit: 10 and daily_limit: 50 for an agent. Even if the agent's LLM is compromised by a prompt injection attack and attempts to drain all funds, the Policy Engine will reject any transaction exceeding the limits.
Threat model summary
| Threat | Protection |
|---|---|
| Device stolen / files leaked | AES-256-GCM encryption, useless without master password |
| Unauthorized wallet access | Must unlock via password / Keychain / env var |
| Agent prompt injection | Policy Engine blocks transactions exceeding limits |
| Agent bug causing repeated losses | daily_limit + max_tx_per_day cap total exposure |
| Transfer to wrong address | allowed_addresses whitelist restriction |
| Swap to unknown/scam token | Security Guard yellow-line UNKNOWN_TOKEN warning |
| Drain attempt via swap | Security Guard red-line ALL_BALANCE_SWAP blocks |
| Transaction to scam address | Security Guard red-line BLACKLISTED_ADDRESS blocks |
| Unusual trading pattern | Security Guard anomaly detection alerts |
| Configuration tampering | Baseline verification detects changes |
Design principle: Master password protects who can use the wallet. Policy Engine controls what the wallet can do. Security Guard provides runtime threat detection. Three layers, independent of each other.
Security Guard
Security Guard is a runtime protection system that evaluates every write operation against a set of red-line and yellow-line rules before execution.
Red-line rules (block)
Red-line rules block the operation by default. Use --yes to confirm after reviewing the warning.
| Rule | Trigger |
|---|---|
DRAIN_ALL | Attempting to drain entire wallet balance |
EXPORT_KEY | Exporting private keys or mnemonic |
LARGE_TRANSFER | Transfer exceeding a significant threshold |
NEW_ADDRESS | Sending to a never-before-used address |
ALL_BALANCE_SWAP | Swapping entire token balance |
POLICY_CHANGE | Modifying spending policy (e.g., raising limits) |
BLACKLISTED_ADDRESS | Interacting with a blacklisted address |
Yellow-line rules (warn)
Yellow-line rules warn but allow the operation to proceed. Use --force to suppress the warning.
| Rule | Trigger |
|---|---|
HIGH_SLIPPAGE | Swap slippage exceeds safe threshold |
UNKNOWN_TOKEN | Swapping to or from an unverified token |
HIGH_LEVERAGE | Opening a perpetual position with high leverage |
RAPID_TRANSACTIONS | Multiple transactions in quick succession |
NIGHT_TRADING | Trading outside normal hours |
LARGE_CROSS_CHAIN | Large cross-chain bridge amount |
LARGE_PERP_POSITION | Large perpetual position size |
--force and --yes flags
--force— bypass yellow-line warnings (e.g., high slippage, unknown token)--yes— confirm red-line prompts without interactive input (e.g., large transfer, drain)
# Bypass yellow-line warning for high slippage
aw swap exec --wallet bot --from ETH --to PEPE --amount 0.1 --force --json
# Confirm red-line prompt for large transfer
aw send --wallet bot --to 0x9f4E... --amount 5000 --token USDC --yes --jsonBlacklist management
Maintain a list of blocked addresses to prevent interaction with known malicious actors.
# Add address to blacklist
aw security blacklist add --address 0xBAD...123 --reason "Known scam" --json
# List all blacklisted addresses
aw security blacklist list --json
# Remove address from blacklist
aw security blacklist remove --address 0xBAD...123 --jsonBaseline verification
Detect configuration tampering by comparing the current state against a stored baseline.
# Initialize baseline (run once after setup)
aw security baseline init --json
# Verify configuration hasn't been tampered with
aw security baseline verify --jsonIf the baseline check fails (ERR_BASELINE_TAMPERED), investigate immediately — it indicates that configuration files have been modified outside of normal CLI operations.
Anomaly detection
Analyze a wallet's transaction patterns to detect unusual behavior.
aw security anomaly agent-01 --jsonThe anomaly detector analyzes: transaction frequency, amount deviation, time-of-day patterns, and destination diversity.
Security reports
Generate a comprehensive security assessment.
aw security report --jsonReports include: security score, rule violation counts, anomaly detection results, baseline status, and actionable recommendations.
Key storage
All secrets are stored locally on your machine in ~/.agentswallets/ — HD wallets store an encrypted mnemonic, EVM private key, and Solana private key, each independently encrypted. Keys never leave the device — AgentsWallets is fully non-custodial.
Encryption at rest
Private keys and mnemonics are encrypted using AES-256-GCM with a key derived from your master password via scrypt KDF:
| Parameter | Default | Minimum |
|---|---|---|
| N (CPU/memory cost) | 65,536 | 16,384 |
| r (block size) | 8 | 8 |
| p (parallelization) | 1 | 1 |
| Max memory | 256 MB | — |
Scrypt parameters can be tuned via environment variables (AW_SCRYPT_N, AW_SCRYPT_R, AW_SCRYPT_P, AW_SCRYPT_MAXMEM).
Export key
HD wallets export the BIP-39 mnemonic (not individual private keys). Exporting requires a three-step safety gate:
- Environment variable:
AW_ALLOW_EXPORT=1must be set - CLI flag:
--danger-exportmust be passed explicitly - Interactive confirmation: user must confirm (or pass
--yes)
AW_ALLOW_EXPORT=1 aw wallet export-key bot --danger-export --yes --json{
"ok": true,
"data": {
"mnemonic": "abandon abandon abandon ... about",
"warning": "Store this mnemonic securely. Anyone with access can derive all keys."
}
}If any of the three gates is missing, the command is rejected.
Session model
Write operations (send, predict buy, predict sell, swap exec, bridge exec, perp open, perp close, perp cancel) require an active session.
| Property | Value |
|---|---|
| Token format | Random bytes, SHA-256 hashed |
| Comparison | Constant-time (timing-attack resistant) |
| TTL | Configurable, 1–15 minutes (default: 15) |
| Renewal | Sliding window — each successful command resets the TTL |
| Storage | Local file under $AGENTSWALLETS_HOME |
Sessions are created by aw unlock and destroyed by aw lock (which deletes both session.json and session-token files). Active sessions auto-renew on each successful command, so agents don't need to re-unlock as long as they remain active within the TTL window.
Rate limiting
Failed unlock attempts are rate-limited to prevent brute-force attacks:
| Rule | Value |
|---|---|
| Max attempts | 5 per 15-minute window |
| Backoff | Exponential |
| Reset | After 15 minutes of no failed attempts |
After 5 consecutive failures, the CLI rejects further unlock attempts until the window resets.
Audit chain
Every command that modifies state produces an audit log entry. Entries are chained using SHA-256 hashes for tamper detection:
- Each entry includes
prev_hash(hash of the previous entry) andentry_hash - Breaking the chain indicates tampering
- Audit logs can be queried with
aw audit list
aw audit list --wallet bot --action tx.send --limit 10 --jsonRPC security
| Rule | Detail |
|---|---|
| HTTPS required | Non-localhost http:// URLs are rejected |
| Failover | AW_RPC_URL supports comma-separated URLs with automatic retry |
| Retry strategy | 3 attempts, exponential backoff |
| Timeout | Configurable via --timeout <ms> (default: 30,000 ms) |
| Health check | aw health tests connectivity and reports status |
Production deployment checklist
- Use a strong, unique master password (not reused from other services)
- Save the password to the OS keychain (
aw keychain save) for agent workflows - Set
AW_SESSION_TTL_MINUTESto the minimum needed (e.g.,5) - Configure
AW_RPC_URLwith a private RPC endpoint (e.g., Alchemy, Infura) - Set per-wallet policies:
aw policy set --limit-daily 100 --limit-per-tx 25 - Use
allowed_addressesto restrict destinations to known-safe addresses - Monitor audit logs regularly:
aw audit list --wallet <id> - Never set
AW_ALLOW_EXPORT=1in production environments - Ensure
~/.agentswallets/has restrictive file permissions (chmod 700) - Initialize Security Guard baseline:
aw security baseline init - Add known malicious addresses to blacklist:
aw security blacklist add - Run periodic security reports:
aw security report - Monitor anomaly detection:
aw security anomaly <wallet>