Trust proxy

When Ingenium sits behind a reverse proxy (nginx, Caddy, a CDN, a load balancer), ctx.ip defaults to the socket peer - which is the proxy, not the client. The trustProxy option tells Ingenium how far down the X-Forwarded-* chain to trust.

Configuring

const app = ingenium({ trustProxy: 'loopback' })

// Then in handlers:
ctx.ip          // real client IP after walking the X-Forwarded-For chain
ctx.protocol    // 'https' if X-Forwarded-Proto: https
ctx.hostname    // X-Forwarded-Host (if set), else Host header

This mirrors Express's app.set('trust proxy', ...):

ValueBehavior
false (default)Never trust XFF - ctx.ip is the socket peer
trueTrust the entire chain - leftmost XFF entry wins
number nTrust n upstream hops
'loopback'Trust 127.0.0.0/8, ::1
'linklocal'Trust 169.254.0.0/16, fe80::/10
'uniquelocal'Trust 10/8, 172.16/12, 192.168/16, fc00::/7
'10.0.0.0/8' (CIDR)Trust matching addresses
string[]Multiple of any of the above
(ip, hopIdx) => booleanCustom predicate

Note: The default ingenium.rateLimit keygen reads X-Forwarded-For via ctx.ip. Make sure trustProxy is set correctly before relying on rate limiting in production, or attackers can spoof the header.

What gets affected

When trustProxy is enabled, the following ctx fields become XFF-aware:

  • ctx.ip - the resolved client IP after walking the chain.
  • ctx.ips - the full forwarded chain (read-only array).
  • ctx.protocol - 'https' if X-Forwarded-Proto says so.
  • ctx.secure - boolean shortcut for ctx.protocol === 'https'.
  • ctx.hostname - X-Forwarded-Host (if set), else the Host header.

ctx.remoteAddress always reports the immediate socket peer, regardless of trustProxy. ctx.baseProtocol reports the underlying transport (http vs https).

Where to next?