Skip to content

api: GeoIP#8002

Open
zhaohuabing wants to merge 3 commits intoenvoyproxy:mainfrom
zhaohuabing:geoip-api
Open

api: GeoIP#8002
zhaohuabing wants to merge 3 commits intoenvoyproxy:mainfrom
zhaohuabing:geoip-api

Conversation

@zhaohuabing
Copy link
Member

@zhaohuabing zhaohuabing commented Jan 21, 2026

API for #4412.

API:

  • Configure shared GeoIP provider settings in EnvoyProxy.spec.geoIP.provider.
  • Use ClientTrafficPolicy.spec.clientIPDetection for client IP extraction (for example, trusted XFF hops). If route-level settings are required in the future, an override can be added to the SecurityPolicy later.
  • Enforce geolocation decisions in SecurityPolicy.spec.authorization.rules[].principal.geoLocation.
  • Support local MaxMind .mmdb databases via file paths; operators mount and refresh databases outside Envoy Gateway.

Example:

  1. Create a PVC and mount it into Envoy via EnvoyProxy.spec.provider.kubernetes.pod.{volumes,container.volumeMounts}.
  2. Run MaxMind geoipupdate as a sidecar writing into the shared mount.
  3. Configure trusted client IP extraction in ClientTrafficPolicy.
  4. enforce GeoIP allow/deny in SecurityPolicy.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
spec:
provider:
  kubernetes:
    pod:
      volumes:
      - name: geoip-db
        persistentVolumeClaim:
          claimName: geoip-db
      container:
        volumeMounts:
        - name: geoip-db
          mountPath: /var/lib/geoip
geoIP:
  provider:
    type: MaxMind
    maxMind:
      cityDbPath: /var/lib/geoip/GeoLite2-City.mmdb
      asnDbPath: /var/lib/geoip/GeoLite2-ASN.mmdb
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
spec:
targetRefs:
- group: gateway.networking.k8s.io
  kind: Gateway
  name: eg
clientIPDetection:
  xForwardedFor:
    numTrustedHops: 2
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
spec:
targetRefs:
- group: gateway.networking.k8s.io
  kind: Gateway
  name: eg
authorization:
  rules:
  - action: Deny
    principal:
      geoLocations:
        - country: foo
        - country: bar

This keeps vendor-specific download logic out of Envoy Gateway while giving users a native way to enforce GeoIP-based policies.

Alternate approach:

Push GeoIP decisions into SecurityPolicy.authorization by matching on the headers the GeoIP filter emits. That technically works (you’d add header conditions under uthorization.rules[].principal.headers), but it’s brittle: users must remember the exact header names, every policy has to duplicate the boilerplate, and any future header renames become breaking. Embedding allow/deny rules inside the geoip block keeps the UX intuitive—configure lookup + provider + enforcement in one place—and lets the controller manage header wiring internally.

@zhaohuabing zhaohuabing requested a review from a team as a code owner January 21, 2026 02:49
@netlify
Copy link

netlify bot commented Jan 21, 2026

Deploy Preview for cerulean-figolla-1f9435 canceled.

Name Link
🔨 Latest commit 5b4db72
🔍 Latest deploy log https://app.netlify.com/projects/cerulean-figolla-1f9435/deploys/69972492947de30008d85721

@zhaohuabing zhaohuabing marked this pull request as draft January 21, 2026 02:49
@zhaohuabing zhaohuabing force-pushed the geoip-api branch 2 times, most recently from dd737d9 to 16882c2 Compare January 21, 2026 02:55
@codecov
Copy link

codecov bot commented Jan 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.57%. Comparing base (fa3ff1d) to head (5b4db72).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8002      +/-   ##
==========================================
- Coverage   73.58%   73.57%   -0.01%     
==========================================
  Files         242      242              
  Lines       37003    37003              
==========================================
- Hits        27228    27226       -2     
- Misses       7856     7857       +1     
- Partials     1919     1920       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zhaohuabing zhaohuabing marked this pull request as ready for review January 21, 2026 03:06
@zhaohuabing zhaohuabing force-pushed the geoip-api branch 3 times, most recently from 3a6461f to b56a4b1 Compare January 21, 2026 04:00
@zhaohuabing zhaohuabing changed the title API: GeoIP api: GeoIP Jan 21, 2026
@funkluk
Copy link

funkluk commented Jan 22, 2026

Hi @zhaohuabing
Thanks for your effort - we would look forward to having such a feature!
IMHO, I would rather see a solution more like the one you described in the alternative approach.
I see three parts in your configuration:

  1. ClientIP Source
  2. GeoIP Database source
  3. Access rules based on geo information

Client IP Source

