Skip to content

IP/Geo rules not prioritized when OAuth2 also runs on the same route (filterOrder) #8913

Description

@hidalz

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions