envoyproxy / gateway

Manages Envoy Proxy as a Standalone or Kubernetes-based Application Gateway
https://gateway.envoyproxy.io
Apache License 2.0
1.58k stars 343 forks source link

Ext_Authz Filter and Authorization Header #4522

Open jamesglennan opened 2 hours ago

jamesglennan commented 2 hours ago

Hi Team,

I've been trying to get something working- I'm currently in the process of migrating from Contour to Envoy Gateway. I have an issue where any request I pass with an Authorization header is bypassing the Ext_Authz service and going straight to the backend service. Is there some setting I don't know about or some change between envoy versions where this is expected.

In our current setup a token is passed down to the Ext_Authz server and replaced with another token that the Authz server generates based on the first token. This currently works in contour- as far as the Ext_authz config in the config_dump the biggest difference I see is that clear_route_cache is enabled, but i pulled the latest code that supports the RecomputeRoute variable and I'm not getting any different behaviour.

Any help on this issue would be greatly appreciated. Please feel free to ask me questions, I would be happy to join the slack (it doesnt look open) if it would be easier to chat there

arkodg commented 2 hours ago

hey @jamesglennan welcome to Envoy Gateway, can you share your config (SecurityPolicy, HTTPRoute) with -o yaml so we can also look at the Status thats populated.

you may have already seen this, here's an example of implementing ext authz https://gateway.envoyproxy.io/docs/tasks/security/ext-auth/

jamesglennan commented 2 hours ago

Hi @arkodg Thanks for the quick response

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: authenticated
  namespace: dev145
spec:
  extAuth:
    failOpen: false
    grpc:
      backendRefs:
      - group: ""
        kind: Service
        name: platform-authentication-service
        port: 9443
  targetSelectors:
  - group: gateway.networking.k8s.io
    kind: HTTPRoute
    matchLabels:
      securityPolicy: authenticated
status:
  ancestors:
  - ancestorRef:
      group: gateway.networking.k8s.io
      kind: Gateway
      name: api
      namespace: dev145
    conditions:
    - lastTransitionTime: "2024-10-24T00:19:34Z"
      message: Policy has been accepted.
      reason: Accepted
      status: "True"
      type: Accepted
    controllerName: gateway.envoyproxy.io/dev145-gatewayclass-controller

I've ommitted some things (like our cors policy)- but works otherwise, using the example you provided if we have another header that contains some auth information that i can see logged in the authentication service, checked and approved and the request goes on

One big difference is this particular endpoint is a websocket- so is there something when the upgrade connection is sent off that would cause it miss? In our current setup that connection goes as I said above, the Authorization header gets overwritten and passed on to the service

jamesglennan commented 1 hour ago

Sorry forgot the httproute

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  labels:
    securityPolicy: authenticated
  name: service-websocket
  namespace: dev145
spec:
  hostnames:
  - example.com
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: api
    namespace: dev145
  rules:
  - backendRefs:
    - group: ""
      kind: Service
      name: our-service
      port: 2622
      weight: 1
    matches:
    - path:
        type: Exact
        value: /system/socket2
status:
  parents:
  - conditions:
    - lastTransitionTime: "2024-10-24T03:58:41Z"
      message: Route is accepted
      observedGeneration: 4
      reason: Accepted
      status: "True"
      type: Accepted
    - lastTransitionTime: "2024-10-24T03:58:41Z"
      message: Resolved all the Object references for the Route
      observedGeneration: 4
      reason: ResolvedRefs
      status: "True"
      type: ResolvedRefs
    controllerName: gateway.envoyproxy.io/dev145-gatewayclass-controller
    parentRef:
      group: gateway.networking.k8s.io
      kind: Gateway
      name: api
      namespace: dev145

I've ommitted or changed some values like the hostname, but as you can see it seems resolved and accepted

If i send a request to that endpoint ommitting the Auth header, it will attempt to go via ext-authz

jamesglennan commented 1 hour ago

Sorry for the spam- ive just noticed on a regular (non-websocket) it will pass to the ext_authz service if the Authz header is populated so this makes me think its websocket specific?