envoyproxy / gateway

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

AND NOT style matches for RateLimiting #2193

Open arkodg opened 10 months ago

arkodg commented 10 months ago

Description:

Describe the desired behavior, what scenario it enables and how it would be used.

Consider this config

cat <<EOF | kubectl apply -f -
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: jwt-backend
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: backend
  jwt:
    providers:
    - name: example
      remoteJWKS:
        uri: https://test.eu.auth0.com/.well-known/jwks.json
      claimToHeaders:
      - claim: email
        header: x-user-email
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy 
metadata:
  name: policy-httproute
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: backend
    namespace: envoy
  rateLimit:
    type: Global
    global:
      rules:
      - clientSelectors:
        - headers:
          - name: x-user-email
            value: myemail@gmail.com
        limit:
          requests: 10
          unit: Minute
    - clientSelectors:
      - headers:
        - type: Distinct
          name: x-claim-email
      limit:
        requests: 5
        unit: Minute
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: backend
spec:
  parentRefs:
    - name: eg
      namespace: envoy
  hostnames:
    - "www.example.com"
  rules:
    - backendRefs:
        - group: ""
          kind: Service
          name: backend
          port: 3000
          weight: 1
      matches:
        - path:
            type: PathPrefix
            value: /
EOF

I want to allow myemail@gmail.com user to 10 req/min but all other user 5 req/min. But with this config myemail@gmail.com user is getting 429 after 5 requests.

Relates to https://envoyproxy.slack.com/archives/C03E6NHLESV/p1699784524023299

[optional Relevant Links:]

Any extra documentation required to understand the issue.

arkodg commented 10 months ago

thinking out loud, this use case can be achieved in two ways

  1. by adding a dontMatch field
    - clientSelectors:
      - headers:
        - type: Distinct
          name: x-claim-email
        - type: Exact
           name: x-claim-email
           dontMatch: true
           value: myemail@gmail.com
  1. by adding a except field
    - clientSelectors:
      - headers:
        - type: Distinct
          name: x-claim-email
         except:
           headers:    
           - type: Exact
              name: x-claim-email
              value: myemail@gmail.com

this api field would decide the value of expect_match in https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-ratelimit-action-headervaluematch

slayer321 commented 10 months ago

I'm new to this part of the code , will like to learn an implement this feature. /assign

arkodg commented 10 months ago

ptal @envoyproxy/gateway-maintainers

github-actions[bot] commented 9 months ago

This issue has been automatically marked as stale because it has not had activity in the last 30 days.

arkodg commented 1 week ago

hey @slayer321 still planning on working on this issue ?

slayer321 commented 1 week ago

Hey @arkodg , currently stuck with some other stuff .. will not be able to work on this issue as of now.

rudrakhp commented 1 week ago

@arkodg interested in picking up this issue, thanks!

arkodg commented 1 week ago

great thanks @rudrakhp, suggest breaking up the work into multiple PRs (API, Implementation, Docs/E2E)

rudrakhp commented 1 week ago

@arkodg raised API PR to support this in both header and source matches. Thought it might be easier to do so when dealing with scenarios where subset IP CIDRs might be exempted or have different rate limits. Preferred the dontMatch approach, went with another name though. Please do review, thanks!