By on March 17, 2016

Protecting and Rate Limiting an API with Kong

You have just finished building a nice RESTful API, implemented all the endpoints, and you are ready to make it available to potential developers. Usually the next steps before publishing the API are:

  1. Protecting the API, with a security mechanism, ie with an API-key or Basic authentication.
  2. Rate-Limit developers, to avoid them making too many requests to your service.
  3. Whitelist developers, and allow them to make more requests than the others.

With Kong, an open source API gateway, you can easily implement the above features and let it do the hard work for you. And most of all, you can do it quickly.

How does Kong work?

Kong sits in front of your APIs and is the main entry-point to your upstream APIs. While processing the request and the response, Kong will execute any plugin that you have decided to add to the API.

 

kong-simple

 

We assume you have already installed Kong on your system.

Adding an API on Kong

The first step is adding an API on Kong using Kong’s admin API. We will use Mockbin as our example API, and assume Kong is running on the local system at the default ports:

curl http://127.0.0.1:8001/apis/ \
     -d "name=mockbin" \
     -d "request_path=/test" \
     -d "strip_request_path=true" \
     -d "upstream_url=http://mockbin.org"

Now Kong is aware that every request sent to “/test” should be proxied to Mockbin. We can make the following request to Kong on its proxy port to test it:

curl http://127.0.0.1:8000/test/request

{
    "startedDateTime": "2016-03-08T07:37:03.611Z",
    "clientIPAddress": "127.0.0.1",
    "method": "GET",
    ...
}

And it works. The request has been received by Kong and proxied to Mockbin, not before stripping the “/test” path as instructed with the “strip_request_path” property when adding the API on Kong.

Adding Key Authentication

Now that the API has been added on Kong, we can start adding extra functionality to it by using Kong Plugins. For example, let’s add Key Authentication plugin that expects the developers to send a valid api-key in order to consume the API:

curl http://127.0.0.1:8001/apis/mockbin/plugins/ \
     -d "name=key-auth" \
     -d "config.key_names=apikey"

And that’s it. We added key authentication security in a few seconds. Trying to consume the API again will fail this time because no security credentials have been created:

curl http://127.0.0.1:8000/test/request

{
    "message":"No API Key found in headers, body or querystring"
}

Creating a consumer and a credential

Now that the API has been protected, we need to create a consumer and associate an api-key credential to it. This is very straightforward, let’s create a consumer first:

curl http://127.0.0.1:8001/consumers/ \
     -d "username=mike"

And then let’s create a new credential for our consumer:

curl http://127.0.0.1:8001/consumers/mike/key-auth/ \
     -d "key=secret_key_123"

Great, we now have an API, an authentication plugin, a consumer and its credential. We can now consume the API by appending the credential to the request, for example:

curl http://127.0.0.1:8000/test/request?apikey=secret_key_123

{
    "startedDateTime": "2016-03-08T07:37:03.611Z",
    "clientIPAddress": "127.0.0.1",
    "method": "GET",
    ...
}

And it works! The consumer has been properly authenticated this time and the request went through to the final API.

Adding Rate-Limiting

We have protected our API by using Kong’s Key Authentication plugin, so let’s go ahead and protect it from an excessive number of requests by adding the rate-limiting functionality using the Rate-Limiting plugin, with a limit of 10 requests per minute from every consumer:

curl http://127.0.0.1:8001/apis/mockbin/plugins/ \
     -d "name=rate-limiting" \
     -d "config.minute=10"

And done. If we now make more than 10 requests, Kong will respond with the following error message:

curl http://127.0.0.1:8000/test/request?apikey=secret_key_123

{
    "message":"API rate limit exceeded"
}

So far so good. We have literally added an API on Kong, protected it with key-authentication, create a consumer and a credential, plus we added rate-limiting in just five HTTP requests to Kong’s admin API.

Customizing the Rate-Limiting per consumer

Let’s say that now we have an enterprise customer who deserves a higher rate-limit. Well, many plugins on Kong can be configured not only per API, but also per API and Consumer, by specifying the “consumer_id” property when adding the plugin.

curl http://127.0.0.1:8001/consumers?username=mike

{
    "total":1,
    "data":[{
        "id":"03040614-5cfb-4138-8277-c3f856de1fe8",
        "username":"mike",
        "created_at":1457423123000
    }]
}

Our consumer’s ID is “03040614-5cfb-4138-8277-c3f856de1fe8”, so we can now add a customized the Rate-Limiting plugin just for him, with a higher limit of 200 requests per minute:

curl http://127.0.0.1:8001/apis/mockbin/plugins/ \
     -d "name=rate-limiting" \
     -d "config.minute=200"

The above command will allow our consumer “mike” to make up to 200 requests per minute before being blocked by Kong, while still keeping the limit at 10req/minute for every other consumer.

zgWFptmpEKSl

What next?

Kong supports tens of plugins that allow to implement pretty much every common API requirement, from authentication to logging, going through transformations and monitoring. It is stateless, so you can scale your system just by adding more Kong instances, and supports every RESTful API and Microservice.

Want to secure, manage and extend your APIs and Microservices?