Skip to main content

x402-firewall

Spending firewall middleware for x402 payments.

@guard(budget_usd=25.00, require_approval_above=5.00)
async def my_agent():
    fw = get_firewall()
    data = await fw.pay_x402("https://data.example.com/report", max_usd=1.50)

Every x402 payment inside the decorated function is checked against your policy before it executes. Too expensive → blocked. Above the approval threshold → paused until a human approves. Over budget → raises immediately. Everything is audit-logged.


Install

pip install x402-firewall

Zero required dependencies.


Quickstart

import asyncio
from x402_firewall import guard, get_firewall, PaymentBlocked, PaymentPendingApproval

@guard(
    budget_usd=25.00,           # max total spend per call
    require_approval_above=5.00, # payments ≥ $5 need human approval
    block_vendors=["untrusted-vendor.com"],
)
async def research_agent(query: str):
    fw = get_firewall()

    # This payment is $1.50 — allowed immediately
    result = await fw.pay_x402(
        "https://data.example.com/report",
        max_usd=1.50,
        chain="base",
    )

    # This payment is $8.00 — escalated to approval queue
    # (blocks here until a human approves or timeout)
    premium = await fw.pay_x402(
        "https://premium.example.com/dataset",
        max_usd=8.00,
        chain="base",
    )

    return result, premium

asyncio.run(research_agent("latest AI research"))

Policy options

@guard(
    budget_usd=25.00,               # session budget cap
    max_single_payment_usd=10.00,   # hard cap per payment
    require_approval_above=5.00,    # escalate above this amount
    block_vendors=["spam.com", r".*\.evil\.com$"],  # regex supported
    allow_vendors=["trusted.com"],  # allowlist mode (blocks all others)
    allow_chains=["base", "solana"],# only these chains
    block_chains=["ethereum"],      # block specific chains
    max_payments_per_session=10,    # max number of payments
)
async def my_agent(): ...

Human approval queue

When a payment exceeds require_approval_above, the agent pauses and waits for a human decision. You can wire up any notification channel.

Webhook (Slack, custom server)

@guard(
    budget_usd=50.00,
    require_approval_above=2.00,
    webhook_url="https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
    approval_timeout=300.0,  # seconds to wait (default: 300)
)
async def my_agent(): ...

The webhook receives a POST with:

{
  "request_id": "abc-123",
  "amount_usd": 8.50,
  "vendor": "premium.example.com",
  "chain": "base",
  "session_id": "sess-4f2a"
}

Your server calls queue.resolve(request_id, approved=True) to unblock the agent.

Custom notification (callback)

from x402_firewall import ApprovalQueue

queue = ApprovalQueue(
    on_pending=lambda req: send_telegram(
        f"Approve payment of ${req.amount_usd:.2f} to {req.vendor}? "
        f"ID: {req.request_id}"
    )
)

@guard(budget_usd=50.00, require_approval_above=2.00, approval_queue=queue)
async def my_agent(): ...

# From your Telegram bot handler:
queue.resolve("abc-123", approved=True, approver="Clarence")

In-process approval (for testing)

from x402_firewall import ApprovalQueue
import asyncio

queue = ApprovalQueue()

@guard(budget_usd=50.00, require_approval_above=2.00, approval_queue=queue)
async def my_agent(): ...

async def main():
    task = asyncio.create_task(my_agent())
    await asyncio.sleep(0.1)          # let the agent reach the payment
    queue.auto_approve()              # approve all pending
    await task

Audit log

Every payment decision is recorded — blocked, allowed, escalated, approved, rejected.

from x402_firewall import AuditLog, guard, get_firewall

log = AuditLog(path="/var/log/x402-agent.jsonl")  # or None for in-memory

@guard(budget_usd=25.00, audit_log=log)
async def my_agent(): ...

# After the run:
entries = log.entries_for_session("sess-abc")
print(f"Total spent: ${log.total_spent('sess-abc'):.4f}")

Each JSONL line:

{
  "decision": "allowed",
  "amount_usd": 1.5,
  "vendor": "data.example.com",
  "chain": "base",
  "session_id": "sess-4f2a",
  "timestamp": 1750000000.0,
  "reason": "",
  "approver": ""
}

Manual firewall (no decorator)

from x402_firewall import Firewall, FirewallContext, Policy, AuditLog

fw = Firewall(
    policy=Policy(budget_usd=25.00, require_approval_above=5.00),
    audit_log=AuditLog(path="/var/log/x402.jsonl"),
)
ctx = FirewallContext(session_id="my-agent-session")

# Pre-flight check
await fw.check_payment(1.50, "https://data.example.com/r", "base", ctx)

# Or full payment flow
response = await fw.pay_x402("https://data.example.com/r", max_usd=1.50, ctx=ctx)

Load from YAML config

# policy.yaml
budget_usd: 25.00
require_approval_above: 5.00
block_vendors:
  - "untrusted.com"
  - ".*\\.spam\\..*"
allow_chains:
  - base
  - solana
max_payments_per_session: 20
import yaml
from x402_firewall import Policy, Firewall

with open("policy.yaml") as f:
    policy = Policy.from_dict(yaml.safe_load(f))

fw = Firewall(policy=policy)

EU AI Act compliance

The require_approval_above threshold combined with the audit log gives you Article 14 (human-in-the-loop) compliance for AI agents making financial decisions. Every escalated payment is:

  • Paused before execution
  • Sent to a designated human approver
  • Logged with approver identity and timestamp

This is the documented compliance mechanism for high-risk AI systems under the EU AI Act (enforcement starts August 2026).

For teams needing a managed dashboard, hosted approval queue, and compliance reports: → bonanza-labs.com/firewall


License

Apache 2.0 — see LICENSE.

Built by Bonanza Labs.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

x402_firewall-0.1.0.tar.gz (16.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

x402_firewall-0.1.0-py3-none-any.whl (14.1 kB view details)

Uploaded Python 3

File details

Details for the file x402_firewall-0.1.0.tar.gz.

File metadata

  • Download URL: x402_firewall-0.1.0.tar.gz
  • Upload date:
  • Size: 16.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for x402_firewall-0.1.0.tar.gz
Algorithm Hash digest
SHA256 aad6fcbc4cffa17f550e65127c078293d526055c1d0487462c2ab1277cfd1950
MD5 8c197a9270a05bc0945da4c90c4933b9
BLAKE2b-256 7d892afbcf80f44ff60f65af6f7486266469cf56e731a3f24527e007f26cd5fc

See more details on using hashes here.

File details

Details for the file x402_firewall-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: x402_firewall-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for x402_firewall-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9659fe9baa0df0ebd4a8cf83edd1defc890be4fb53e10df41cda0b70b678b1d1
MD5 a9becef1c5cb1b5b98a57d39226d4c34
BLAKE2b-256 4b87839fadb93d056175d037393bfe4668e71fcff393088084f4cd6fee6ef10b

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page