Skip to main content
Behind a reverse proxy or tunnel the socket peer is the proxy for every request, so per-IP policy collapses onto one bucket — declaring the proxy trusted resolves the real client instead.

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 walks X-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 existing GatewayConfig. 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.
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.
An attacker prepending a spoofed 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.
Anything set here is allowed to spoof X-Forwarded-For from the gateway’s point of view — only list addresses you actually own. Empty (default) is the safe posture for a directly-reachable gateway. The resolver is fail-closed for anything proxy-shaped but unattributable; proxy:<peer_ip> buckets in per-IP rate-limit logs mean “one bucket per misconfigured proxy,” not per real client.

Best Practices

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.
Trusting the whole internet removes the protection entirely — every caller becomes a trusted hop and any spoofed X-Forwarded-For is believed.
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.
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.

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 precedence

Gateway

Main gateway configuration and the gateway: block