Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Istio: AuthorizationPolicy executed before RequestAuthentication?

I'd like to understand in which order RequestAuthentications and AuthorizationPolicies are executed for an istio-ingressgateway.

In a PoC, I'm defining the following RequestAuthentication and AuthorizationPolicy for the istio-ingressgateway, where the AuthorizationPolicy uses the CUSTOM action (external authorizer):

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata: 
  name: ingress-reguest-authentication
  namespace: istio-system
spec: 
  jwtRules: 
    - 
      issuer: "https://<my-issuer>"
      jwksUri: "https://<my-issuer>/oauth2/jwks"
      forwardOriginalToken: true
      outputPayloadToHeader: x-forwarded-jwt-payload
  selector:
    matchLabels:
      istio: ingressgateway
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: ingress-ext-authz
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  action: CUSTOM
  provider:
    name: ext-authz-http
  rules: [{}]

With the RequestPolicy I'd like to let Istio handle the basic token validation before the external authorizer performs additional checks, for which Istio doesn't provide configuration (in my case I want to verify that the mTLS client certificate and JWT token for an incoming request match according to RFC 8705). Since I don't want to validate the token again in the external authorizer, I'm using the outputPayloadToHeader to forward the payload of the validated JWT.

However, to my surprise, it looks like the external authorizer is actually called before the request authentication happens:

  • The x-forwarded-jwt-payload header defined in the RequestAuthentication is not arriving at the external authorizer (I ended up using the Authorization header instead to extract the JWT payload myself).
  • A request with an expired access token that also didn't match the used client cert resulted in a deny response from the external authorizer instead of the expired token being rejected by the request authentication before.

This is not what I had expected, given that ALLOW/DENY actions for authorization policies support rules which inspect JWT claims, which I assumed would be evaluated for an already validated JWT.

Is this the order in which Istio processes RequestAuthentication and AuthorizationPolicy in general or is it specific to the CUSTOM action?

Or is there simply something wrong in my configuration?

like image 488
maglite Avatar asked Oct 22 '25 20:10

maglite


1 Answers

In the end, what helped to get the order right was configuring the external authorizer through an envoy filter that is plugged into the http_connection_manager filter chain right before http router filter.

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: ingress-ext-authz
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - 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.ext_authz
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
          failureModeAllow: false
          httpService:
            serverUri:
              cluster: outbound|8000||ext-authz.default.svc.cluster.local
              timeout: 1s
              uri: http://ext-authz.default.svc.cluster.local
            authorizationRequest:
              allowedHeaders:
                patterns:
                  - exact: x-forwarded-jwt-payload
                  - exact: x-forwarded-client-cert
like image 75
maglite Avatar answered Oct 25 '25 00:10

maglite



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!