Quick Start
1
Simple (Python)
Declare the proxy’s network so the gateway keys per-IP policy on the real client.
2
YAML
Set
trusted_proxies under the gateway: block in gateway.yaml.3
CLI
Pass
--trusted-proxy (repeatable) to praisonai gateway start.How It Works
Every per-IP seam consults one pure decision that walksX-Forwarded-For across declared trusted hops, then keys policy on the first untrusted address.
The walk peels trusted hops right→left and stops at the first untrusted hop, so a client-supplied spoofed prefix cannot be peeled past. A malformed hop (e.g. unknown) fails closed to the socket peer.
Which option should I pick?
Every inbound request lands in one of five classifications.
An empty
trusted_proxies (default) preserves today’s raw-peer behaviour byte-for-byte — every seam keys on the socket peer as before.
Configuration Options
The feature adds a single field on the existingGatewayConfig.
Entries accept a CIDR (
10.0.0.0/8, 2001:db8::/32), a bare IPv4/IPv6 address (192.168.1.10, 2001:db8::1), whitespace is trimmed, and malformed entries are silently skipped (fail-closed for the entry, not the whole config).
The trusted set resolves in this order every request, so a config reload takes effect without a restart: CLI --trusted-proxy (always wins) → YAML gateway.trusted_proxies → Python GatewayConfig(trusted_proxies=[...]).
Adding or removing a proxy in
gateway.yaml and hot-reloading takes effect on the next request — no restart. The CLI --trusted-proxy override always wins.Common Patterns
Three real deployment shapes cover almost every setup.- nginx / reverse proxy
- Cloudflare in front
- Tailscale Serve / loopback tunnel
The proxy peer (
10.0.0.5) is trusted, so the real client (203.0.113.9) is resolved from X-Forwarded-For: 203.0.113.9, 10.0.0.5.10.0.0.9 to the chain (10.0.0.9, 198.51.100.7, 10.0.0.1) with trusted_proxies: [10.0.0.0/8] still resolves to 198.51.100.7 — the walk stops at the first untrusted hop.
Best Practices
Set the exact CIDR of your reverse proxy, not a broader range
Set the exact CIDR of your reverse proxy, not a broader range
Scope
trusted_proxies to the narrowest network that contains your proxy. A broad range trusts addresses you do not control and lets them spoof the forwarded chain.Don't trust 0.0.0.0/0
Don't trust 0.0.0.0/0
Trusting the whole internet removes the protection entirely — every caller becomes a trusted hop and any spoofed
X-Forwarded-For is believed.For Cloudflare, use their published IP ranges and refresh periodically
For Cloudflare, use their published IP ranges and refresh periodically
Trust only Cloudflare’s official edge ranges, and update the list when they publish changes. Stale ranges either trust addresses you shouldn’t or fail closed on real traffic.
Verify with a spoofed curl
Verify with a spoofed curl
Hit the gateway directly with a forged
X-Forwarded-For — per-IP rate limits should still key on your actual IP, confirming the header is ignored on a directly-reachable path.Related
Edge Protections
Pre-auth connection budget that now keys on the real client IP
Rate Limiting
Per-identity rate limits that separate real callers behind a proxy
Gateway CLI
The
--trusted-proxy flag and its precedenceGateway
Main gateway configuration and the
gateway: block
