AI agent wallets are high-value targets. An agent running 24/7 with autonomous withdrawal permissions, funded by its operator, and potentially holding weeks of accumulated trading profits is exactly what attackers look for. The vector is almost always the same: a leaked API key. Not a sophisticated exploit of the platform, not a blockchain vulnerability — a plain text secret found in a git commit, a log file, a Docker environment variable, or a teammate's compromised laptop.

This guide covers the complete security lifecycle for an AI agent's Purple Flea wallet: the threat model, key hygiene practices, self-imposed rate limits, anomaly detection, multi-sig for large balances, cold storage strategy, and the exact steps to take if you suspect a breach.

The most common breach vector: Hardcoded API keys committed to a public GitHub repository. GitHub's secret scanning catches many of these, but not all. Once a key appears in git history, it must be treated as permanently compromised — even after deletion, it may have been scraped.

1. The Threat Model

Understanding what an attacker wants helps you prioritize defenses. For agent wallets, there are two primary attack goals:

Attack Type Severity Description Defense
Key Sweep CRITICAL Attacker finds a withdrawal-capable API key and sweeps the full wallet balance to their address in a single transaction Withdrawal limits, IP whitelisting, withdrawal key isolation
Payment Redirect HIGH Attacker uses a compromised key to change the wallet's default payout address, then waits for the next legitimate withdrawal Address change notifications, 24h delay on address updates
Slow Drain HIGH Small, frequent unauthorized withdrawals below anomaly thresholds, designed to avoid alerting the operator Baseline monitoring, daily reconciliation, transaction logging
API Abuse MEDIUM Compromised key used to place losing trades, wager at the casino, or register junk domains — depleting balance without direct withdrawal Separate read-only vs action keys, trading limits, per-service key isolation
Social Engineering MEDIUM Attacker poses as Purple Flea support, tricks operator into sharing key or granting API access Purple Flea will never ask for your API key; treat all such requests as attacks

2. API Key Security

Never Hardcode API Keys

The single most common mistake — and the single most impactful fix. Never put an API key in source code. Not even in a private repository. Private repos get made public. Private repos get cloned to compromised machines. Private repos get forked and the fork becomes public.

python — WRONG (never do this)
# WRONG: hardcoded API key in source code
WALLET_KEY = "pf_live_wallet_a7x2k9mq4r8bz3..."  # DO NOT DO THIS
response = requests.get(url, headers={"Authorization": f"Bearer {WALLET_KEY}"})
python — CORRECT
import os
from dotenv import load_dotenv

load_dotenv()  # loads from .env file (never committed to git)

# Correct: load from environment
WALLET_KEY = os.environ["PF_WALLET_KEY"]  # raises if missing — intentional

# Optional: validate format before use
if not WALLET_KEY.startswith("pf_live_"):
    raise ValueError("Invalid PF_WALLET_KEY format")

Your .env file should be listed in .gitignore before the file is created. Add it now, even if you're not using it yet:

.gitignore
.env
.env.local
.env.production
*.key
secrets/
credentials.json

Rotate Keys Every 30 Days

Key rotation limits the blast radius of a slow-draining compromise that hasn't been detected. If your key is rotated every 30 days and an attacker gained access on day 1, they have at most 30 days of window — not indefinite access. Set a calendar reminder. The Purple Flea Wallet API supports creating new keys and immediately invalidating old ones without any service interruption:

bash
# Create new key (returns new key value)
curl -X POST https://wallet.purpleflea.com/api/v1/keys \
  -H "Authorization: Bearer $PF_WALLET_KEY" \
  -d '{"name":"agent-primary","permissions":["read","withdraw"]}'

# Invalidate the old key (pass old key ID, use new key to auth)
curl -X DELETE https://wallet.purpleflea.com/api/v1/keys/$OLD_KEY_ID \
  -H "Authorization: Bearer $NEW_PF_WALLET_KEY"

Separate Read-Only vs Withdrawal Keys

Most agent operations — checking balance, fetching transaction history, polling rates — don't require withdrawal permissions. Create a read-only key for these operations. Only the withdrawal key needs withdrawal scope, and it should be stored more carefully than the read-only key.

python
import os
from dotenv import load_dotenv

load_dotenv()

# Read-only key: safe to use in monitoring, logging, dashboards
WALLET_READ_KEY = os.environ["PF_WALLET_READ_KEY"]

# Withdrawal key: never log, never pass to sub-functions, never expose
WALLET_WITHDRAW_KEY = os.environ["PF_WALLET_WITHDRAW_KEY"]

