x402-firewall 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- x402_firewall-0.1.0/PKG-INFO +273 -0
- x402_firewall-0.1.0/README.md +246 -0
- x402_firewall-0.1.0/pyproject.toml +44 -0
- x402_firewall-0.1.0/setup.cfg +4 -0
- x402_firewall-0.1.0/tests/test_firewall.py +357 -0
- x402_firewall-0.1.0/x402_firewall/__init__.py +33 -0
- x402_firewall-0.1.0/x402_firewall/approval.py +225 -0
- x402_firewall-0.1.0/x402_firewall/audit.py +83 -0
- x402_firewall-0.1.0/x402_firewall/decorators.py +153 -0
- x402_firewall-0.1.0/x402_firewall/firewall.py +266 -0
- x402_firewall-0.1.0/x402_firewall/policy.py +154 -0
- x402_firewall-0.1.0/x402_firewall.egg-info/PKG-INFO +273 -0
- x402_firewall-0.1.0/x402_firewall.egg-info/SOURCES.txt +14 -0
- x402_firewall-0.1.0/x402_firewall.egg-info/dependency_links.txt +1 -0
- x402_firewall-0.1.0/x402_firewall.egg-info/requires.txt +8 -0
- x402_firewall-0.1.0/x402_firewall.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: x402-firewall
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Spending firewall middleware for x402 payments. Policy engine, approval queue, and audit log for AI agents.
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Project-URL: Homepage, https://bonanza-labs.com
|
|
7
|
+
Project-URL: Repository, https://github.com/c6zks4gssn-droid/x402-firewall
|
|
8
|
+
Project-URL: Issues, https://github.com/c6zks4gssn-droid/x402-firewall/issues
|
|
9
|
+
Keywords: x402,payments,ai,agents,firewall,policy,spending,mcp,blockchain,base,usdc
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Provides-Extra: yaml
|
|
22
|
+
Requires-Dist: pyyaml>=6.0; extra == "yaml"
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
26
|
+
Requires-Dist: pyyaml>=6.0; extra == "dev"
|
|
27
|
+
|
|
28
|
+
# x402-firewall
|
|
29
|
+
|
|
30
|
+
**Spending firewall middleware for x402 payments.**
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
@guard(budget_usd=25.00, require_approval_above=5.00)
|
|
34
|
+
async def my_agent():
|
|
35
|
+
fw = get_firewall()
|
|
36
|
+
data = await fw.pay_x402("https://data.example.com/report", max_usd=1.50)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
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.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Install
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install x402-firewall
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Zero required dependencies.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Quickstart
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
import asyncio
|
|
57
|
+
from x402_firewall import guard, get_firewall, PaymentBlocked, PaymentPendingApproval
|
|
58
|
+
|
|
59
|
+
@guard(
|
|
60
|
+
budget_usd=25.00, # max total spend per call
|
|
61
|
+
require_approval_above=5.00, # payments ≥ $5 need human approval
|
|
62
|
+
block_vendors=["untrusted-vendor.com"],
|
|
63
|
+
)
|
|
64
|
+
async def research_agent(query: str):
|
|
65
|
+
fw = get_firewall()
|
|
66
|
+
|
|
67
|
+
# This payment is $1.50 — allowed immediately
|
|
68
|
+
result = await fw.pay_x402(
|
|
69
|
+
"https://data.example.com/report",
|
|
70
|
+
max_usd=1.50,
|
|
71
|
+
chain="base",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# This payment is $8.00 — escalated to approval queue
|
|
75
|
+
# (blocks here until a human approves or timeout)
|
|
76
|
+
premium = await fw.pay_x402(
|
|
77
|
+
"https://premium.example.com/dataset",
|
|
78
|
+
max_usd=8.00,
|
|
79
|
+
chain="base",
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
return result, premium
|
|
83
|
+
|
|
84
|
+
asyncio.run(research_agent("latest AI research"))
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Policy options
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
@guard(
|
|
93
|
+
budget_usd=25.00, # session budget cap
|
|
94
|
+
max_single_payment_usd=10.00, # hard cap per payment
|
|
95
|
+
require_approval_above=5.00, # escalate above this amount
|
|
96
|
+
block_vendors=["spam.com", r".*\.evil\.com$"], # regex supported
|
|
97
|
+
allow_vendors=["trusted.com"], # allowlist mode (blocks all others)
|
|
98
|
+
allow_chains=["base", "solana"],# only these chains
|
|
99
|
+
block_chains=["ethereum"], # block specific chains
|
|
100
|
+
max_payments_per_session=10, # max number of payments
|
|
101
|
+
)
|
|
102
|
+
async def my_agent(): ...
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Human approval queue
|
|
108
|
+
|
|
109
|
+
When a payment exceeds `require_approval_above`, the agent pauses and waits for a human decision. You can wire up any notification channel.
|
|
110
|
+
|
|
111
|
+
### Webhook (Slack, custom server)
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
@guard(
|
|
115
|
+
budget_usd=50.00,
|
|
116
|
+
require_approval_above=2.00,
|
|
117
|
+
webhook_url="https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
|
|
118
|
+
approval_timeout=300.0, # seconds to wait (default: 300)
|
|
119
|
+
)
|
|
120
|
+
async def my_agent(): ...
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The webhook receives a POST with:
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"request_id": "abc-123",
|
|
127
|
+
"amount_usd": 8.50,
|
|
128
|
+
"vendor": "premium.example.com",
|
|
129
|
+
"chain": "base",
|
|
130
|
+
"session_id": "sess-4f2a"
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Your server calls `queue.resolve(request_id, approved=True)` to unblock the agent.
|
|
135
|
+
|
|
136
|
+
### Custom notification (callback)
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from x402_firewall import ApprovalQueue
|
|
140
|
+
|
|
141
|
+
queue = ApprovalQueue(
|
|
142
|
+
on_pending=lambda req: send_telegram(
|
|
143
|
+
f"Approve payment of ${req.amount_usd:.2f} to {req.vendor}? "
|
|
144
|
+
f"ID: {req.request_id}"
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
@guard(budget_usd=50.00, require_approval_above=2.00, approval_queue=queue)
|
|
149
|
+
async def my_agent(): ...
|
|
150
|
+
|
|
151
|
+
# From your Telegram bot handler:
|
|
152
|
+
queue.resolve("abc-123", approved=True, approver="Clarence")
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### In-process approval (for testing)
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from x402_firewall import ApprovalQueue
|
|
159
|
+
import asyncio
|
|
160
|
+
|
|
161
|
+
queue = ApprovalQueue()
|
|
162
|
+
|
|
163
|
+
@guard(budget_usd=50.00, require_approval_above=2.00, approval_queue=queue)
|
|
164
|
+
async def my_agent(): ...
|
|
165
|
+
|
|
166
|
+
async def main():
|
|
167
|
+
task = asyncio.create_task(my_agent())
|
|
168
|
+
await asyncio.sleep(0.1) # let the agent reach the payment
|
|
169
|
+
queue.auto_approve() # approve all pending
|
|
170
|
+
await task
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Audit log
|
|
176
|
+
|
|
177
|
+
Every payment decision is recorded — blocked, allowed, escalated, approved, rejected.
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
from x402_firewall import AuditLog, guard, get_firewall
|
|
181
|
+
|
|
182
|
+
log = AuditLog(path="/var/log/x402-agent.jsonl") # or None for in-memory
|
|
183
|
+
|
|
184
|
+
@guard(budget_usd=25.00, audit_log=log)
|
|
185
|
+
async def my_agent(): ...
|
|
186
|
+
|
|
187
|
+
# After the run:
|
|
188
|
+
entries = log.entries_for_session("sess-abc")
|
|
189
|
+
print(f"Total spent: ${log.total_spent('sess-abc'):.4f}")
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Each JSONL line:
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"decision": "allowed",
|
|
196
|
+
"amount_usd": 1.5,
|
|
197
|
+
"vendor": "data.example.com",
|
|
198
|
+
"chain": "base",
|
|
199
|
+
"session_id": "sess-4f2a",
|
|
200
|
+
"timestamp": 1750000000.0,
|
|
201
|
+
"reason": "",
|
|
202
|
+
"approver": ""
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Manual firewall (no decorator)
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
from x402_firewall import Firewall, FirewallContext, Policy, AuditLog
|
|
212
|
+
|
|
213
|
+
fw = Firewall(
|
|
214
|
+
policy=Policy(budget_usd=25.00, require_approval_above=5.00),
|
|
215
|
+
audit_log=AuditLog(path="/var/log/x402.jsonl"),
|
|
216
|
+
)
|
|
217
|
+
ctx = FirewallContext(session_id="my-agent-session")
|
|
218
|
+
|
|
219
|
+
# Pre-flight check
|
|
220
|
+
await fw.check_payment(1.50, "https://data.example.com/r", "base", ctx)
|
|
221
|
+
|
|
222
|
+
# Or full payment flow
|
|
223
|
+
response = await fw.pay_x402("https://data.example.com/r", max_usd=1.50, ctx=ctx)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Load from YAML config
|
|
229
|
+
|
|
230
|
+
```yaml
|
|
231
|
+
# policy.yaml
|
|
232
|
+
budget_usd: 25.00
|
|
233
|
+
require_approval_above: 5.00
|
|
234
|
+
block_vendors:
|
|
235
|
+
- "untrusted.com"
|
|
236
|
+
- ".*\\.spam\\..*"
|
|
237
|
+
allow_chains:
|
|
238
|
+
- base
|
|
239
|
+
- solana
|
|
240
|
+
max_payments_per_session: 20
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
import yaml
|
|
245
|
+
from x402_firewall import Policy, Firewall
|
|
246
|
+
|
|
247
|
+
with open("policy.yaml") as f:
|
|
248
|
+
policy = Policy.from_dict(yaml.safe_load(f))
|
|
249
|
+
|
|
250
|
+
fw = Firewall(policy=policy)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## EU AI Act compliance
|
|
256
|
+
|
|
257
|
+
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:
|
|
258
|
+
- Paused before execution
|
|
259
|
+
- Sent to a designated human approver
|
|
260
|
+
- Logged with approver identity and timestamp
|
|
261
|
+
|
|
262
|
+
This is the documented compliance mechanism for high-risk AI systems under the EU AI Act (enforcement starts August 2026).
|
|
263
|
+
|
|
264
|
+
For teams needing a managed dashboard, hosted approval queue, and compliance reports:
|
|
265
|
+
→ **[bonanza-labs.com/firewall](https://bonanza-labs.com/firewall)**
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## License
|
|
270
|
+
|
|
271
|
+
Apache 2.0 — see [LICENSE](LICENSE).
|
|
272
|
+
|
|
273
|
+
Built by [Bonanza Labs](https://bonanza-labs.com).
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# x402-firewall
|
|
2
|
+
|
|
3
|
+
**Spending firewall middleware for x402 payments.**
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
@guard(budget_usd=25.00, require_approval_above=5.00)
|
|
7
|
+
async def my_agent():
|
|
8
|
+
fw = get_firewall()
|
|
9
|
+
data = await fw.pay_x402("https://data.example.com/report", max_usd=1.50)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
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.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install x402-firewall
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Zero required dependencies.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Quickstart
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
import asyncio
|
|
30
|
+
from x402_firewall import guard, get_firewall, PaymentBlocked, PaymentPendingApproval
|
|
31
|
+
|
|
32
|
+
@guard(
|
|
33
|
+
budget_usd=25.00, # max total spend per call
|
|
34
|
+
require_approval_above=5.00, # payments ≥ $5 need human approval
|
|
35
|
+
block_vendors=["untrusted-vendor.com"],
|
|
36
|
+
)
|
|
37
|
+
async def research_agent(query: str):
|
|
38
|
+
fw = get_firewall()
|
|
39
|
+
|
|
40
|
+
# This payment is $1.50 — allowed immediately
|
|
41
|
+
result = await fw.pay_x402(
|
|
42
|
+
"https://data.example.com/report",
|
|
43
|
+
max_usd=1.50,
|
|
44
|
+
chain="base",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# This payment is $8.00 — escalated to approval queue
|
|
48
|
+
# (blocks here until a human approves or timeout)
|
|
49
|
+
premium = await fw.pay_x402(
|
|
50
|
+
"https://premium.example.com/dataset",
|
|
51
|
+
max_usd=8.00,
|
|
52
|
+
chain="base",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
return result, premium
|
|
56
|
+
|
|
57
|
+
asyncio.run(research_agent("latest AI research"))
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Policy options
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
@guard(
|
|
66
|
+
budget_usd=25.00, # session budget cap
|
|
67
|
+
max_single_payment_usd=10.00, # hard cap per payment
|
|
68
|
+
require_approval_above=5.00, # escalate above this amount
|
|
69
|
+
block_vendors=["spam.com", r".*\.evil\.com$"], # regex supported
|
|
70
|
+
allow_vendors=["trusted.com"], # allowlist mode (blocks all others)
|
|
71
|
+
allow_chains=["base", "solana"],# only these chains
|
|
72
|
+
block_chains=["ethereum"], # block specific chains
|
|
73
|
+
max_payments_per_session=10, # max number of payments
|
|
74
|
+
)
|
|
75
|
+
async def my_agent(): ...
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Human approval queue
|
|
81
|
+
|
|
82
|
+
When a payment exceeds `require_approval_above`, the agent pauses and waits for a human decision. You can wire up any notification channel.
|
|
83
|
+
|
|
84
|
+
### Webhook (Slack, custom server)
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
@guard(
|
|
88
|
+
budget_usd=50.00,
|
|
89
|
+
require_approval_above=2.00,
|
|
90
|
+
webhook_url="https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
|
|
91
|
+
approval_timeout=300.0, # seconds to wait (default: 300)
|
|
92
|
+
)
|
|
93
|
+
async def my_agent(): ...
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The webhook receives a POST with:
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"request_id": "abc-123",
|
|
100
|
+
"amount_usd": 8.50,
|
|
101
|
+
"vendor": "premium.example.com",
|
|
102
|
+
"chain": "base",
|
|
103
|
+
"session_id": "sess-4f2a"
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Your server calls `queue.resolve(request_id, approved=True)` to unblock the agent.
|
|
108
|
+
|
|
109
|
+
### Custom notification (callback)
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from x402_firewall import ApprovalQueue
|
|
113
|
+
|
|
114
|
+
queue = ApprovalQueue(
|
|
115
|
+
on_pending=lambda req: send_telegram(
|
|
116
|
+
f"Approve payment of ${req.amount_usd:.2f} to {req.vendor}? "
|
|
117
|
+
f"ID: {req.request_id}"
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
@guard(budget_usd=50.00, require_approval_above=2.00, approval_queue=queue)
|
|
122
|
+
async def my_agent(): ...
|
|
123
|
+
|
|
124
|
+
# From your Telegram bot handler:
|
|
125
|
+
queue.resolve("abc-123", approved=True, approver="Clarence")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### In-process approval (for testing)
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from x402_firewall import ApprovalQueue
|
|
132
|
+
import asyncio
|
|
133
|
+
|
|
134
|
+
queue = ApprovalQueue()
|
|
135
|
+
|
|
136
|
+
@guard(budget_usd=50.00, require_approval_above=2.00, approval_queue=queue)
|
|
137
|
+
async def my_agent(): ...
|
|
138
|
+
|
|
139
|
+
async def main():
|
|
140
|
+
task = asyncio.create_task(my_agent())
|
|
141
|
+
await asyncio.sleep(0.1) # let the agent reach the payment
|
|
142
|
+
queue.auto_approve() # approve all pending
|
|
143
|
+
await task
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Audit log
|
|
149
|
+
|
|
150
|
+
Every payment decision is recorded — blocked, allowed, escalated, approved, rejected.
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
from x402_firewall import AuditLog, guard, get_firewall
|
|
154
|
+
|
|
155
|
+
log = AuditLog(path="/var/log/x402-agent.jsonl") # or None for in-memory
|
|
156
|
+
|
|
157
|
+
@guard(budget_usd=25.00, audit_log=log)
|
|
158
|
+
async def my_agent(): ...
|
|
159
|
+
|
|
160
|
+
# After the run:
|
|
161
|
+
entries = log.entries_for_session("sess-abc")
|
|
162
|
+
print(f"Total spent: ${log.total_spent('sess-abc'):.4f}")
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Each JSONL line:
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"decision": "allowed",
|
|
169
|
+
"amount_usd": 1.5,
|
|
170
|
+
"vendor": "data.example.com",
|
|
171
|
+
"chain": "base",
|
|
172
|
+
"session_id": "sess-4f2a",
|
|
173
|
+
"timestamp": 1750000000.0,
|
|
174
|
+
"reason": "",
|
|
175
|
+
"approver": ""
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Manual firewall (no decorator)
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from x402_firewall import Firewall, FirewallContext, Policy, AuditLog
|
|
185
|
+
|
|
186
|
+
fw = Firewall(
|
|
187
|
+
policy=Policy(budget_usd=25.00, require_approval_above=5.00),
|
|
188
|
+
audit_log=AuditLog(path="/var/log/x402.jsonl"),
|
|
189
|
+
)
|
|
190
|
+
ctx = FirewallContext(session_id="my-agent-session")
|
|
191
|
+
|
|
192
|
+
# Pre-flight check
|
|
193
|
+
await fw.check_payment(1.50, "https://data.example.com/r", "base", ctx)
|
|
194
|
+
|
|
195
|
+
# Or full payment flow
|
|
196
|
+
response = await fw.pay_x402("https://data.example.com/r", max_usd=1.50, ctx=ctx)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Load from YAML config
|
|
202
|
+
|
|
203
|
+
```yaml
|
|
204
|
+
# policy.yaml
|
|
205
|
+
budget_usd: 25.00
|
|
206
|
+
require_approval_above: 5.00
|
|
207
|
+
block_vendors:
|
|
208
|
+
- "untrusted.com"
|
|
209
|
+
- ".*\\.spam\\..*"
|
|
210
|
+
allow_chains:
|
|
211
|
+
- base
|
|
212
|
+
- solana
|
|
213
|
+
max_payments_per_session: 20
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
import yaml
|
|
218
|
+
from x402_firewall import Policy, Firewall
|
|
219
|
+
|
|
220
|
+
with open("policy.yaml") as f:
|
|
221
|
+
policy = Policy.from_dict(yaml.safe_load(f))
|
|
222
|
+
|
|
223
|
+
fw = Firewall(policy=policy)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## EU AI Act compliance
|
|
229
|
+
|
|
230
|
+
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:
|
|
231
|
+
- Paused before execution
|
|
232
|
+
- Sent to a designated human approver
|
|
233
|
+
- Logged with approver identity and timestamp
|
|
234
|
+
|
|
235
|
+
This is the documented compliance mechanism for high-risk AI systems under the EU AI Act (enforcement starts August 2026).
|
|
236
|
+
|
|
237
|
+
For teams needing a managed dashboard, hosted approval queue, and compliance reports:
|
|
238
|
+
→ **[bonanza-labs.com/firewall](https://bonanza-labs.com/firewall)**
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## License
|
|
243
|
+
|
|
244
|
+
Apache 2.0 — see [LICENSE](LICENSE).
|
|
245
|
+
|
|
246
|
+
Built by [Bonanza Labs](https://bonanza-labs.com).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "x402-firewall"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Spending firewall middleware for x402 payments. Policy engine, approval queue, and audit log for AI agents."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "Apache-2.0" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
keywords = [
|
|
13
|
+
"x402", "payments", "ai", "agents", "firewall", "policy",
|
|
14
|
+
"spending", "mcp", "blockchain", "base", "usdc",
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: Apache Software License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Topic :: Software Development :: Libraries",
|
|
25
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
26
|
+
]
|
|
27
|
+
dependencies = []
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
yaml = ["pyyaml>=6.0"]
|
|
31
|
+
dev = ["pytest>=8", "pytest-asyncio>=0.23", "pyyaml>=6.0"]
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://bonanza-labs.com"
|
|
35
|
+
Repository = "https://github.com/c6zks4gssn-droid/x402-firewall"
|
|
36
|
+
Issues = "https://github.com/c6zks4gssn-droid/x402-firewall/issues"
|
|
37
|
+
|
|
38
|
+
[tool.setuptools.packages.find]
|
|
39
|
+
where = ["."]
|
|
40
|
+
include = ["x402_firewall*"]
|
|
41
|
+
|
|
42
|
+
[tool.pytest.ini_options]
|
|
43
|
+
asyncio_mode = "auto"
|
|
44
|
+
testpaths = ["tests"]
|