Search code examples
istioenvoyproxy

Istio (envoy) rate limits for matching the absence of a header


We'd like to implement envoyFilters that allow us to apply a local rate limit of 20 requests as maximum per minute to all traffic that has not a particular header. Idea is to limit the amount of request to all non-authenticated users which should lack the header x-user-auth: some_value.

All requests are done to the same Kubernetes service and from different/undetermined origins. We are not using any Istio ingressgateway, but all the pods that are part of the circuit of these requests have the Istio sidecar proxy injected into them.

How could this be achieved?


Solution

  • I'm not using the local rate limit, but external service that acts as our ratelimiter - I've described it in more details in this article: https://domagalski-j.medium.com/istio-rate-limits-for-egress-traffic-8697df490f68

    So in my case it was just a matter of adjusting envoy actions. I've changed it from generic_key to request_headers - as you can read in the docs, request_headers have an option: skip_if_absent - if left blank then if a given header is not attached to the request, the request is not forwarded to rate limiter service. You are trying to ratelimit everything that doesn't have a particular header so maybe "header_value_match" action will suits you better, as it has "expect_match" field that you may use.

    This is EnvoyFilter I've used in istio:

    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: route-httpbin
      namespace: default
    spec:
      workloadSelector:
        labels:
          app: bastion-box
      configPatches:
        - applyTo: HTTP_ROUTE
          match:
            context: SIDECAR_OUTBOUND
            routeConfiguration:
              vhost:
                name: "httpbin.org:80"
                route:
                  name: "default"
          patch:
            operation: MERGE
            value:
              route:
                rate_limits:
                  - actions:
                      - request_headers:
                          header_name: "X-Client-Id"
                          descriptor_key: "clientId"
                      - request_headers:
                          header_name: "X-Credential-Username"
                          descriptor_key: "username"
    

    I also found this article very helpful to understand envoy filters: https://www.aboutwayfair.com/tech-innovation/understanding-envoy-rate-limits