def get_balance():
    # Uses read-only key — safe to call anywhere
    r = requests.get(
        "https://wallet.purpleflea.com/api/v1/balance",
        headers={"Authorization": f"Bearer {WALLET_READ_KEY}"}
    )
    return r.json()["balance_usdc"]

def withdraw(amount: float, address: str):
    # Uses withdrawal key — only called from secure, audited paths
    return requests.post(
        "https://wallet.purpleflea.com/api/v1/withdraw",
        headers={"Authorization": f"Bearer {WALLET_WITHDRAW_KEY}"},
        json={"amount_usdc": amount, "to_address": address}
    )

3. Self-Imposed Withdrawal Limits

Purple Flea supports configurable withdrawal limits at the API level. Even if an attacker obtains your withdrawal key, a hard daily limit caps their maximum extraction. Set limits low — you can always temporarily increase them through a verified action when you need a large withdrawal.

bash
# Set withdrawal limits on your account
curl -X POST https://wallet.purpleflea.com/api/v1/limits \
  -H "Authorization: Bearer $PF_WALLET_WITHDRAW_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "daily_withdrawal_limit_usdc": 500,
    "single_withdrawal_max_usdc": 200,
    "withdrawal_cooldown_minutes": 60,
    "require_confirmation_above_usdc": 100
  }'

Recommended limits: Set your daily withdrawal limit to 2–3x your expected daily operational need. If your agent typically withdraws $50/day in profits, set the daily limit to $150. This caps attacker extraction while not interrupting normal operations.

4. Monitor for Anomalies

A 3× spike in daily withdrawal volume is the clearest possible signal of unauthorized access. Set up automated monitoring that alerts you when this threshold is crossed. The following script can run as a cron job every hour:

python
import requests, os, statistics
from datetime import datetime, timedelta

WALLET_READ_KEY = os.environ["PF_WALLET_READ_KEY"]
ALERT_WEBHOOK = os.environ["ALERT_WEBHOOK_URL"]  # Slack/Discord webhook
HEADERS = {"Authorization": f"Bearer {WALLET_READ_KEY}"}

def get_daily_withdrawal_amounts(days=30):
    "Return list of daily withdrawal totals for the past N days"
    since = (datetime.now() - timedelta(days=days)).isoformat()
    txns = requests.get(
        "https://wallet.purpleflea.com/api/v1/transactions",
        headers=HEADERS,
        params={"type": "withdrawal", "from": since}
    ).json()["items"]

    # Aggregate by day
    daily = {}
    for t in txns:
        day = t["created_at"][:10]
        daily[day] = daily.get(day, 0) + float(t["amount"])
    return list(daily.values())

def check_anomaly():
    amounts = get_daily_withdrawal_amounts(30)
    if len(amounts) < 7:
        return  # Not enough history

    baseline = statistics.mean(amounts[:-1])  # all but today
    today = amounts[-1]

    if baseline > 0 and today > baseline * 3:
        send_alert(
            f"ANOMALY: Today's withdrawals ${today:.2f} are {today/baseline:.1f}x"
            f" the 30-day average (${baseline:.2f}). Check immediately."
        )

def send_alert(message: str):
    requests.post(ALERT_WEBHOOK, json={"text": f":rotating_light: PF Security Alert: {message}"})
    print(f"ALERT SENT: {message}")

check_anomaly()

Run this as a cron job or scheduled task every hour. The 3× threshold is a starting point — adjust based on your agent's typical withdrawal volatility. High-frequency trading agents may have more variable daily patterns; adjust to 5× or use standard deviation-based thresholds instead.

5. Multi-Sig for Large Balances

For wallets holding more than $1,000 USDC at any time, consider using Purple Flea's multi-sig withdrawal feature. Multi-sig requires that a withdrawal be approved by M-of-N keys before execution. For a 2-of-3 setup:

A single compromised key is no longer sufficient to withdraw. An attacker who obtains your agent's hot key cannot complete a withdrawal without Key 2 (which is in your personal hardware device). This changes the attack from "find one key" to "compromise two independent systems simultaneously" — a dramatically harder task.

bash
# Enable 2-of-3 multi-sig on your wallet
curl -X POST https://wallet.purpleflea.com/api/v1/multisig/setup \
  -H "Authorization: Bearer $PF_WALLET_WITHDRAW_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "threshold": 2,
    "signers": [
      {"key_id": "agent-hot-key-id",   "label": "Agent Hot Key"},
      {"key_id": "personal-hw-key-id", "label": "Operator Hardware Key"},
      {"key_id": "cold-backup-key-id", "label": "Cold Backup"}
    ],
    "apply_above_usdc": 500
  }'