In my opinion, this setting is redundant to [ClientIPDetectionSettings](https://gateway.envoyproxy.io/latest/api/extension_types/#clientipdetectionsettings) from ClientTrafficPolicy`.
Therefore, I wouldn't repeat that here and rely on this setting.
Or do you see a use-case that would make sense to have two separate settings?

Envoy allows the different XFF configuration for HCM and GeoIP filter, I don't know the exact reason, but there might be use cases that they could be different?

Huabing:
Envoy supports configuring XFF differently for HCM and the GeoIP filter. I’m not sure why, but there may be edge cases where they need to diverge.

One possible use case is that different routes may need different XFF settings (e.g., different source headers or different hop counts). That isn’t feasible with ClientTrafficPolicy today since it applies at the Gateway level, not per-route.

Another concern with this approach is that it would generate XFF configuration for both the HCM and the GeoIP filter. That could have unintended side effects in cases where HCM-level XFF configuration isn’t desired.

That said, I think consolidating this in one place in the control plane is a better UX and helps avoid misconfiguration. An optional XFF configuration in the SecurityPolicy should also be supported to allow route-level configuration.

ref:

GeoIP Database source

The database source is an infrastructure responsibility, and I don't see that this information should be provided for each SecurityPolicy. As an application owner, I just want to enable GeoIP access rules without the need to know where the DB is located.
Besides, you might want to have the geo information in the access logs, so this would also require configuring geolocation detection on a cluster level.
Therefore, I would see the option to enable a GeoIP Provider on a cluster level, for example, in the EnvoyProxy or EnvoyGatway spec.

Huabing:
Agree, it makes more sense to share the provider info across SPs.

Access rules

I think configuring access decision with geo location information as part of the SecurityPolicy.authorization rules would be the way to go. I agree with your concern about using the existing header principal. But what would you think about extending principal with geoLocation or clientLocation?

geolocation:
    countries: ["AB", "CD"]
    cities: []
    asns: []
    ...

This would ensure that the geo information population and the headers to match are entirely within the responsibility of the controller manager.

Huabing:
Yeah, this would work, and it allows using geo information with other conditions for more flexible access control.

What do you think?

Huabing:
All the suggestions are legitimate. One main concern I have is that GeoIP configuration would be spread across four places:

  • EnvoyGateway / EnvoyProxy for providers
  • ClientTrafficPolicy for source IP
  • SecurityPolicy (GeoIP) for the provider reference
  • SecurityPolicy (Authorization) for access control

That feels harder for users to understand and configure correctly.

@zhaohuabing zhaohuabing marked this pull request as draft January 23, 2026 07:15
@sboulkour
Copy link

Hi @zhaohuabing, do you know if this a PR that could be shipped with v1.8.0 ?

My team and I are currently benchmarking possible replacement of ingress-nginx, and Envoy Gateway has been a great candidate so far. Except on one mandatory feature for us that is GeoIP filtering (to deny countries under embargo). I know this is debatable in terms of real protection, but this is more of a legal matter and we can't do this without this feature.

BTW, thank you very much for your work (you personnaly and Envoy/Gateway teams in general) on this project !

@zhaohuabing
Copy link
Member Author

zhaohuabing commented Feb 11, 2026

@funkluk replied to your comment inline(text in italics) to make it easier to follow.

@zhaohuabing
Copy link
Member Author

zhaohuabing commented Feb 11, 2026

@sboulkour No guarantees, but aiming for v1.8.0 — and it looks very likely if we can agree on the API.

@zhaohuabing zhaohuabing added this to the v1.8.0-rc.1 Release milestone Feb 12, 2026
@funkluk
Copy link

funkluk commented Feb 13, 2026

@zhaohuabing seems like we are on the same page, and I fully agree that the drawback is that the config is a bit more cluttered. But on the other hand, it allows IMHO a more flexible usage.

Two last remarks:

  1. I'm not sure if we currently need more than one provider, as Envoy proxy has no other implementation than the MaxMind provider. I don't see a practical use-case of having two different database sets in the same gateway... This would also remove the requirement that we have to select the provider in the SecurityPolicy

  2. IMHO I'd wait before implementing an XFF configuration on route-level until someone comes up with the actual need...

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
@zhaohuabing zhaohuabing force-pushed the geoip-api branch 2 times, most recently from ecd3c12 to 8ebe1ff Compare February 19, 2026 04:55
// EnvoyProxyGeoIP defines shared GeoIP provider settings for EnvoyProxy.
type EnvoyProxyGeoIP struct {
// Provider defines the GeoIP provider configuration used by GeoIP filter instances.
Provider GeoIPProvider `json:"provider"`
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a EnvoyProxyGeoIP layer for future-proofing.

//
// +optional
// +notImplementedHide
GeoLocation *GeoLocationPrincipal `json:"geoLocation,omitempty"`
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The. GeoLocation access control can be applied on both the HTTP and TCP layer, depending on the targeted route type.

@zhaohuabing zhaohuabing marked this pull request as ready for review February 19, 2026 05:08
Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
@zhaohuabing zhaohuabing marked this pull request as draft February 19, 2026 14:07
@zhaohuabing zhaohuabing marked this pull request as ready for review February 19, 2026 14:52
Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments