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 server.host and rateLimit.trustForwardedFor required
Two remaining hidden defaults flagged by the explicit-over-implicit
principle:
- `server.host` was defaulted to `'0.0.0.0'`. That's a security choice
(every interface vs loopback-only), not a universal default. Operators
should declare it.
- `rateLimit.trustForwardedFor` was defaulted to `false`. Behind a
reverse proxy this is the difference between per-client and per-proxy
rate limiting — wrong answer either way is operationally surprising.
Both are now required. Updated all four example configs, inline test
YAMLs (schema/parser/validate test fixtures), the server.md reference,
and the "applies defaults" test (which no longer asserts host defaulting
since there's no default to assert).
| `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. |
27
+
| Field | Type | Required | Default | Description |
| `port` | `number` | **Yes** | -- | TCP port the server listens on. |
30
+
| `host` | `string` | **Yes** | -- | Bind address. `'0.0.0.0'` binds every interface; `'127.0.0.1'` restricts to localhost. |
31
+
| `cors` | `object` | No | -- | CORS configuration. When omitted, `Access-Control-Allow-Origin: *` is used. |
32
+
| `cors.origins` | `string[]` | No | `['*']` | Allow-list of origins. The request's `Origin` is reflected back only if it matches an entry. |
33
+
| `rateLimit` | `object` | **Yes** | -- | Per-IP rate limiting. Set `max` very high to effectively disable it. |
34
+
| `rateLimit.window` | `number` | **Yes** | -- | Time window in milliseconds. |
35
+
| `rateLimit.max` | `number` | **Yes** | -- | Maximum requests per IP within the window. |
36
+
| `rateLimit.trustForwardedFor` | `boolean` | **Yes** | --| Use the first `X-Forwarded-For` entry as the client IP. Set `true` only behind a trusted reverse proxy; otherwise `false`. |
37
+
| `rateLimit.x402` | `object` | **Yes** | -- | Stricter per-IP bucket on x402 verification attempts (each one fires several chain-RPC reads). Shares `trustForwardedFor`. |
38
+
| `rateLimit.x402.window` | `number` | **Yes** | -- | Time window in milliseconds. |
39
+
| `rateLimit.x402.max` | `number` | **Yes** | -- | Maximum x402 verification attempts per IP within the window. |
39
40
40
41
## Minimal
41
42
42
-
`port`and `rateLimit` (including the `x402` sub-block) are required:
43
+
`port`, `host`, and `rateLimit` (including `trustForwardedFor` and the `x402` sub-block) are required:
43
44
44
45
```yaml
45
46
server:
46
47
port: 3000
48
+
host: '0.0.0.0'
47
49
rateLimit:
48
50
window: 60000
49
51
max: 100
52
+
trustForwardedFor: false
50
53
x402:
51
54
window: 60000
52
55
max: 30
@@ -63,9 +66,11 @@ resetting at fixed intervals.
63
66
```yaml
64
67
server:
65
68
port: 3000
69
+
host: '0.0.0.0'
66
70
rateLimit:
67
71
window: 60000 # 60 seconds
68
72
max: 100 # 100 requests per 60s per IP
73
+
trustForwardedFor: false
69
74
x402:
70
75
window: 60000
71
76
max: 30 # 30 x402 verification attempts per 60s per IP
@@ -75,10 +80,11 @@ When a client exceeds the limit, the server returns `429 Too Many Requests`.
75
80
76
81
The rate limiter tracks up to 10,000 unique IPs. When this limit is reached, the oldest entries are evicted.
77
82
78
-
By default the client IP is the socket peer. If Airnode runs behind a reverse proxy that is the proxy's address, so
79
-
every client would share one bucket — set `rateLimit.trustForwardedFor: true` to use the first `X-Forwarded-For` entry
80
-
instead. Only enable this when a trusted proxy controls that header; a client-supplied `X-Forwarded-For` is otherwise
81
-
trivially spoofable.
83
+
The client IP defaults to the socket peer when `trustForwardedFor` is `false`. If Airnode runs behind a reverse proxy
84
+
the peer is the proxy itself, so every client would share one bucket — set `trustForwardedFor: true` to use the first
85
+
`X-Forwarded-For`entry instead. Only enable this when a trusted proxy controls that header; a client-supplied
86
+
`X-Forwarded-For`is otherwise trivially spoofable, which would let any client bypass the rate limit by picking a fresh
0 commit comments