Skip to content

BackendTrafficPolicy's redirect functionality not working in OAuth2 flow #7796

@pylaligand

Description

@pylaligand

Description:

I am using a SecurityPolicy to trigger an OIDC flow when users visit my app in their browser, following this example in the docs. On the OIDC provider side, users may get denied under certain conditions, resulting in a 401 error with the OAuth flow failed. message.

I am trying to identify this case and redirect users to a proper error page using a BackendTrafficPolicy attached to the route that has the SecurityPolicy and configured with a response override, as suggested in this discussion thread.
For some reason, custom redirections do not work as users see the exact same message as when the traffic policy is absent, but custom responses. Another user reported in a Slack thread that they observed a very similar phenomenon.

Repro steps:

I cannot provide the full environment as this requires an OIDC provider, but I'll provide as much as I can. Starting from a standard Envoy Gateway deployment, instantiate a Gateway and attach a route and security policy:

Route:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: my-route
spec:
  parentRefs:
    - name: my-gateway
  rules:
    - backendRefs:
        - kind: Service
          name: my-service
          port: 80
      matches:
        - path:
            type: Exact
            value: /
    # Handle OAuth2 paths.
    - backendRefs:
        - kind: Service
          name: orchestrator
          port: 80
      matches:
        - path:
            type: PathPrefix
            value: /oauth2
        - path:
            type: Exact
            value: /logout

Policy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: my-policy
spec:
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      name: my-route
  oidc:
    provider:
      issuer: xxx-issuer
    clientID: xxx-client-id
    clientSecret:
      name: xxx-secret
    redirectURL: xxx-redirect-url
    logoutPath: /logout

Now comes the traffic policy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: denied-redirect
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: my-route
  responseOverride:
    - match:
        statusCodes:
          - type: Value
            value: 401
      redirect:
        path:
          type: ReplaceFullPath
          replaceFullPath: /any-non-functional-path
        statusCode: 302

When attempting to navigate to / and after completing the auth steps, the browser gets redirected to https://my.domain/oauth2/callback?error=access_denied&<some more parameters> and gets a 401 with the message OAuth flow failed.. The exact same thing happens without the policy.

Now if I replace the redirect block with:

response:
  contentType: text/plain
  body:
    type: Inline
    inline: "You got denied dude!"
  statusCode: 200

then the browser displaces the expected message and gets a 200 error code for that same URL.

Environment:

Envoy Gateway 1.6.1

Logs:

Gateway logs with a redirect in the traffic policy:

[2025-12-22 15:25:49.015][128][warning][oauth2] [source/extensions/filters/http/oauth2/filter.cc:1281] Responding with 401 Unauthorized. Cause: OAuth server returned an error: ?error=access_denied&<some more params>
{
    ":authority": "my.domain",
    "bytes_received": 0,
    "bytes_sent": 18,
    "connection_termination_details": null,
    "downstream_local_address": "ip:port",
    "downstream_remote_address": "ip:port",
    "duration": 0,
    "method": "GET",
    "protocol": "HTTP/2",
    "requested_server_name": "my.domain",
    "response_code": 401,
    "response_code_details": "OAuth_server_returned_an_error:_?error=access_denied&<some more params>",
    "response_flags": "-",
    "route_name": "httproute/default/my-route/rule/0/match/0/my_domain",
    "start_time": "2025-12-22T15:25:49.014Z",
    "upstream_cluster": "httproute/default/my-route/rule/0",
    "upstream_host": null,
    "upstream_local_address": null,
    "upstream_transport_failure_reason": null,
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
    "x-envoy-origin-path": "/oauth2/callback?error=access_denied&<some more params>",
    "x-envoy-upstream-service-time": null,
    "x-forwarded-for": "ip",
    "x-request-id": "4109ab2c-40a3-4110-b9d5-189f6c9601e9"
}

Gateway logs with a custom response in the traffic policy:

[2025-12-22 15:33:03.908][164][warning][oauth2] [source/extensions/filters/http/oauth2/filter.cc:1281] Responding with 401 Unauthorized. Cause: OAuth server returned an error: ?error=access_denied&<some params>
{
    ":authority": "my.domain",
    "bytes_received": 0,
    "bytes_sent": 20,
    "connection_termination_details": null,
    "downstream_local_address": "ip:port",
    "downstream_remote_address": "ip:port",
    "duration": 0,
    "method": "GET",
    "protocol": "HTTP/2",
    "requested_server_name": "my.domain",
    "response_code": 200,
    "response_code_details": "",
    "response_flags": "-",
    "route_name": "httproute/default/my-route/rule/0/match/0/my_domain",
    "start_time": "2025-12-22T15:33:03.908Z",
    "upstream_cluster": "httproute/default/my-route/rule",
    "upstream_host": null,
    "upstream_local_address": null,
    "upstream_transport_failure_reason": null,
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
    "x-envoy-origin-path": "/oauth2/callback?error=access_denied&<some params>",
    "x-envoy-upstream-service-time": null,
    "x-forwarded-for": "ip",
    "x-request-id": "ce91c00b-e4d1-41f7-8d69-a2c97758c9d7"
}

Metadata

Metadata

Assignees

Labels

kind/bugSomething isn't working

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions