OAuth2 EnvoyFilter is not applied while others are

Hello,

I’m trying to apply mandatory authentication through Okta before accessing the apps running on the cluster (GKE on GCP), by applying the Envoy OAuth2 filter at the Istio Ingress Gateway level. However, after applying the EnvoyFilter, nothing change, and I can still access the application without being redirected to Okta first.

Istioctl version: 1.16.2
Kubernetes version: v1.25.5-gke.2000

I did two things to diagnose the issue:

  • Add another Envoy filter with a Lua script that add a header, to see if the EnvoyFilter was properly applied
  - applyTo: HTTP_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
            subFilter:
              name: "envoy.filters.http.router"
    patch:
      operation: INSERT_BEFORE
      value:
       name: envoy.filters.http.lua
       typed_config:
         "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
         default_source_code:
          inline_string: |
              function envoy_on_request(request_handle)
                  request_handle:headers():add("authorization", "it works!")
              end
              function envoy_on_response(response_handle)
                    filter_name = "ENVOY"
                    response_handle:headers():add("my_Filter", filter_name)
              end

Running a curl on my cluster endpoint, I can see that the filter is applied and the test header added:

curl -s -I -X HEAD https://www.mytestdomain.com/productpage
HTTP/2 200
content-type: text/html; charset=utf-8
content-length: 5294
server: istio-envoy
date: Thu, 09 Feb 2023 13:23:56 GMT
x-envoy-upstream-service-time: 51
my_filter: ENVOY
via: 1.1 google
alt-svc: h3=“:443”; ma=2592000,h3-29=“:443”; ma=2592000

  • Watch the logs of the ingress gateway for any problems. Indeed, there is a warning about the secrets not being found:

“2023-02-09T12:26:18.535534Z warning envoy config gRPC config for type.googleapis.com/envoy.config.listener.v3.Listener rejected: Error adding/updating listener(s) 0.0.0.0_8080: paths must refer to an existing path in the system: ‘/etc/istio/config/token-secret.yaml’ does not exist”

Running kubectl exec istio-ingressgateway-pod -n istio-system -c istio-proxy -- ls /etc/istio/config, I do not see any secrets files.

This problem is mentiond here but the workaround did not fixed the issue for me. I changed between inline_bytes and inline_string and nothing changed.

Please find below my full config:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: ingressgateway-settings
  namespace: istio-system 
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: NETWORK_FILTER # trusts the GCLB (two hops) and does not sanitize the X-Forwarded headers
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: envoy.filters.network.http_connection_manager
    patch:
      operation: MERGE
      value:
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager" 
          xff_num_trusted_hops: 2
  - applyTo: CLUSTER
    match:
      cluster:
        service: oauth
    patch:
      operation: ADD
      value:
        name: oauth
        dns_lookup_family: V4_ONLY
        type: LOGICAL_DNS
        connect_timeout: 10s
        lb_policy: ROUND_ROBIN
        transport_socket:
          name: envoy.transport_sockets.tls
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
            sni: myorg.okta.com 
        load_assignment:
          cluster_name: oauth
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: myorg.okta.com 
                    port_value: 443
  - applyTo: HTTP_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
            subFilter:
              name: "envoy.filters.http.router"
    patch:
      operation: INSERT_BEFORE
      value:
       name: envoy.filters.http.lua
       typed_config:
         "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
         default_source_code:
          inline_string: |
              function envoy_on_request(request_handle)
                  request_handle:headers():add("authorization", "it works!")
              end
              function envoy_on_response(response_handle)
                    filter_name = "ENVOY"
                    response_handle:headers():add("my_Filter", filter_name)
              end
  - applyTo: HTTP_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
            subFilter:
              name: "envoy.filters.http.jwt_authn"
    patch:
      operation: INSERT_BEFORE
      value:
       name: envoy.filters.http.oauth2
       typed_config:
         "@type": type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2
         config:
          token_endpoint:
            cluster: oauth
            uri: "https://myorg.okta.com/oauth2/v1/token" 
            timeout: 5s
          authorization_endpoint: "https://myorg.okta.com/oauth2/v1/authorize" 
          redirect_uri: "http://localhost:8080/authorization-code/callback" 
          redirect_path_matcher:
            path:
              exact: /callback
          signout_path:
            path:
              exact: /signout 
          auth_scopes:
            - openid
            - profile
          credentials:
            client_id: xxx
            token_secret:
              name: token
              sds_config:
                path: "/etc/istio/config/token-secret.yaml"
            hmac_secret:
              name: hmac
              sds_config:
                path: "/etc/istio/config/hmac-secret.yaml"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: istio-oauth2
  namespace: istio-system
data:
  token-secret.yaml: |-
    resources:
      - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
        name: token
        generic_secret:
          secret:
            inline_bytes: xxx
  hmac-secret.yaml: |-
    resources:
      - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
        name: hmac
        generic_secret:
          secret:
            # generated using `head -c 32 /dev/urandom | base64`
            inline_bytes: xxx

Any help welcomed. Thank you!

Hello,

Below issue is working for me when i used inline_bytes for hmac_secret and it was generated using head -c 32 /dev/urandom | base64. but redirecting to keycloak login URL.

Issue: “2023-02-09T12:26:18.535534Z warning envoy config gRPC config for type.googleapis.com/envoy.config.listener.v3.Listener rejected: Error adding/updating listener(s) 0.0.0.0_8080: paths must refer to an existing path in the system: ‘/etc/istio/config/token-secret.yaml’ does not exist”

Hello,

Did you had to mount the ConfigMap? If yes, how did you do it? I also opened an issue here : OAuth2 Envoy Filter not applied but others are · Issue #43251 · istio/istio · GitHub

Hello,
I deployed OAuth2 Envoy filter(customized envoy configuration) on to xxx namespace where our services are deployed without workload selector tag and with configPatches applied to CLUSTER, HTTP_FILTER,HTTP_FILTER in this order. no volume mount but still redirection to keycloak login page is not happening. I tried following option

  1. Client id with client credentials
  2. Client id without client credentials