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:
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).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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With