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
- TLS proof: requestProof rejects a proof whose claim.parameters don't match
the request Airnode made (or that is malformed) — non-fatal; corrected the
misleading pipeline comment; documented request-vs-response divergence.
- Streaming mode runs inside runWithContext and calls callError/callResponseSent
like the sync path, and propagates a non-200 pipeline outcome as a plain HTTP
error response rather than a 200 SSE frame carrying an error payload.
- The response cache is sync-mode only — async/stream neither read nor write it
(serving a cached JSON body there would break the 202/SSE contract).
- Async store: finished requests are retained only ~60s for polling instead of
the full 10-minute TTL, and a finished/expired slot is reclaimed when the
store is full — MAX_PENDING is no longer a sustained-throughput cap.
- Rate limiting: opt-in server.rateLimit.trustForwardedFor uses the first
X-Forwarded-For entry as the key (for Airnode behind a trusted reverse proxy);
default false.
- TLS proof gateway timeout is configurable via settings.proof.timeout
(default 30000ms).
- Dropped the vestigial x402 paymentId — the txHash dedup is the per-payment
uniqueness guard; the signed message is now
keccak256(encodePacked(airnode, endpointId, uint64(expiresAt))). Also
clarified that this scheme is x402-flavoured, not the x402 wire protocol.
- buildApiRequest rejects a cookie parameter value containing ';', CR, or LF.
- FHE instance: caches the createInstance promise (concurrent first requests
share one call), drops a rejected promise so the next request retries (also
picks up a rotated chain key), and clears the instance on an encrypt failure.
- Documented: caching an encrypt endpoint replays the same signed ciphertext
(only one on-chain submission lands per window); set encoding.times on
encrypt endpoints; the canonical endpoint-ID string format.
| `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 | `['*']` | Allowed origins. Each entry is joined with `, ` in the response header. |
29
+
| `rateLimit` | `object` | No | -- | Per-IP rate limiting. When omitted, no rate limiting is applied. |
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. |
32
33
33
34
## Minimal
34
35
@@ -58,6 +59,11 @@ When a client exceeds the limit, the server returns `429 Too Many Requests`.
58
59
59
60
The rate limiter tracks up to 10,000 unique IPs. When this limit is reached, the oldest entries are evicted.
60
61
62
+
By default the client IP is the socket peer. If Airnode runs behind a reverse proxy that is the proxy's address, so
63
+
every client would share one bucket — set `rateLimit.trustForwardedFor: true` to use the first `X-Forwarded-For` entry
64
+
instead. Only enable this when a trusted proxy controls that header; a client-supplied `X-Forwarded-For` is otherwise
65
+
trivially spoofable.
66
+
61
67
## CORS
62
68
63
69
CORS headers are included on every response. The `OPTIONS` preflight handler returns:
| `type` | `string` | Yes | Must be `'reclaim'`. |
64
+
| `gatewayUrl` | `string` | Yes | Full URL of the proof gateway endpoint. Must be a valid URL. |
65
+
| `timeout` | `number` | No (default `30000`) | Gateway request timeout in milliseconds. The proof is fetched after signing on the sync path, so this latency is added to the response; a timeout just omits the `proof` field. |
65
66
66
67
When enabled, Airnode requests a TLS proof from the gateway after each API call. The proof is attached to the response
67
68
in a `proof` field alongside the signature. See [TLS Proofs](/docs/concepts/proofs) for details on how proofs work.
0 commit comments