Skip to main content

X-Forwarded-For Settings

The X-Forwarded-For (XFF) HTTP header lists the IP addresses a request has passed through on its way from the end user (client) to a backend service.

(This is most relevant for deployments where there is another L7 proxy or load balancer in front of Pomerium, or in between Pomerium and upstream services.)

The following settings affect the way Pomerium sets or consumes the XFF header.

Skip XFF Append

By default, when Pomerium receives a request, it appends the IP address of the direct downstream client to the XFF header before proxying the request to the upstream service.

However, if you set the Skip XFF Append (skip_xff_append) option to true, Pomerium will not modify an incoming XFF header. Instead, Pomerium will pass this incoming header to the upstream service unchanged.

How to configure

Config file keysEnvironment variablesTypeDefault
skip_xff_appendSKIP_XFF_APPENDbooleanfalse

Examples

skip_xff_append: true
SKIP_XFF_APPEND=true

Skip XFF Append examples

Assume you have a load balancer in front of Pomerium, and it connects to Pomerium from IP address 10.1.2.3. Say that the load balancer is configured to populate the X-Forwarded-For header, so that if a client connects to the load balancer from IP address 192.0.5.1, then the load balancer will set X-Forwarded-For: 192.0.5.1 on the request to Pomerium.

With skip_xff_append set to false (the default behavior), Pomerium will then append the IP address of the load balancer on the request made to the upstream service:

Request Details
X-Forwarded-For: 192.0.5.1,10.1.2.3

With skip_xff_append set to true, Pomerium will not append the IP address of the load balancer on the request made to the upstream service:

Request Details
X-Forwarded-For: 192.0.5.1

XFF Number of Trusted Hops

The XFF Number of Trusted Hops (xff_num_trusted_hops) setting instructs Pomerium whether to trust an incoming request's XFF header.

When unset or set to 0, Pomerium will not trust the incoming XFF header. Pomerium will consider the client IP address to be the IP address of the direct downstream client.

This affects the client IP address logged in the access logs (if configured; see Access log fields). The client IP address is also sent to the upstream service in the x-envoy-external-address header.

X-Forwarded-Proto header

This setting also affects whether Pomerium trusts the X-Forwarded-Proto header. This header indicates the originating protocol (either HTTP or HTTPS) of the downstream client request. Pomerium will only trust the downstream X-Forwarded-Proto header if you set xff_num_trusted_hops to a non-zero value.

When set to 0, Pomerium will set the X-Forwarded-Proto header to either http or https depending on whether the downstream connection is secured over TLS.

How to configure

Config file keysEnvironment variablesTypeUsage
xff_num_trusted_hopsXFF_NUM_TRUSTED_HOPSuint32optional

Examples

xff_num_trusted_hops: 2
XFF_NUM_TRUSTED_HOPS=2

XFF Number of Trusted Hops examples

As in the previous example, assume you have a load balancer in front of Pomerium, which connects to Pomerium from IP address 10.1.2.3, and is configured to populate the X-Forwarded-For header.

With xff_num_trusted_hops set to 0, Pomerium's access log will show the load balancer IP address (10.1.2.3) as the client IP address for all incoming requests.

config.yaml
xff_num_trusted_hops: 0
access_log_fields: [forwarded-for, ip, method, path]

Example access log entry:

{
"level": "info",
"service": "envoy",
"forwarded-for": "192.0.5.1,10.1.2.3",
"ip": "10.1.2.3",
"method": "GET",
"path": "/",
"time": "2024-07-08T16:42:48-07:00",
"message": "http-request"
}

With the xff_num_trusted_hops option set to 1, Pomerium will trust the client IP address populated by the load balancer:

config.yaml
xff_num_trusted_hops: 1
access_log_fields: [forwarded-for, ip, method, path]

Example access log entry:

{
"level": "info",
"service": "envoy",
"forwarded-for": "192.0.5.1,10.1.2.3",
"ip": "192.0.5.1",
"method": "GET",
"path": "/",
"time": "2024-07-08T16:42:48-07:00",
"message": "http-request"
}
Additional Resource

See the Envoy docs for more information about the X-Forwarded-For header.