X402_ALLOWED_DOMAINS: Control Which APIs Your AI Agent Can Pay For

AI agents with wallet access need strict payment controls, or they'll drain your funds on unauthorized API calls. The X402_ALLOWED_DOMAINS policy in WAIaaS creates a whitelist of trusted domains where your agent can make automatic payments, blocking everything else by default.

When you deploy an AI agent with payment capabilities, you're essentially giving it a credit card that works across the internet. Without proper controls, a single misconfigured prompt or compromised dependency could result in thousands of dollars in unauthorized charges. The x402 HTTP payment protocol makes this even more dangerous—it allows any API to request payment directly from your agent's wallet with a simple 402 status code.

Why Payment Domain Control Matters

The x402 protocol is elegant but dangerous. When your AI agent hits an API that returns HTTP 402 (Payment Required), it can automatically pay the requested amount and retry the request. This creates seamless AI-to-API commerce, but also opens a massive attack vector.

Consider these scenarios:

Without domain controls, your agent becomes a target for any bad actor who can influence its API calls.

The X402_ALLOWED_DOMAINS Solution

WAIaaS implements domain-level payment controls through the X402_ALLOWED_DOMAINS policy. This works as a whitelist—your agent can only make automatic payments to domains you've explicitly approved.

Here's how to create a domain payment policy:

curl -X POST http://localhost:3100/v1/policies \
  -H 'Content-Type: application/json' \
  -H 'X-Master-Password: my-secret-password' \
  -d '{
    "walletId": "019c47d6-51ef-7f43-a76b-d50e875d95f4",
    "type": "X402_ALLOWED_DOMAINS",
    "rules": {
      "domains": [
        "api.openai.com",
        "api.anthropic.com",
        "*.huggingface.co",
        "rapidapi.com"
      ]
    }
  }'

This policy configuration allows your agent to make x402 payments only to:

Any x402 payment request from other domains gets blocked immediately.

How X402 Payment Blocking Works

When your AI agent makes an HTTP request through WAIaaS's x402Fetch method, here's what happens:

  1. Request sent to target API
  2. API returns 402 with payment details
  3. Domain check against X402_ALLOWED_DOMAINS policy
  4. If domain blocked: Request fails with POLICY_DENIED error
  5. If domain allowed: Payment processed automatically

Here's the x402Fetch method in action:

import { WAIaaSClient } from '@waiaas/sdk';

const client = new WAIaaSClient({
  baseUrl: 'http://127.0.0.1:3100',
  sessionToken: process.env.WAIAAS_SESSION_TOKEN,
});

try {
  // This will work - api.openai.com is in our whitelist
  const response = await client.x402Fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      model: 'gpt-4',
      messages: [{ role: 'user', content: 'Hello' }]
    })
  });
  
  const data = await response.json();
  console.log('API call successful:', data);
  
} catch (error) {
  if (error.code === 'POLICY_DENIED') {
    console.log('Payment blocked by domain policy');
  }
}

If someone tricks your agent into calling https://evil-api.com/expensive-endpoint, the payment gets blocked even if the API legitimately returns a 402 status code.

Combining with Other Security Layers

X402_ALLOWED_DOMAINS works best when combined with WAIaaS's other security policies. Here's a comprehensive security setup:

# 1. Domain payment controls
curl -X POST http://localhost:3100/v1/policies \
  -H 'Content-Type: application/json' \
  -H 'X-Master-Password: my-secret-password' \
  -d '{
    "walletId": "<wallet-id>",
    "type": "X402_ALLOWED_DOMAINS", 
    "rules": {
      "domains": ["api.openai.com", "api.anthropic.com"]
    }
  }'

# 2. Spending limits for all transactions
curl -X POST http://localhost:3100/v1/policies \
  -H 'Content-Type: application/json' \
  -H 'X-Master-Password: my-secret-password' \
  -d '{
    "walletId": "<wallet-id>",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 1,
      "notify_max_usd": 10, 
      "delay_max_usd": 50,
      "delay_seconds": 300,
      "daily_limit_usd": 100
    }
  }'

# 3. Rate limiting to prevent payment loops
curl -X POST http://localhost:3100/v1/policies \
  -H 'Content-Type: application/json' \
  -H 'X-Master-Password: my-secret-password' \
  -d '{
    "walletId": "<wallet-id>",
    "type": "RATE_LIMIT",
    "rules": {
      "maxTransactions": 50,
      "period": "hourly"
    }
  }'

This creates a three-layer defense:

Wildcard Domain Support

WAIaaS supports wildcard patterns for domain matching, which is useful for services with multiple subdomains:

{
  "domains": [
    "*.openai.com",           // matches api.openai.com, chat.openai.com, etc.
    "*.googleapis.com",       // matches any Google API subdomain
    "huggingface.co",         // exact match only
    "*.rapidapi.com"          // matches all RapidAPI subdomains
  ]
}

Be careful with wildcards—*.com would allow payments to any .com domain, which defeats the purpose of the whitelist.

Monitoring Payment Attempts

WAIaaS logs all x402 payment attempts, including blocked ones. You can monitor your agent's payment behavior:

curl http://127.0.0.1:3100/v1/transactions \
  -H "Authorization: Bearer wai_sess_<token>" \
  | jq '.[] | select(.metadata.type == "x402_payment")'

Look for patterns like:

Quick Start: Secure AI Agent Payments

Here's how to set up domain-controlled x402 payments in 5 minutes:

  1. Start WAIaaS with Docker:

    docker run -d -p 127.0.0.1:3100:3100 -e WAIAAS_AUTO_PROVISION=true ghcr.io/minhoyoo-iotrust/waiaas:latest
    
  2. Get your master password:

    docker exec <container-id> cat /data/recovery.key
    
  3. Create a wallet and session (use the CLI for simplicity):

    npm install -g @waiaas/cli
    waiaas quickset --mode mainnet
    
  4. Create the domain payment policy (replace with your wallet ID):

    curl -X POST http://localhost:3100/v1/policies \
      -H 'Content-Type: application/json' \
      -H 'X-Master-Password: <your-password>' \
      -d '{"walletId": "<wallet-id>", "type": "X402_ALLOWED_DOMAINS", "rules": {"domains": ["api.openai.com"]}}'
    
  5. Test with your AI agent:

    const response = await client.x402Fetch('https://api.openai.com/v1/models');
    // Works - domain is whitelisted
    
    const blocked = await client.x402Fetch('https://untrusted-api.com/expensive');  
    // Throws POLICY_DENIED error
    

Your AI agent can now make payments only to approved domains, preventing unauthorized charges while maintaining seamless API access.

What's Next

The X402_ALLOWED_DOMAINS policy is just one piece of WAIaaS's comprehensive security model. Combined with spending limits, rate controls, and human approval workflows, it creates defense-in-depth for AI agents with wallet access.

Ready to secure your AI agent's payment capabilities? Check out the WAIaaS GitHub repository for the complete source code, or visit waiaas.ai to learn more about building secure AI agents with proper financial controls.