How to Rate-Limit Requests by JWT Claim

Overview

This tutorial shows how to apply rate limiting in Membrane API Gateway based on a claim inside a JWT—specifically the organization claim. Different token issuers can be throttled independently.

Use Case

Useful when different clients (organizations) access the same API and you want to apply fair usage rules.

Step 1: Generate a JWK

./membrane.sh generate-jwk -o ./conf/jwk.json

Step 2: Configure the Routes

<router>

  <!-- Token Issuer 1: Exotic Fruits Company -->
  <api port="2000" name="Token Issuer 1">
    <request>
      <template>
        {
          "sub": "alice@exotic-fruits.com",
          "aud": "order",
          "organization": "Exotic Fruits Company"
        }
      </template>
      <jwtSign>
        <jwk location="jwk.json"/>
      </jwtSign>
    </request>
    <return/>
  </api>

  <!-- Token Issuer 2: Western Tasty Fruits Ltd. -->
  <api port="2003" name="Token Issuer 2">
    <request>
      <template>
        {
          "sub": "bob@western-fruits.com",
          "aud": "order",
          "organization": "Western Tasty Fruits Ltd."
        }
      </template>
      <jwtSign>
        <jwk location="jwk.json"/>
      </jwtSign>
    </request>
    <return/>
  </api>

  <!-- Protected API with Rate Limiting -->
  <api port="2001" name="Protected API with Rate Limiting">
    <jwtAuth expectedAud="order">
      <jwks>
        <jwk location="jwk.json"/>
      </jwks>
    </jwtAuth>

    <rateLimiter keyExpression="${properties.jwt['organization']}"
                 requestLimitDuration="PT300S"
                 requestLimit="4"/>

    <static>Welcome! You’ve successfully connected.</static>
    <return statusCode="200"/>
  </api>

</router>

Step 3: Start Membrane

./membrane.sh

Step 4: Demo

Request a token from Token Issuer 1 (Port 2000):

curl http://localhost:2000

Use the token to hit the API (Port 2001). Repeat 4 times:

curl -H "Authorization: Bearer <token>" http://localhost:2001

The 5th request should be blocked with a rate limit (HTTP 429).

Now get a token from Token Issuer 2 (Port 2003):

curl http://localhost:2003

Use that token to make a request—should succeed, different organization!

Note: The rate limit is per-organization, refreshed every 5 minutes (PT300S).

Next Steps