diff --git a/api/v1alpha1/authorization_types.go b/api/v1alpha1/authorization_types.go
index 05b5ef59ae..54acaa7512 100644
--- a/api/v1alpha1/authorization_types.go
+++ b/api/v1alpha1/authorization_types.go
@@ -72,7 +72,7 @@ type Operation struct {
// or any other identity that can be extracted from a custom header.
// If there are multiple principal types, all principals must match for the rule to match.
//
-// +kubebuilder:validation:XValidation:rule="(has(self.clientCIDRs) || has(self.jwt) || has(self.headers))",message="at least one of clientCIDRs, jwt, or headers must be specified"
+// +kubebuilder:validation:XValidation:rule="(has(self.clientCIDRs) || has(self.jwt) || has(self.headers) || has(self.clientIPGeoLocations))",message="at least one of clientCIDRs, jwt, headers, or clientIPGeoLocations must be specified"
type Principal struct {
// ClientCIDRs are the IP CIDR ranges of the client.
// Valid examples are "192.168.1.0/24" or "2001:db8::/64"
@@ -128,6 +128,60 @@ type Principal struct {
// +kubebuilder:validation:MinItems=1
// +notImplementedHide
SourceCIDRs []CIDR `json:"sourceCIDRs,omitempty"`
+
+ // ClientIPGeoLocations authorizes the request based on geolocation metadata derived from the client IP.
+ // If multiple entries are specified, one of the ClientIPGeoLocation entries must match for the rule to match.
+ //
+ // +optional
+ // +kubebuilder:validation:MinItems=1
+ // +notImplementedHide
+ ClientIPGeoLocations []ClientIPGeoLocation `json:"clientIPGeoLocations,omitempty"`
+}
+
+// ClientIPGeoLocation specifies geolocation-based match criteria for authorization.
+//
+// +kubebuilder:validation:XValidation:rule="has(self.country) || has(self.region) || has(self.city) || has(self.asn) || has(self.isp) || has(self.anonymous)",message="at least one of country, region, city, asn, isp, or anonymous must be specified"
+type ClientIPGeoLocation struct {
+ // Country is the country ISO code associated with the client IP.
+ //
+ // +optional
+ // +kubebuilder:validation:MinLength=2
+ // +kubebuilder:validation:MaxLength=2
+ // +kubebuilder:validation:Pattern=`^[A-Za-z]{2}$`
+ Country *string `json:"country,omitempty"`
+
+ // Region is the region ISO code associated with the client IP.
+ //
+ // +optional
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=16
+ // +kubebuilder:validation:Pattern=`^[A-Za-z0-9-]+$`
+ Region *string `json:"region,omitempty"`
+
+ // City is the city associated with the client IP.
+ //
+ // +optional
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=128
+ City *string `json:"city,omitempty"`
+
+ // ASN is the autonomous system number associated with the client IP.
+ //
+ // +optional
+ // +kubebuilder:validation:Minimum=1
+ ASN *uint32 `json:"asn,omitempty"`
+
+ // ISP is the internet service provider associated with the client IP.
+ //
+ // +optional
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=256
+ ISP *string `json:"isp,omitempty"`
+
+ // Anonymous matches anonymous network detection signals.
+ //
+ // +optional
+ Anonymous *GeoIPAnonymousMatch `json:"anonymous,omitempty"`
}
// AuthorizationHeaderMatch specifies how to match against the value of an HTTP header within a authorization rule.
diff --git a/api/v1alpha1/envoyproxy_types.go b/api/v1alpha1/envoyproxy_types.go
index 4ce860bd39..ad08058116 100644
--- a/api/v1alpha1/envoyproxy_types.go
+++ b/api/v1alpha1/envoyproxy_types.go
@@ -198,6 +198,18 @@ type EnvoyProxySpec struct {
// +listMapKey=name
// +optional
DynamicModules []DynamicModuleEntry `json:"dynamicModules,omitempty"`
+
+ // GeoIP defines shared GeoIP provider configuration for this EnvoyProxy fleet.
+ //
+ // +optional
+ // +notImplementedHide
+ GeoIP *EnvoyProxyGeoIP `json:"geoIP,omitempty"`
+}
+
+// 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"`
}
// +kubebuilder:validation:Enum=Strict;InsecureSyntax;Disabled
diff --git a/api/v1alpha1/geoip_types.go b/api/v1alpha1/geoip_types.go
new file mode 100644
index 0000000000..8e42c47d78
--- /dev/null
+++ b/api/v1alpha1/geoip_types.go
@@ -0,0 +1,105 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package v1alpha1
+
+// GeoIPProvider defines provider-specific settings.
+// +kubebuilder:validation:XValidation:rule="self.type == 'MaxMind' ? has(self.maxMind) : true",message="maxMind must be set when type is MaxMind"
+type GeoIPProvider struct {
+ // +kubebuilder:validation:Enum=MaxMind
+ // +kubebuilder:validation:Required
+ Type GeoIPProviderType `json:"type"`
+
+ // MaxMind configures the MaxMind provider.
+ //
+ // +optional
+ MaxMind *GeoIPMaxMind `json:"maxMind,omitempty"`
+}
+
+// GeoIPProviderType enumerates GeoIP providers supported by Envoy Gateway.
+type GeoIPProviderType string
+
+const (
+ // GeoIPProviderTypeMaxMind configures Envoy with the MaxMind provider pointing to local files.
+ GeoIPProviderTypeMaxMind GeoIPProviderType = "MaxMind"
+)
+
+// GeoIPMaxMind configures the MaxMind provider.
+// These database files are expected to be mounted into the Envoy container, and a sidecar container can be used to update the database files.
+// +kubebuilder:validation:XValidation:rule="has(self.cityDbSource) || has(self.countryDbSource) || has(self.asnDbSource) || has(self.ispDbSource) || has(self.anonymousIpDbSource)",message="at least one MaxMind database source must be specified"
+type GeoIPMaxMind struct {
+ // CityDBSource configures the City database source.
+ //
+ // +optional
+ CityDBSource *GeoIPDBSource `json:"cityDbSource,omitempty"`
+
+ // CountryDBSource configures the Country database source.
+ //
+ // +optional
+ CountryDBSource *GeoIPDBSource `json:"countryDbSource,omitempty"`
+
+ // ASNDBSource configures the ASN database source.
+ //
+ // +optional
+ ASNDBSource *GeoIPDBSource `json:"asnDbSource,omitempty"`
+
+ // ISPDBSource configures the ISP database source.
+ //
+ // +optional
+ ISPDBSource *GeoIPDBSource `json:"ispDbSource,omitempty"`
+
+ // AnonymousIPDBSource configures the Anonymous IP database source.
+ //
+ // +optional
+ AnonymousIPDBSource *GeoIPDBSource `json:"anonymousIpDbSource,omitempty"`
+}
+
+// GeoIPDBSource defines where a GeoIP .mmdb database can be loaded from.
+type GeoIPDBSource struct {
+ // Local is a database source from a local file.
+ Local LocalGeoIPDBSource `json:"local"`
+}
+
+// LocalGeoIPDBSource configures a GeoIP database from a local file path.
+type LocalGeoIPDBSource struct {
+ // Path is the path to the database file.
+ //
+ // +kubebuilder:validation:Pattern=`^.*\\.mmdb$`
+ Path string `json:"path"`
+}
+
+// GeoIPAnonymousMatch matches anonymous network signals emitted by the GeoIP provider.
+// If multiple fields are specified, all specified fields must match.
+// These signals are not mutually exclusive. A single IP may satisfy multiple
+// flags at the same time (for example, a commercial VPN exit IP may also be
+// classified as a public proxy, so both IsVPN and IsProxy can be true).
+//
+// +kubebuilder:validation:XValidation:rule="has(self.isAnonymous) || has(self.isVPN) || has(self.isHosting) || has(self.isTor) || has(self.isProxy)",message="at least one of isAnonymous, isVPN, isHosting, isTor, or isProxy must be specified"
+type GeoIPAnonymousMatch struct {
+ // IsAnonymous matches whether the client IP is considered anonymous.
+ //
+ // +optional
+ IsAnonymous *bool `json:"isAnonymous,omitempty"`
+
+ // IsVPN matches whether the client IP is detected as VPN.
+ //
+ // +optional
+ IsVPN *bool `json:"isVPN,omitempty"`
+
+ // IsHosting matches whether the client IP belongs to a hosting provider.
+ //
+ // +optional
+ IsHosting *bool `json:"isHosting,omitempty"`
+
+ // IsTor matches whether the client IP belongs to a Tor exit node.
+ //
+ // +optional
+ IsTor *bool `json:"isTor,omitempty"`
+
+ // IsProxy matches whether the client IP belongs to a public proxy.
+ //
+ // +optional
+ IsProxy *bool `json:"isProxy,omitempty"`
+}
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index ebececcbc9..7f17094f26 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -1030,6 +1030,51 @@ func (in *ClientIPDetectionSettings) DeepCopy() *ClientIPDetectionSettings {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ClientIPGeoLocation) DeepCopyInto(out *ClientIPGeoLocation) {
+ *out = *in
+ if in.Country != nil {
+ in, out := &in.Country, &out.Country
+ *out = new(string)
+ **out = **in
+ }
+ if in.Region != nil {
+ in, out := &in.Region, &out.Region
+ *out = new(string)
+ **out = **in
+ }
+ if in.City != nil {
+ in, out := &in.City, &out.City
+ *out = new(string)
+ **out = **in
+ }
+ if in.ASN != nil {
+ in, out := &in.ASN, &out.ASN
+ *out = new(uint32)
+ **out = **in
+ }
+ if in.ISP != nil {
+ in, out := &in.ISP, &out.ISP
+ *out = new(string)
+ **out = **in
+ }
+ if in.Anonymous != nil {
+ in, out := &in.Anonymous, &out.Anonymous
+ *out = new(GeoIPAnonymousMatch)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientIPGeoLocation.
+func (in *ClientIPGeoLocation) DeepCopy() *ClientIPGeoLocation {
+ if in == nil {
+ return nil
+ }
+ out := new(ClientIPGeoLocation)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClientTLSSettings) DeepCopyInto(out *ClientTLSSettings) {
*out = *in
@@ -2675,6 +2720,22 @@ func (in *EnvoyProxyAncestorStatus) DeepCopy() *EnvoyProxyAncestorStatus {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EnvoyProxyGeoIP) DeepCopyInto(out *EnvoyProxyGeoIP) {
+ *out = *in
+ in.Provider.DeepCopyInto(&out.Provider)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyProxyGeoIP.
+func (in *EnvoyProxyGeoIP) DeepCopy() *EnvoyProxyGeoIP {
+ if in == nil {
+ return nil
+ }
+ out := new(EnvoyProxyGeoIP)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EnvoyProxyHostProvider) DeepCopyInto(out *EnvoyProxyHostProvider) {
*out = *in
@@ -2880,6 +2941,11 @@ func (in *EnvoyProxySpec) DeepCopyInto(out *EnvoyProxySpec) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
+ if in.GeoIP != nil {
+ in, out := &in.GeoIP, &out.GeoIP
+ *out = new(EnvoyProxyGeoIP)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyProxySpec.
@@ -3484,6 +3550,122 @@ func (in *GatewayAPISettings) DeepCopy() *GatewayAPISettings {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GeoIPAnonymousMatch) DeepCopyInto(out *GeoIPAnonymousMatch) {
+ *out = *in
+ if in.IsAnonymous != nil {
+ in, out := &in.IsAnonymous, &out.IsAnonymous
+ *out = new(bool)
+ **out = **in
+ }
+ if in.IsVPN != nil {
+ in, out := &in.IsVPN, &out.IsVPN
+ *out = new(bool)
+ **out = **in
+ }
+ if in.IsHosting != nil {
+ in, out := &in.IsHosting, &out.IsHosting
+ *out = new(bool)
+ **out = **in
+ }
+ if in.IsTor != nil {
+ in, out := &in.IsTor, &out.IsTor
+ *out = new(bool)
+ **out = **in
+ }
+ if in.IsProxy != nil {
+ in, out := &in.IsProxy, &out.IsProxy
+ *out = new(bool)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeoIPAnonymousMatch.
+func (in *GeoIPAnonymousMatch) DeepCopy() *GeoIPAnonymousMatch {
+ if in == nil {
+ return nil
+ }
+ out := new(GeoIPAnonymousMatch)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GeoIPDBSource) DeepCopyInto(out *GeoIPDBSource) {
+ *out = *in
+ out.Local = in.Local
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeoIPDBSource.
+func (in *GeoIPDBSource) DeepCopy() *GeoIPDBSource {
+ if in == nil {
+ return nil
+ }
+ out := new(GeoIPDBSource)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GeoIPMaxMind) DeepCopyInto(out *GeoIPMaxMind) {
+ *out = *in
+ if in.CityDBSource != nil {
+ in, out := &in.CityDBSource, &out.CityDBSource
+ *out = new(GeoIPDBSource)
+ **out = **in
+ }
+ if in.CountryDBSource != nil {
+ in, out := &in.CountryDBSource, &out.CountryDBSource
+ *out = new(GeoIPDBSource)
+ **out = **in
+ }
+ if in.ASNDBSource != nil {
+ in, out := &in.ASNDBSource, &out.ASNDBSource
+ *out = new(GeoIPDBSource)
+ **out = **in
+ }
+ if in.ISPDBSource != nil {
+ in, out := &in.ISPDBSource, &out.ISPDBSource
+ *out = new(GeoIPDBSource)
+ **out = **in
+ }
+ if in.AnonymousIPDBSource != nil {
+ in, out := &in.AnonymousIPDBSource, &out.AnonymousIPDBSource
+ *out = new(GeoIPDBSource)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeoIPMaxMind.
+func (in *GeoIPMaxMind) DeepCopy() *GeoIPMaxMind {
+ if in == nil {
+ return nil
+ }
+ out := new(GeoIPMaxMind)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GeoIPProvider) DeepCopyInto(out *GeoIPProvider) {
+ *out = *in
+ if in.MaxMind != nil {
+ in, out := &in.MaxMind, &out.MaxMind
+ *out = new(GeoIPMaxMind)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeoIPProvider.
+func (in *GeoIPProvider) DeepCopy() *GeoIPProvider {
+ if in == nil {
+ return nil
+ }
+ out := new(GeoIPProvider)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GlobalRateLimit) DeepCopyInto(out *GlobalRateLimit) {
*out = *in
@@ -5154,6 +5336,21 @@ func (in *LocalDynamicModuleSource) DeepCopy() *LocalDynamicModuleSource {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *LocalGeoIPDBSource) DeepCopyInto(out *LocalGeoIPDBSource) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalGeoIPDBSource.
+func (in *LocalGeoIPDBSource) DeepCopy() *LocalGeoIPDBSource {
+ if in == nil {
+ return nil
+ }
+ out := new(LocalGeoIPDBSource)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *LocalJWKS) DeepCopyInto(out *LocalJWKS) {
*out = *in
@@ -5855,6 +6052,13 @@ func (in *Principal) DeepCopyInto(out *Principal) {
*out = make([]CIDR, len(*in))
copy(*out, *in)
}
+ if in.ClientIPGeoLocations != nil {
+ in, out := &in.ClientIPGeoLocations, &out.ClientIPGeoLocations
+ *out = make([]ClientIPGeoLocation, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Principal.
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml
index feb15e887e..168e1c18f1 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml
@@ -545,6 +545,130 @@ spec:
rule: (has(self.before) && !has(self.after)) || (!has(self.before)
&& has(self.after))
type: array
+ geoIP:
+ description: GeoIP defines shared GeoIP provider configuration for
+ this EnvoyProxy fleet.
+ properties:
+ provider:
+ description: Provider defines the GeoIP provider configuration
+ used by GeoIP filter instances.
+ properties:
+ maxMind:
+ description: MaxMind configures the MaxMind provider.
+ properties:
+ anonymousIpDbSource:
+ description: AnonymousIPDBSource configures the Anonymous
+ IP database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ asnDbSource:
+ description: ASNDBSource configures the ASN database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ cityDbSource:
+ description: CityDBSource configures the City database
+ source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ countryDbSource:
+ description: CountryDBSource configures the Country database
+ source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ ispDbSource:
+ description: ISPDBSource configures the ISP database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ type: object
+ x-kubernetes-validations:
+ - message: at least one MaxMind database source must be specified
+ rule: has(self.cityDbSource) || has(self.countryDbSource)
+ || has(self.asnDbSource) || has(self.ispDbSource) || has(self.anonymousIpDbSource)
+ type:
+ description: GeoIPProviderType enumerates GeoIP providers
+ supported by Envoy Gateway.
+ enum:
+ - MaxMind
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: maxMind must be set when type is MaxMind
+ rule: 'self.type == ''MaxMind'' ? has(self.maxMind) : true'
+ required:
+ - provider
+ type: object
ipFamily:
description: |-
IPFamily specifies the IP family for the EnvoyProxy fleet.
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml
index c7bac74c16..fe19156032 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -272,6 +272,85 @@ spec:
type: string
minItems: 1
type: array
+ clientIPGeoLocations:
+ description: |-
+ ClientIPGeoLocations authorizes the request based on geolocation metadata derived from the client IP.
+ If multiple entries are specified, one of the ClientIPGeoLocation entries must match for the rule to match.
+ items:
+ description: ClientIPGeoLocation specifies geolocation-based
+ match criteria for authorization.
+ properties:
+ anonymous:
+ description: Anonymous matches anonymous network
+ detection signals.
+ properties:
+ isAnonymous:
+ description: IsAnonymous matches whether the
+ client IP is considered anonymous.
+ type: boolean
+ isHosting:
+ description: IsHosting matches whether the
+ client IP belongs to a hosting provider.
+ type: boolean
+ isProxy:
+ description: IsProxy matches whether the client
+ IP belongs to a public proxy.
+ type: boolean
+ isTor:
+ description: IsTor matches whether the client
+ IP belongs to a Tor exit node.
+ type: boolean
+ isVPN:
+ description: IsVPN matches whether the client
+ IP is detected as VPN.
+ type: boolean
+ type: object
+ x-kubernetes-validations:
+ - message: at least one of isAnonymous, isVPN,
+ isHosting, isTor, or isProxy must be specified
+ rule: has(self.isAnonymous) || has(self.isVPN)
+ || has(self.isHosting) || has(self.isTor)
+ || has(self.isProxy)
+ asn:
+ description: ASN is the autonomous system number
+ associated with the client IP.
+ format: int32
+ minimum: 1
+ type: integer
+ city:
+ description: City is the city associated with
+ the client IP.
+ maxLength: 128
+ minLength: 1
+ type: string
+ country:
+ description: Country is the country ISO code associated
+ with the client IP.
+ maxLength: 2
+ minLength: 2
+ pattern: ^[A-Za-z]{2}$
+ type: string
+ isp:
+ description: ISP is the internet service provider
+ associated with the client IP.
+ maxLength: 256
+ minLength: 1
+ type: string
+ region:
+ description: Region is the region ISO code associated
+ with the client IP.
+ maxLength: 16
+ minLength: 1
+ pattern: ^[A-Za-z0-9-]+$
+ type: string
+ type: object
+ x-kubernetes-validations:
+ - message: at least one of country, region, city,
+ asn, isp, or anonymous must be specified
+ rule: has(self.country) || has(self.region) || has(self.city)
+ || has(self.asn) || has(self.isp) || has(self.anonymous)
+ minItems: 1
+ type: array
headers:
description: |-
Headers authorize the request based on user identity extracted from custom headers.
@@ -414,9 +493,10 @@ spec:
type: array
type: object
x-kubernetes-validations:
- - message: at least one of clientCIDRs, jwt, or headers
- must be specified
- rule: (has(self.clientCIDRs) || has(self.jwt) || has(self.headers))
+ - message: at least one of clientCIDRs, jwt, headers, or
+ clientIPGeoLocations must be specified
+ rule: (has(self.clientCIDRs) || has(self.jwt) || has(self.headers)
+ || has(self.clientIPGeoLocations))
required:
- action
- principal
diff --git a/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
index c3a43484c4..994302717f 100644
--- a/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
+++ b/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
@@ -544,6 +544,130 @@ spec:
rule: (has(self.before) && !has(self.after)) || (!has(self.before)
&& has(self.after))
type: array
+ geoIP:
+ description: GeoIP defines shared GeoIP provider configuration for
+ this EnvoyProxy fleet.
+ properties:
+ provider:
+ description: Provider defines the GeoIP provider configuration
+ used by GeoIP filter instances.
+ properties:
+ maxMind:
+ description: MaxMind configures the MaxMind provider.
+ properties:
+ anonymousIpDbSource:
+ description: AnonymousIPDBSource configures the Anonymous
+ IP database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ asnDbSource:
+ description: ASNDBSource configures the ASN database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ cityDbSource:
+ description: CityDBSource configures the City database
+ source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ countryDbSource:
+ description: CountryDBSource configures the Country database
+ source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ ispDbSource:
+ description: ISPDBSource configures the ISP database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ type: object
+ x-kubernetes-validations:
+ - message: at least one MaxMind database source must be specified
+ rule: has(self.cityDbSource) || has(self.countryDbSource)
+ || has(self.asnDbSource) || has(self.ispDbSource) || has(self.anonymousIpDbSource)
+ type:
+ description: GeoIPProviderType enumerates GeoIP providers
+ supported by Envoy Gateway.
+ enum:
+ - MaxMind
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: maxMind must be set when type is MaxMind
+ rule: 'self.type == ''MaxMind'' ? has(self.maxMind) : true'
+ required:
+ - provider
+ type: object
ipFamily:
description: |-
IPFamily specifies the IP family for the EnvoyProxy fleet.
diff --git a/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
index 6a08796189..b10bcf458d 100644
--- a/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -271,6 +271,85 @@ spec:
type: string
minItems: 1
type: array
+ clientIPGeoLocations:
+ description: |-
+ ClientIPGeoLocations authorizes the request based on geolocation metadata derived from the client IP.
+ If multiple entries are specified, one of the ClientIPGeoLocation entries must match for the rule to match.
+ items:
+ description: ClientIPGeoLocation specifies geolocation-based
+ match criteria for authorization.
+ properties:
+ anonymous:
+ description: Anonymous matches anonymous network
+ detection signals.
+ properties:
+ isAnonymous:
+ description: IsAnonymous matches whether the
+ client IP is considered anonymous.
+ type: boolean
+ isHosting:
+ description: IsHosting matches whether the
+ client IP belongs to a hosting provider.
+ type: boolean
+ isProxy:
+ description: IsProxy matches whether the client
+ IP belongs to a public proxy.
+ type: boolean
+ isTor:
+ description: IsTor matches whether the client
+ IP belongs to a Tor exit node.
+ type: boolean
+ isVPN:
+ description: IsVPN matches whether the client
+ IP is detected as VPN.
+ type: boolean
+ type: object
+ x-kubernetes-validations:
+ - message: at least one of isAnonymous, isVPN,
+ isHosting, isTor, or isProxy must be specified
+ rule: has(self.isAnonymous) || has(self.isVPN)
+ || has(self.isHosting) || has(self.isTor)
+ || has(self.isProxy)
+ asn:
+ description: ASN is the autonomous system number
+ associated with the client IP.
+ format: int32
+ minimum: 1
+ type: integer
+ city:
+ description: City is the city associated with
+ the client IP.
+ maxLength: 128
+ minLength: 1
+ type: string
+ country:
+ description: Country is the country ISO code associated
+ with the client IP.
+ maxLength: 2
+ minLength: 2
+ pattern: ^[A-Za-z]{2}$
+ type: string
+ isp:
+ description: ISP is the internet service provider
+ associated with the client IP.
+ maxLength: 256
+ minLength: 1
+ type: string
+ region:
+ description: Region is the region ISO code associated
+ with the client IP.
+ maxLength: 16
+ minLength: 1
+ pattern: ^[A-Za-z0-9-]+$
+ type: string
+ type: object
+ x-kubernetes-validations:
+ - message: at least one of country, region, city,
+ asn, isp, or anonymous must be specified
+ rule: has(self.country) || has(self.region) || has(self.city)
+ || has(self.asn) || has(self.isp) || has(self.anonymous)
+ minItems: 1
+ type: array
headers:
description: |-
Headers authorize the request based on user identity extracted from custom headers.
@@ -413,9 +492,10 @@ spec:
type: array
type: object
x-kubernetes-validations:
- - message: at least one of clientCIDRs, jwt, or headers
- must be specified
- rule: (has(self.clientCIDRs) || has(self.jwt) || has(self.headers))
+ - message: at least one of clientCIDRs, jwt, headers, or
+ clientIPGeoLocations must be specified
+ rule: (has(self.clientCIDRs) || has(self.jwt) || has(self.headers)
+ || has(self.clientIPGeoLocations))
required:
- action
- principal
diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go
index e91bda51d6..43584586b2 100644
--- a/internal/gatewayapi/securitypolicy.go
+++ b/internal/gatewayapi/securitypolicy.go
@@ -450,7 +450,8 @@ func validateSecurityPolicyForTCP(p *egv1a1.SecurityPolicy) error {
if p.Spec.Authorization == nil || len(p.Spec.Authorization.Rules) == 0 {
return nil
}
- for i, rule := range p.Spec.Authorization.Rules {
+ for i := range p.Spec.Authorization.Rules {
+ rule := &p.Spec.Authorization.Rules[i]
if rule.Principal.JWT != nil {
return fmt.Errorf("rule %d: JWT not supported for TCP", i)
}
@@ -2086,7 +2087,8 @@ func (t *Translator) buildAuthorization(policy *egv1a1.SecurityPolicy) (*ir.Auth
}
irAuth.DefaultAction = defaultAction
- for i, rule := range authorization.Rules {
+ for i := range authorization.Rules {
+ rule := &authorization.Rules[i]
irPrincipal := ir.Principal{}
for _, cidr := range rule.Principal.ClientCIDRs {
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index c366d3b0c5..10d45cb266 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -724,6 +724,25 @@ _Appears in:_
| `customHeader` | _[CustomHeaderExtensionSettings](#customheaderextensionsettings)_ | false | | CustomHeader provides configuration for determining the client IP address for a request based on
a trusted custom HTTP header. This uses the custom_header original IP detection extension.
Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto
for more details. |
+#### ClientIPGeoLocation
+
+
+
+ClientIPGeoLocation specifies geolocation-based match criteria for authorization.
+
+_Appears in:_
+- [Principal](#principal)
+
+| Field | Type | Required | Default | Description |
+| --- | --- | --- | --- | --- |
+| `country` | _string_ | false | | Country is the country ISO code associated with the client IP. |
+| `region` | _string_ | false | | Region is the region ISO code associated with the client IP. |
+| `city` | _string_ | false | | City is the city associated with the client IP. |
+| `asn` | _integer_ | false | | ASN is the autonomous system number associated with the client IP. |
+| `isp` | _string_ | false | | ISP is the internet service provider associated with the client IP. |
+| `anonymous` | _[GeoIPAnonymousMatch](#geoipanonymousmatch)_ | false | | Anonymous matches anonymous network detection signals. |
+
+
#### ClientTLSSettings
@@ -1855,6 +1874,20 @@ _Appears in:_
+#### EnvoyProxyGeoIP
+
+
+
+EnvoyProxyGeoIP defines shared GeoIP provider settings for EnvoyProxy.
+
+_Appears in:_
+- [EnvoyProxySpec](#envoyproxyspec)
+
+| Field | Type | Required | Default | Description |
+| --- | --- | --- | --- | --- |
+| `provider` | _[GeoIPProvider](#geoipprovider)_ | true | | Provider defines the GeoIP provider configuration used by GeoIP filter instances. |
+
+
#### EnvoyProxyHostProvider
@@ -2381,6 +2414,90 @@ _Appears in:_
| `enabled` | _[GatewayAPI](#gatewayapi) array_ | true | | |
+#### GeoIPAnonymousMatch
+
+
+
+GeoIPAnonymousMatch matches anonymous network signals emitted by the GeoIP provider.
+If multiple fields are specified, all specified fields must match.
+These signals are not mutually exclusive. A single IP may satisfy multiple
+flags at the same time (for example, a commercial VPN exit IP may also be
+classified as a public proxy, so both IsVPN and IsProxy can be true).
+
+_Appears in:_
+- [ClientIPGeoLocation](#clientipgeolocation)
+
+| Field | Type | Required | Default | Description |
+| --- | --- | --- | --- | --- |
+| `isAnonymous` | _boolean_ | false | | IsAnonymous matches whether the client IP is considered anonymous. |
+| `isVPN` | _boolean_ | false | | IsVPN matches whether the client IP is detected as VPN. |
+| `isHosting` | _boolean_ | false | | IsHosting matches whether the client IP belongs to a hosting provider. |
+| `isTor` | _boolean_ | false | | IsTor matches whether the client IP belongs to a Tor exit node. |
+| `isProxy` | _boolean_ | false | | IsProxy matches whether the client IP belongs to a public proxy. |
+
+
+#### GeoIPDBSource
+
+
+
+GeoIPDBSource defines where a GeoIP .mmdb database can be loaded from.
+
+_Appears in:_
+- [GeoIPMaxMind](#geoipmaxmind)
+
+| Field | Type | Required | Default | Description |
+| --- | --- | --- | --- | --- |
+| `local` | _[LocalGeoIPDBSource](#localgeoipdbsource)_ | true | | Local is a database source from a local file. |
+
+
+#### GeoIPMaxMind
+
+
+
+GeoIPMaxMind configures the MaxMind provider.
+These database files are expected to be mounted into the Envoy container, and a sidecar container can be used to update the database files.
+
+_Appears in:_
+- [GeoIPProvider](#geoipprovider)
+
+| Field | Type | Required | Default | Description |
+| --- | --- | --- | --- | --- |
+| `cityDbSource` | _[GeoIPDBSource](#geoipdbsource)_ | false | | CityDBSource configures the City database source. |
+| `countryDbSource` | _[GeoIPDBSource](#geoipdbsource)_ | false | | CountryDBSource configures the Country database source. |
+| `asnDbSource` | _[GeoIPDBSource](#geoipdbsource)_ | false | | ASNDBSource configures the ASN database source. |
+| `ispDbSource` | _[GeoIPDBSource](#geoipdbsource)_ | false | | ISPDBSource configures the ISP database source. |
+| `anonymousIpDbSource` | _[GeoIPDBSource](#geoipdbsource)_ | false | | AnonymousIPDBSource configures the Anonymous IP database source. |
+
+
+#### GeoIPProvider
+
+
+
+GeoIPProvider defines provider-specific settings.
+
+_Appears in:_
+- [EnvoyProxyGeoIP](#envoyproxygeoip)
+
+| Field | Type | Required | Default | Description |
+| --- | --- | --- | --- | --- |
+| `type` | _[GeoIPProviderType](#geoipprovidertype)_ | true | | |
+| `maxMind` | _[GeoIPMaxMind](#geoipmaxmind)_ | false | | MaxMind configures the MaxMind provider. |
+
+
+#### GeoIPProviderType
+
+_Underlying type:_ _string_
+
+GeoIPProviderType enumerates GeoIP providers supported by Envoy Gateway.
+
+_Appears in:_
+- [GeoIPProvider](#geoipprovider)
+
+| Value | Description |
+| ----- | ----------- |
+| `MaxMind` | GeoIPProviderTypeMaxMind configures Envoy with the MaxMind provider pointing to local files.
|
+
+
#### GlobalRateLimit
@@ -3529,6 +3646,20 @@ _Appears in:_
| `path` | _string_ | true | | Path is the absolute filesystem path to the dynamic module shared library (.so file). |
+#### LocalGeoIPDBSource
+
+
+
+LocalGeoIPDBSource configures a GeoIP database from a local file path.
+
+_Appears in:_
+- [GeoIPDBSource](#geoipdbsource)
+
+| Field | Type | Required | Default | Description |
+| --- | --- | --- | --- | --- |
+| `path` | _string_ | true | | Path is the path to the database file. |
+
+
#### LocalJWKS
diff --git a/test/cel-validation/securitypolicy_test.go b/test/cel-validation/securitypolicy_test.go
index d05ecc4b9e..52c86cfbc4 100644
--- a/test/cel-validation/securitypolicy_test.go
+++ b/test/cel-validation/securitypolicy_test.go
@@ -1301,7 +1301,7 @@ func TestSecurityPolicyTarget(t *testing.T) {
},
}
},
- wantErrors: []string{"at least one of clientCIDRs, jwt, or headers must be specified"},
+ wantErrors: []string{"at least one of clientCIDRs, jwt, headers, or clientIPGeoLocations must be specified"},
},
{
desc: "authorization-jwt-claims-without-jwt-authn",
diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml
index 649c584d89..1574085396 100644
--- a/test/helm/gateway-crds-helm/all.out.yaml
+++ b/test/helm/gateway-crds-helm/all.out.yaml
@@ -30892,6 +30892,130 @@ spec:
rule: (has(self.before) && !has(self.after)) || (!has(self.before)
&& has(self.after))
type: array
+ geoIP:
+ description: GeoIP defines shared GeoIP provider configuration for
+ this EnvoyProxy fleet.
+ properties:
+ provider:
+ description: Provider defines the GeoIP provider configuration
+ used by GeoIP filter instances.
+ properties:
+ maxMind:
+ description: MaxMind configures the MaxMind provider.
+ properties:
+ anonymousIpDbSource:
+ description: AnonymousIPDBSource configures the Anonymous
+ IP database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ asnDbSource:
+ description: ASNDBSource configures the ASN database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ cityDbSource:
+ description: CityDBSource configures the City database
+ source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ countryDbSource:
+ description: CountryDBSource configures the Country database
+ source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ ispDbSource:
+ description: ISPDBSource configures the ISP database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ type: object
+ x-kubernetes-validations:
+ - message: at least one MaxMind database source must be specified
+ rule: has(self.cityDbSource) || has(self.countryDbSource)
+ || has(self.asnDbSource) || has(self.ispDbSource) || has(self.anonymousIpDbSource)
+ type:
+ description: GeoIPProviderType enumerates GeoIP providers
+ supported by Envoy Gateway.
+ enum:
+ - MaxMind
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: maxMind must be set when type is MaxMind
+ rule: 'self.type == ''MaxMind'' ? has(self.maxMind) : true'
+ required:
+ - provider
+ type: object
ipFamily:
description: |-
IPFamily specifies the IP family for the EnvoyProxy fleet.
@@ -48164,6 +48288,85 @@ spec:
type: string
minItems: 1
type: array
+ clientIPGeoLocations:
+ description: |-
+ ClientIPGeoLocations authorizes the request based on geolocation metadata derived from the client IP.
+ If multiple entries are specified, one of the ClientIPGeoLocation entries must match for the rule to match.
+ items:
+ description: ClientIPGeoLocation specifies geolocation-based
+ match criteria for authorization.
+ properties:
+ anonymous:
+ description: Anonymous matches anonymous network
+ detection signals.
+ properties:
+ isAnonymous:
+ description: IsAnonymous matches whether the
+ client IP is considered anonymous.
+ type: boolean
+ isHosting:
+ description: IsHosting matches whether the
+ client IP belongs to a hosting provider.
+ type: boolean
+ isProxy:
+ description: IsProxy matches whether the client
+ IP belongs to a public proxy.
+ type: boolean
+ isTor:
+ description: IsTor matches whether the client
+ IP belongs to a Tor exit node.
+ type: boolean
+ isVPN:
+ description: IsVPN matches whether the client
+ IP is detected as VPN.
+ type: boolean
+ type: object
+ x-kubernetes-validations:
+ - message: at least one of isAnonymous, isVPN,
+ isHosting, isTor, or isProxy must be specified
+ rule: has(self.isAnonymous) || has(self.isVPN)
+ || has(self.isHosting) || has(self.isTor)
+ || has(self.isProxy)
+ asn:
+ description: ASN is the autonomous system number
+ associated with the client IP.
+ format: int32
+ minimum: 1
+ type: integer
+ city:
+ description: City is the city associated with
+ the client IP.
+ maxLength: 128
+ minLength: 1
+ type: string
+ country:
+ description: Country is the country ISO code associated
+ with the client IP.
+ maxLength: 2
+ minLength: 2
+ pattern: ^[A-Za-z]{2}$
+ type: string
+ isp:
+ description: ISP is the internet service provider
+ associated with the client IP.
+ maxLength: 256
+ minLength: 1
+ type: string
+ region:
+ description: Region is the region ISO code associated
+ with the client IP.
+ maxLength: 16
+ minLength: 1
+ pattern: ^[A-Za-z0-9-]+$
+ type: string
+ type: object
+ x-kubernetes-validations:
+ - message: at least one of country, region, city,
+ asn, isp, or anonymous must be specified
+ rule: has(self.country) || has(self.region) || has(self.city)
+ || has(self.asn) || has(self.isp) || has(self.anonymous)
+ minItems: 1
+ type: array
headers:
description: |-
Headers authorize the request based on user identity extracted from custom headers.
@@ -48306,9 +48509,10 @@ spec:
type: array
type: object
x-kubernetes-validations:
- - message: at least one of clientCIDRs, jwt, or headers
- must be specified
- rule: (has(self.clientCIDRs) || has(self.jwt) || has(self.headers))
+ - message: at least one of clientCIDRs, jwt, headers, or
+ clientIPGeoLocations must be specified
+ rule: (has(self.clientCIDRs) || has(self.jwt) || has(self.headers)
+ || has(self.clientIPGeoLocations))
required:
- action
- principal
diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
index f795861ef0..2e07265107 100644
--- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
+++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
@@ -8873,6 +8873,130 @@ spec:
rule: (has(self.before) && !has(self.after)) || (!has(self.before)
&& has(self.after))
type: array
+ geoIP:
+ description: GeoIP defines shared GeoIP provider configuration for
+ this EnvoyProxy fleet.
+ properties:
+ provider:
+ description: Provider defines the GeoIP provider configuration
+ used by GeoIP filter instances.
+ properties:
+ maxMind:
+ description: MaxMind configures the MaxMind provider.
+ properties:
+ anonymousIpDbSource:
+ description: AnonymousIPDBSource configures the Anonymous
+ IP database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ asnDbSource:
+ description: ASNDBSource configures the ASN database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ cityDbSource:
+ description: CityDBSource configures the City database
+ source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ countryDbSource:
+ description: CountryDBSource configures the Country database
+ source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ ispDbSource:
+ description: ISPDBSource configures the ISP database source.
+ properties:
+ local:
+ description: Local is a database source from a local
+ file.
+ properties:
+ path:
+ description: Path is the path to the database
+ file.
+ pattern: ^.*\\.mmdb$
+ type: string
+ required:
+ - path
+ type: object
+ required:
+ - local
+ type: object
+ type: object
+ x-kubernetes-validations:
+ - message: at least one MaxMind database source must be specified
+ rule: has(self.cityDbSource) || has(self.countryDbSource)
+ || has(self.asnDbSource) || has(self.ispDbSource) || has(self.anonymousIpDbSource)
+ type:
+ description: GeoIPProviderType enumerates GeoIP providers
+ supported by Envoy Gateway.
+ enum:
+ - MaxMind
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: maxMind must be set when type is MaxMind
+ rule: 'self.type == ''MaxMind'' ? has(self.maxMind) : true'
+ required:
+ - provider
+ type: object
ipFamily:
description: |-
IPFamily specifies the IP family for the EnvoyProxy fleet.
@@ -26145,6 +26269,85 @@ spec:
type: string
minItems: 1
type: array
+ clientIPGeoLocations:
+ description: |-
+ ClientIPGeoLocations authorizes the request based on geolocation metadata derived from the client IP.
+ If multiple entries are specified, one of the ClientIPGeoLocation entries must match for the rule to match.
+ items:
+ description: ClientIPGeoLocation specifies geolocation-based
+ match criteria for authorization.
+ properties:
+ anonymous:
+ description: Anonymous matches anonymous network
+ detection signals.
+ properties:
+ isAnonymous:
+ description: IsAnonymous matches whether the
+ client IP is considered anonymous.
+ type: boolean
+ isHosting:
+ description: IsHosting matches whether the
+ client IP belongs to a hosting provider.
+ type: boolean
+ isProxy:
+ description: IsProxy matches whether the client
+ IP belongs to a public proxy.
+ type: boolean
+ isTor:
+ description: IsTor matches whether the client
+ IP belongs to a Tor exit node.
+ type: boolean
+ isVPN:
+ description: IsVPN matches whether the client
+ IP is detected as VPN.
+ type: boolean
+ type: object
+ x-kubernetes-validations:
+ - message: at least one of isAnonymous, isVPN,
+ isHosting, isTor, or isProxy must be specified
+ rule: has(self.isAnonymous) || has(self.isVPN)
+ || has(self.isHosting) || has(self.isTor)
+ || has(self.isProxy)
+ asn:
+ description: ASN is the autonomous system number
+ associated with the client IP.
+ format: int32
+ minimum: 1
+ type: integer
+ city:
+ description: City is the city associated with
+ the client IP.
+ maxLength: 128
+ minLength: 1
+ type: string
+ country:
+ description: Country is the country ISO code associated
+ with the client IP.
+ maxLength: 2
+ minLength: 2
+ pattern: ^[A-Za-z]{2}$
+ type: string
+ isp:
+ description: ISP is the internet service provider
+ associated with the client IP.
+ maxLength: 256
+ minLength: 1
+ type: string
+ region:
+ description: Region is the region ISO code associated
+ with the client IP.
+ maxLength: 16
+ minLength: 1
+ pattern: ^[A-Za-z0-9-]+$
+ type: string
+ type: object
+ x-kubernetes-validations:
+ - message: at least one of country, region, city,
+ asn, isp, or anonymous must be specified
+ rule: has(self.country) || has(self.region) || has(self.city)
+ || has(self.asn) || has(self.isp) || has(self.anonymous)
+ minItems: 1
+ type: array
headers:
description: |-
Headers authorize the request based on user identity extracted from custom headers.
@@ -26287,9 +26490,10 @@ spec:
type: array
type: object
x-kubernetes-validations:
- - message: at least one of clientCIDRs, jwt, or headers
- must be specified
- rule: (has(self.clientCIDRs) || has(self.jwt) || has(self.headers))
+ - message: at least one of clientCIDRs, jwt, headers, or
+ clientIPGeoLocations must be specified
+ rule: (has(self.clientCIDRs) || has(self.jwt) || has(self.headers)
+ || has(self.clientIPGeoLocations))
required:
- action
- principal