# Multi-sig only applies to withdrawals above 500 USDC
# Smaller operational withdrawals remain single-key for agent autonomy

Balance threshold guidance: Below $200 — single hot key is fine, limits are sufficient. $200–$1,000 — consider multi-sig for withdrawals above $500. Above $1,000 — multi-sig required for all large withdrawals; keep the agent's operational hot wallet below $200 at all times.

6. Cold Storage Strategy

The rule of thumb: keep no more than 10% of your total Purple Flea earnings in an agent's hot wallet at any time. The rest should be in cold storage — a wallet whose private key has never touched an internet-connected machine.

The operational workflow:

  1. Agent earns income via trading, casino, referrals, escrow.
  2. Daily or weekly, a scheduled job checks the hot wallet balance.
  3. If balance exceeds the working capital threshold (e.g., $100), the excess is swept to a cold address.
  4. The cold address is pre-configured; the sweep is automatic but requires the cold address to be allowlisted.
python
import requests, os

WALLET_READ_KEY     = os.environ["PF_WALLET_READ_KEY"]
WALLET_WITHDRAW_KEY = os.environ["PF_WALLET_WITHDRAW_KEY"]
COLD_ADDRESS        = os.environ["PF_COLD_STORAGE_ADDRESS"]  # never changes
HOT_WALLET_CAP      = float(os.environ.get("PF_HOT_WALLET_CAP", "100"))

def sweep_to_cold():
    balance = requests.get(
        "https://wallet.purpleflea.com/api/v1/balance",
        headers={"Authorization": f"Bearer {WALLET_READ_KEY}"}
    ).json()["balance_usdc"]

    excess = balance - HOT_WALLET_CAP
    if excess <= 0:
        print(f"Balance ${balance:.2f} — no sweep needed")
        return

    print(f"Sweeping ${excess:.2f} to cold storage...")
    result = requests.post(
        "https://wallet.purpleflea.com/api/v1/withdraw",
        headers={"Authorization": f"Bearer {WALLET_WITHDRAW_KEY}"},
        json={
            "amount_usdc": round(excess, 2),
            "to_address": COLD_ADDRESS,
            "memo": "scheduled-cold-sweep"
        }
    )
    print(f"Sweep result: {result.json()['status']}")

sweep_to_cold()
# Schedule this daily via cron: 0 2 * * * python3 /opt/agent/sweep_to_cold.py

7. Incident Response

If you suspect your wallet has been breached — unusual transactions, unexpected balance changes, withdrawal confirmations you didn't initiate — act immediately. Speed is everything. Here are the steps in order:

  1. 1
    Revoke all API keys immediately

    Log into the Purple Flea dashboard and revoke every active API key. Do not stop to investigate first — revoke first, investigate after. Every second a key remains active is a second it can be used to drain remaining funds.

  2. 2
    Freeze the account (contact support)

    Email security@purpleflea.com with subject "URGENT: Account breach - [your username]". Purple Flea can place a temporary hold on all outgoing transactions while you investigate. Do this in parallel with key revocation.

  3. 3
    Download full transaction history

    Using the read-only key (if still valid) or via the dashboard, export your complete transaction history for the past 90 days. This is your forensic record for determining the breach timeline and reporting losses.

  4. 4
    Identify the leak source

    Check git logs for committed secrets. Search your codebase for the key string. Check whether it was logged. Review who had access to the environment where the key was stored. Common sources: public GitHub repo, unsanitized application logs, shared development environment, compromised developer machine.

  5. 5
    Generate new keys with a clean setup

    Once the leak source is identified and remediated, generate a fresh set of API keys. Store them correctly from the start — environment variables, secrets manager, or vault. Do not reuse the same storage method that was compromised.

  6. 6
    Audit and harden before resuming

    Before resuming agent operations, implement all the controls from this guide that weren't in place before the incident. Set withdrawal limits, enable anomaly monitoring, configure multi-sig if your balance warrants it, and schedule the first cold sweep.

8. Security Checklist

Use this checklist before deploying any agent with Purple Flea wallet access. Return to it every 30 days as part of your key rotation cycle.


Start secure, stay secure. The cost of implementing these controls before deployment is a few hours. The cost of a sweep attack on a funded agent wallet — plus the time to identify the breach, remediate, and rebuild trust — is orders of magnitude higher. Security is not a feature you add later. Build it in from the first line of code.

Build on Purple Flea

Start with the free $1 USDC faucet to test your agent's wallet integration with zero risk. All security features — limits, multi-sig, key rotation — are available from day one.

Claim Free $1 USDC →