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
config: make x402 rate limit + maxConcurrentApiCalls explicit
`server.rateLimit.x402` and `settings.maxConcurrentApiCalls` are now
required (no `.default()`). Hidden defaults make it hard to see what's
actually running at a glance, and these tuning knobs aren't universal —
operators should set them per deployment. Breaking, in line with
`server.rateLimit` from c1a37c4.
The x402 bucket is also now configurable per-deployment: it threads
through `PipelineDependencies.rateLimit` into `AuthContext.x402RateLimit`
and is honored when the per-IP bucket is checked in `checkX402`. Tests
exercise both the default plumbing and a custom override.
`createTestServer` and `makeConfig` (server.test.ts) deep-merge a
`Partial<RateLimit>` override so call sites stay tight — tests pass
`{ max: 3 }` instead of redeclaring the full shape every time.
Examples, inline YAML fixtures, and book/docs/config/{server,settings}
updated to include the new required fields.
| `port` | `number` | Yes | -- | TCP port the server listens on. |
26
-
| `host` | `string` | No | `'0.0.0.0'` | Bind address. Use `127.0.0.1` to restrict to localhost. |
27
-
| `cors` | `object` | No | -- | CORS configuration. When omitted, `Access-Control-Allow-Origin: *` is used. |
28
-
| `cors.origins` | `string[]` | No | `['*']` | Allow-list of origins. The request's `Origin` is reflected back only if it matches an entry. |
29
-
| `rateLimit` | `object` | **Yes** | -- | Per-IP rate limiting (required). Set `max` very high to effectively disable it. |
30
-
| `rateLimit.window` | `number` | Yes | -- | Time window in milliseconds. |
31
-
| `rateLimit.max` | `number` | Yes | -- | Maximum requests per IP within the window. |
32
-
| `rateLimit.trustForwardedFor` | `boolean` | No | `false` | Use the first `X-Forwarded-For` entry as the client IP. Only enable behind a trusted reverse proxy. |
26
+
| Field | Type | Required | Default | Description |
| `port` | `number` | Yes | -- | TCP port the server listens on. |
29
+
| `host` | `string` | No | `'0.0.0.0'` | Bind address. Use `127.0.0.1` to restrict to localhost. |
30
+
| `cors` | `object` | No | -- | CORS configuration. When omitted, `Access-Control-Allow-Origin: *` is used. |
31
+
| `cors.origins` | `string[]` | No | `['*']` | Allow-list of origins. The request's `Origin` is reflected back only if it matches an entry. |
32
+
| `rateLimit` | `object` | **Yes** | -- | Per-IP rate limiting (required). Set `max` very high to effectively disable it. |
33
+
| `rateLimit.window` | `number` | Yes | -- | Time window in milliseconds. |
34
+
| `rateLimit.max` | `number` | Yes | -- | Maximum requests per IP within the window. |
35
+
| `rateLimit.trustForwardedFor` | `boolean` | No | `false` | Use the first `X-Forwarded-For` entry as the client IP. Only enable behind a trusted reverse proxy. |
36
+
| `rateLimit.x402` | `object` | **Yes** | -- | Stricter per-IP bucket on x402 verification attempts (each one fires several chain-RPC reads). Shares `trustForwardedFor`. |
37
+
| `rateLimit.x402.window` | `number` | Yes | -- | Time window in milliseconds. |
38
+
| `rateLimit.x402.max` | `number` | Yes | -- | Maximum x402 verification attempts per IP within the window. |
33
39
34
40
## Minimal
35
41
36
-
`port` and `rateLimit` are required:
42
+
`port` and `rateLimit` (including the `x402` sub-block) are required:
37
43
38
44
```yaml
39
45
server:
40
46
port: 3000
41
47
rateLimit:
42
48
window: 60000
43
49
max: 100
50
+
x402:
51
+
window: 60000
52
+
max: 30
44
53
```
45
54
46
55
This binds to `0.0.0.0:3000` with a default `Access-Control-Allow-Origin: *` header. If you front the airnode with your
@@ -57,6 +66,9 @@ server:
57
66
rateLimit:
58
67
window: 60000 # 60 seconds
59
68
max: 100 # 100 requests per 60s per IP
69
+
x402:
70
+
window: 60000
71
+
max: 30 # 30 x402 verification attempts per 60s per IP
60
72
```
61
73
62
74
When a client exceeds the limit, the server returns `429 Too Many Requests`.
@@ -68,6 +80,14 @@ every client would share one bucket — set `rateLimit.trustForwardedFor: true`
68
80
instead. Only enable this when a trusted proxy controls that header; a client-supplied `X-Forwarded-For` is otherwise
69
81
trivially spoofable.
70
82
83
+
### x402 verification bucket
84
+
85
+
`rateLimit.x402`is a separate, stricter per-IP bucket that applies only to **submitted x402 payment proofs**. Each
86
+
verification fires several chain-RPC reads, so an unauthenticated flooder would otherwise drain the operator's RPC quota
87
+
even at a generous global `rateLimit.max`. The 402-challenge response (sent when no proof header is present) does not
88
+
draw from this bucket. The same client-IP key is used as the global limit, so `trustForwardedFor` applies consistently
89
+
to both. When exceeded, the response is `401 Too many x402 verification attempts — slow down`.
90
+
71
91
## CORS
72
92
73
93
CORS headers are included on every response (and on the `OPTIONS` preflight, which returns `204`):
0 commit comments