You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Security hardening, wallet fast-path, and doc updates
Security:
- Add URL validation (core/url_validation.py) to block SSRF: private IPs,
cloud metadata, non-HTTP schemes return 400 url_blocked
- Sanitize error responses: generic messages to clients, details only in logs
- Wallet ledger: thread-safe balance operations, crypto-random tokens,
test wallets only when FAIRFETCH_TEST_MODE=true
- CORS: allow * only in test mode; production restricted to publisher domain
- Validate wallet inputs: positive amounts, owner length, balance caps
Wallet fast-path:
- In-memory WalletLedger with charge/top_up/transactions
- X-WALLET-TOKEN skips 402 when balance sufficient
- Endpoints: POST /wallet/register, GET /wallet/balance, POST /wallet/topup,
GET /wallet/transactions
Docs:
- README: Security section, config notes, project structure
- DEVELOPMENT: URL validation and test_mode behavior
- CONCEPTS: Allowed URLs and SSRF protection
- AI_AGENT_GUIDE: url_blocked, test wallets only in test mode
- PUBLISHER_GUIDE: Production CORS and wallet behavior
- openapi: 400 UrlBlocked, 502/503, X-WALLET-TOKEN in payment description
Copy file name to clipboardExpand all lines: README.md
+78-6Lines changed: 78 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -289,6 +289,65 @@ X-Content-Hash: sha256:2c449548... # Fingerprint of the content
289
289
290
290
<br />
291
291
292
+
## 👛 Wallet-Based Payment (Fast Path)
293
+
294
+
The 402 round-trip makes sense for discovery, but once an AI company is onboarded it's inefficient to negotiate payment on every request. Fairfetch supports **pre-funded wallets** that skip the 402 entirely:
295
+
296
+
```bash
297
+
# Register a wallet (in production, this happens through the Fairfetch marketplace)
298
+
curl -X POST "http://localhost:8402/wallet/register?owner=AcmeAI&initial_balance=100000"
Not all content usage is equal. Fairfetch defines **usage categories** that control what an AI agent is permitted to do with the content, with escalating compliance requirements and pricing:
@@ -480,7 +539,9 @@ Every successful response includes these headers. Think of them as a receipt and
480
539
|`X-FairFetch-Origin-Signature`| A digital fingerprint proving the publisher's server produced this exact content. Like a notary stamp — tamper-proof. |`GllQLb/V4Vd+Su...` (base64) |
481
540
|`X-FairFetch-License-ID`| Your Usage Grant reference. Store this — it's your proof of legal access if questions arise later. Format: `grant_id:signature_prefix`. |`47db4290...:k2+wXE3x...`|
482
541
|`X-Content-Hash`| A fingerprint of the content body itself, so you can verify nothing was altered in transit. |`sha256:2c449548...`|
483
-
|`X-PAYMENT-RECEIPT`| Proof that payment was settled. In test mode this is a simulated transaction hash. In production, a real on-chain transaction ID. |`0x6d8ce1bf...`|
542
+
|`X-PAYMENT-RECEIPT`| Proof that payment was settled. For x402: a transaction hash. For wallets: a ledger transaction ID (`ff_...`). |`0x6d8ce1bf...` or `ff_3a7c9e...`|
543
+
|`X-FairFetch-Payment-Method`| How the agent paid: `wallet` (pre-funded account) or `x402` (one-time payment). |`wallet`|
544
+
|`X-FairFetch-Wallet-Balance`| Remaining wallet balance after this charge (only present for wallet payments). |`99000`|
484
545
|`X-Fairfetch-Version`| Protocol version, so clients know which Fairfetch spec they're talking to. |`0.2`|
485
546
486
547
> [!TIP]
@@ -510,6 +571,7 @@ Every successful response includes these headers. Think of them as a receipt and
-**URL validation:** The `url` parameter is validated before any outbound request. Private IPs (e.g. `127.0.0.1`, `10.x`, `192.168.x`), cloud metadata endpoints (e.g. `169.254.169.254`), and non-HTTP(S) schemes are rejected with `400` and `error: "url_blocked"`. This prevents SSRF (server-side request forgery).
643
+
-**Test mode:** With `FAIRFETCH_TEST_MODE=false`, CORS allows only `https://{FAIRFETCH_PUBLISHER_DOMAIN}` and the ledger does not pre-seed test wallets. Use test mode only for local development.
644
+
-**Error responses:** Upstream fetch and summarization errors return generic messages to clients; details are logged server-side only.
0 commit comments