Description:
I have two SecurityPolicies on the same route: one Gateway-level deny by clientIPGeoLocations[].country, one route-level oidc (merged via mergeType: StrategicMerge).
Default filter order is ... -> oauth2 → ... -> geoip → rbac. So an unauthenticated request from a denied country gets a 302 to the IdP instead of a 403, because oauth2 gets ahead before rbac evaluates the deny rule.
Backend traffic is still blocked (rbac runs on the request after the OAuth2 redirect callback), but the deny is post-auth. That means that a client in a sanctioned country can reach the OAuth2 redirect endpoint, complete the token exchange, cause the IdP to issue a session and log successfully (and learn the route exists), before the 403.
IMHO that is not what's wanted from a country block.
Both policies report Accepted=True, Merged=True.
Repro steps:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata: { name: geo-deny, namespace: envoy-gateway }
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gw
authorization:
defaultAction: Allow
rules:
- action: Deny
principal:
clientIPGeoLocations:
- country: IR
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata: { name: oidc, namespace: app }
spec:
targetRefs: [{ group: gateway.networking.k8s.io, kind: HTTPRoute, name: protected }]
mergeType: StrategicMerge
oidc: { provider: { issuer: https://idp.example.com }, ... }
curl -H 'X-Forwarded-For: <BLOCKED-COUNTRY-IP>' https://gw/<OAUTH_ROUTE>/
Want: 403. Got: 302 to the IdP.
Environment:
EG v1.8.0-rc.1, Envoy 1.38.0, Gateway API v1.5.1, K8s 1.32.
Let me know if you need a more concrete reproduction or if, on the contrary, the idea is clear. Lastly, I understand this could be by design. In such case, are there any records or written documentation as to why that is a desired behaviour, and if it is worth a discussion?
Description:
I have two SecurityPolicies on the same route: one Gateway-level deny by
clientIPGeoLocations[].country, one route-leveloidc(merged viamergeType: StrategicMerge).Default filter order is
... -> oauth2 → ... -> geoip → rbac. So an unauthenticated request from a denied country gets a 302 to the IdP instead of a 403, because oauth2 gets ahead before rbac evaluates the deny rule.Backend traffic is still blocked (rbac runs on the request after the OAuth2 redirect callback), but the deny is post-auth. That means that a client in a sanctioned country can reach the OAuth2 redirect endpoint, complete the token exchange, cause the IdP to issue a session and log successfully (and learn the route exists), before the 403.
IMHO that is not what's wanted from a country block.
Both policies report
Accepted=True,Merged=True.Repro steps:
curl -H 'X-Forwarded-For: <BLOCKED-COUNTRY-IP>' https://gw/<OAUTH_ROUTE>/Want: 403. Got: 302 to the IdP.
Environment:
EG
v1.8.0-rc.1, Envoy1.38.0, Gateway APIv1.5.1, K8s 1.32.Let me know if you need a more concrete reproduction or if, on the contrary, the idea is clear. Lastly, I understand this could be by design. In such case, are there any records or written documentation as to why that is a desired behaviour, and if it is worth a discussion?