API Rate limiting with generated token

Good afternoon. I am playing with Tyk as a POC to evaluate which API Gateway we will be setting up in our company and I have the following scenario where I need to set up rate limiting for generated tokens:

  1. Client calls /oauth/token with a Basic HTTP Authorization header. In this case it was kind of easy to add to Tyk the same credential that is needed to send to our backend as the Authorization header. This was configured as follow:

API Config

{
  "name": "OAuth-Token",
  "api_id": "OAuth-Token",
  "org_id": "1",
  "use_basic_auth": true,
  "auth_configs": {
    "basic": {
      "auth_header_name": "Authorization"
    }
  },
  "definition": {
    "location": "header",
    "key": "x-api-version"
  },
  "version_data": {
    "not_versioned": true,
    "versions": {
      "Default": {
        "name": "Default",
        "use_extended_paths": true
      }
    }
  },
  "proxy": {
    "listen_path": "/oauth/token",
    "target_url": "https://my-server/oauth/token/",
    "strip_listen_path": true
  },
  "active": true
}

Creating Key

curl --location --request POST 'localhost:7070/tyk/keys/my_client_id' \
--header 'X-Tyk-Authorization: my_tyk_token' \
--header 'Content-Type: application/json' \
--data-raw '{
  "allowance": 1000,
  "rate": 1000,
  "per": 1,
  "expires": -1,
  "quota_max": -1,
  "org_id": "1",
  "quota_renews": 1449051461,
  "quota_remaining": -1,
  "quota_renewal_rate": 60,
  "access_rights": {
    "OAuth-Token": {
      "api_id": "OAuth-Token",
      "api_name": "OAuth-Token",
      "versions": ["Default"]
    }
  },
  "meta_data": {},
  "basic_auth_data": {
    "password": "my_client_password"
  }
}'

With the configuration above I am able to call the following URL and Tyk can Rate Limit it properly:

curl --location --request POST 'http://localhost:7070/oauth/token/?grant_type=client_credentials' \
--header 'Authorization: Basic my_basic_token_using'

This API call returns the following:

{
    "access_token": "my_unique_access_token",
    "token_type": "bearer",
    "expires_in": 1799,
    "scope": "read write"
}

Now I would like to have all other APIs to be able to be rate-limited using my_unique_access_token as the token and I could not find a way of achieving it. I would also like to have different rate limits for different APIs that are using the same token.

Is there a way I can achieve what I need with Tyk? I don’t want to have to generate an access token that Tyk will hold and send it in another header just to be able to rate limit my APIs, which would also enforce that every API using the same access token would have the same rate limits. For example, I could have a set of APIs like this model:

{
  "name": "API-1",
  "api_id": "API-1",
  "org_id": "1",
  "auth_configs": {
    "authToken": {
      "auth_header_name": "X-Api-Key"
    }
  },
  "definition": {
    "location": "header",
    "key": "X-Api-Version"
  },
  "version_data": {
    "not_versioned": true,
    "versions": {
      "Default": {
        "name": "Default",
        "use_extended_paths": true
      }
    }
  },
  "proxy": {
    "listen_path": "/my/listen/path/api-1",
    "target_url": "https://my-server/api/api-1",
    "strip_listen_path": true
  },
  "active": true
}

And have the same rate limit for all of them like this:

curl --location --request POST 'localhost:7070/tyk/keys/create' \
--header 'X-Tyk-Authorization: my_tyk_token' \
--header 'Content-Type: application/json' \
--data-raw '{
  "allowance": 1000,
  "rate": 1000,
  "per": 1,
  "expires": -1,
  "quota_max": -1,
  "org_id": "1",
  "quota_renews": 1449051461,
  "quota_remaining": -1,
  "quota_renewal_rate": 60,
  "access_rights": {
    "API-1": {
      "api_id": "API-1",
      "api_name": "API-1",
      "versions": ["Default"]
    },
    "API-2": {
      "api_id": "API-2",
      "api_name": "API-2",
      "versions": ["Default"]
    },
    "API-3": {
      "api_id": "API-3",
      "api_name": "API-3",
      "versions": ["Default"]
    },
    ...,
    "API-N": {
      "api_id": "API-N",
      "api_name": "API-N",
      "versions": ["Default"]
    }
  }
}'

But I like neither the idea of forcing API users to send an extra header, in this case X-Api-Key, nor the idea of having the same rate-limiting for ALL my APIs.

Is there a way to achieve what we need for our use case?

Thank you very much

HI @rdasilva_fispan,

It sounds like Option 1 would suit your approach. You would need to make “my_unique_access_token” a custom key via the Gateway API.

You can also set different rate limits for each API by passing a value in the limit property. Here is an example below

"access_rights": {
            "2": {
                "api_name": "Secured Star Wars REST API",
                "api_id": "2",
                "versions": [
                    "Default"
                ],
                "allowed_urls": [],
                "restricted_types": [],
                "limit": {
                    "rate": 5,
                    "per": 60,
                    "throttle_interval": -1,
                    "throttle_retry_limit": -1,
                    "max_query_depth": -1,
                    "quota_max": -1,
                    "quota_renews": 0,
                    "quota_remaining": 0,
                    "quota_renewal_rate": -1,
                    "set_by_policy": false
                },
                "allowance_scope": ""

I will try this approach to see if that works.

Thanks a bunch!

Hi, @Olu. Sorry for taking long to get back to you but things have been a bit crazy.

I was going through Option 1 and if I understood correctly, I would have to call Tyk API from my application to make Tyk generate a session key for my generated key! Is that understanding correct? If it is, I think it is a bit crazy to couple the application with the API Gateway. From the docs:

The first is to integrate a standard OAuth 2.0 flow into your application using one of the many OAuth libraries that exist for popular frameworks and languages. And then when your API issues a token, use the Tyk Gateway REST API to create a key session for your own generated key.

If my understanding is correct I think Tyk really needs to have something changed in order to automatically generate a session key when you use a configuration like this:

{
  "name": "Config-Api-Products",
  "api_id": "Config-Api-Products",
  "org_id": "1",
  "auth_configs": {
    "authToken": {
      "auth_header_name": "Authorization"
    }
  },
  "definition": {
    "location": "header",
    "key": "X-Api-Version"
  },
  "version_data": {
    "not_versioned": true,
    "versions": {
      "Default": {
        "name": "Default",
        "use_extended_paths": true,
        "extended_paths": {
          "transform_response_headers": [
            {
              "path": "/api/product/list",
              "method": "GET",
              "delete_headers": ["Strict-Transport-Security"]
            }
          ]
        }
      }
    }
  },
  "proxy": {
    "listen_path": "/api/product/list",
    "target_url": "https://my-server/api/products",
    "strip_listen_path": true
  },
  "response_processors": [
    {
      "name": "header_injector"
    }
  ],
  "active": true
}

Making a call to Tyk from the application standpoint to have this working is a big no for me :slight_smile:

Please, let me know if my understanding is correct and thank you very much for your reply!

@Olu, @rdasilva_fispan and I will have call this afternoon and I will discuss this problem and the different options then!