envoyproxy / envoyproxy/gateway
GeoIP authorization: support clientIPDetection.xForwardedFor.trustedCIDRs
- Dominant language
- Go
- Stars
- 3k
- Forks
- 864
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 140
Description
### Description
`SecurityPolicy` authorization rules with `clientIPGeoLocations` currently reject the `trustedCIDRs` client IP detection mode. `validateAuthorizationGeoIP` returns:
```
authorization clientIPGeoLocations does not support ClientIPDetection.XForwardedFor.TrustedCIDRs
```
(`internal/gatewayapi/securitypolicy.go`, L3134 on current main.)
The supported modes are `directSourceIP`, `xForwardedFor.numTrustedHops` and `customHeader`. This is a feature request to also support `xForwardedFor.trustedCIDRs`.
### Use case
Internet-facing gateway with:
- a GeoIP authorization policy (country blocklist), and
- a client mix of direct clients and clients behind trusted CDNs (Cloudflare, Fastly).
None of the supported detection modes gives the GeoIP filter the real end-user IP for that mix:
- `directSourceIP` geolocates the CDN edge for proxied traffic, so the country rules do not apply to the end user.
- `xForwardedFor.numTrustedHops` cannot express a mixed topology: direct and CDN-fronted traffic have different hop counts, and a fixed count either trusts client-spoofable entries or resolves to the CDN edge.
- `customHeader` needs a trusted upstream to inject the header, which does not exist for direct traffic.
`trustedCIDRs` is exactly the right semantic for this topology (unspoofable, correct for both direct and CDN-fronted clients), and it already works at the HCM level (`original_ip_detection.xff` with `xff_trusted_cidrs`) — it is only the GeoIP authorization path that rejects it.
### Why it is rejected today
Envoy's GeoIP filter (`envoy.extensions.filters.http.geoip.v3.Geoip`) selects its IP source through `xff_config` (only `xff_num_trusted_hops`) or `custom_header_config`. There is no trusted-CIDRs option, so Envoy Gateway cannot wire the walk into the filter and rejects the combination instead of letting the GeoIP result silently diverge from the HCM-detected client address.
### Possible implementations
**A. Upstream Envoy change**: add `xff_trusted_cidrs` to the GeoIP filter's `XffConfig`, mirroring `envoy.extensions.http.original_ip_detection.xff.v3.XffConfig`. Then Envoy Gateway maps `trustedCIDRs` in `buildHCMGeoIPFilter` the same way it maps `numTrustedHops`, and drops the validation rejection. I am happy to file the corresponding Envoy feature request if this is the preferred direction.
**B. Envoy Gateway only**: when `trustedCIDRs` is configured, the HCM already computes the detected client address via `original_ip_detection.xff` and exposes it as `x-envoy-external-address`. The GeoIP filter could be configured with `custom_header_config: { header_name: x-envoy-external-address }` to consume that result. This needs verification that the header mutation is guaranteed to happen before the GeoIP filter reads it, and that the header cannot be client-injected in this position.
### Environment
Envoy Gateway v1.9+, GeoIP MaxMind provider, `clientIPGeoLocations` authorization rules.
### Relates to
- #8956 (directSourceIP client IP detection for GeoIP authorization)
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in internal/gatewayapi/securitypolicy.go at validateAuthorizationGeoIP and inspect buildHCMGeoIPFilter. Determine whether Envoy needs trusted-CIDR support or whether the existing x-envoy-external-address can be consumed safely and in time by the GeoIP filter. Done means trustedCIDRs is accepted for GeoIP authorization and the detected client address remains correct for direct and CDN-fronted traffic.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, authorization, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100