Mystique Unicorn App is a building new application based on microservice architectural pattern. The app provides updates on events in real-time. At any given time, there will be a number of users querying for the same data (Very much like match data of a sporting event). During the event, Many users will be using the query to check the latests stats on the match event. The app exposes for third party developers and partners to access the data and build their own dashboards.
They are exploring two offerings: Free Tier & Premium Tier. All APIs call need to be made with a valid api-key generated by the app. In the free tier developer accounts will be limited to 1
request per second and premium tier will be allowed to make 10
requests per second.
Can you help them do that in Amazon API Gateway?
Rate limiting protects your APIs from overuse by limiting how often each user can call the API. This protects them from inadvertent or malicious overuse. Without rate limiting, each user may request as often as they like, which can lead to spikes of requests that starve other consumers. After rate limiting is enabled, they are limited to a fixed number of requests per second.
In the above image, When rate limiting of 2 reqs/sec
was enabled at 13:30:01 all requests above the limit are denied(shown in red). This image is to show how rate-limiting works in a simplified way, Amazon API Gateway throttles requests to your API using the token bucket algorithm1, 2. Refer to the docs or the wiki reference to know more.
In this article, we will build the above architecture. using Cloudformation generated using AWS Cloud Development Kit (CDK). The architecture has been designed in a modular way so that we can build them individually and integrate them together. The prerequisites to build this architecture are listed below
-
This demo, instructions, scripts and cloudformation template is designed to be run in
us-east-1
. With few modifications you can try it out in other regions as well(Not covered here).- π AWS CLI Installed & Configured - Get help here
- π AWS CDK Installed & Configured - Get help here
- π Python Packages, Change the below commands to suit your OS, the following is written for amzn linux 2
- Python3 -
yum install -y python3
- Python Pip -
yum install -y python-pip
- Virtualenv -
pip3 install virtualenv
- Python3 -
-
-
Get the application code
git clone https://github.com/miztiik/secure-api-with-keys cd secure-api-with-keys
-
-
We will cdk to be installed to make our deployments easier. Lets go ahead and install the necessary components.
# If you DONT have cdk installed npm install -g aws-cdk # Make sure you in root directory python3 -m venv .env source .env/bin/activate pip3 install -r requirements.txt
The very first time you deploy an AWS CDK app into an environment (account/region), youβll need to install a
bootstrap stack
, Otherwise just go ahead and deploy usingcdk deploy
.cdk bootstrap cdk ls # Follow on screen prompts
You should see an output of the available stacks,
unsecure-api secure-api-with-keys
-
Let us walk through each of the stacks,
-
Stack: unsecure-api We are going to deploy a simple api running as a lambda function. This API is deployed as public endpoint without any usage plan or api-keys. When the api is invoked, The backend processess the request adds an timestamp to the response
There are two api resources available for us,
{UNCACHED_API_URL}
- Every invocation will return a random movie item data{UNCACHED_API_URL}/{id}
- As this is a sample, there are only 10 movies in the database.You can also invoke query the database for a movie by providing an id. The id value can be between{0..9}
Initiate the deployment with the following command,
cdk deploy unsecure-api
Expected output: The
UnSecureApiUrl
can be found in the outputs section of the stack,$ UNSECURE_API_URL="https://94zj9dm1x8.execute-api.us-east-1.amazonaws.com/miztiik/unsecure/greeter" $ curl ${UNSECURE_API_URL} { "message": "Hello from Miztiikal World, How is it going?", "ts": "2020-08-19 13:59:33.621248" }
Here you can observe that the url can be invoked by anybody and does not require any
api-key
and is only subject to the account level throttling limits. This is NOT what we wants. Lets go ahead and fix that. -
Stack: secure-api-with-keys
This stack:secure-api-with-keys is very much similar to the previous stack. In addition to that, We will also add an usage plan along with api-keys. We will create two usage plan,
- Developer Kon Usage Plan:
- This plan will allow the user to make limited requests to the API, very much similar to a free tier
- Rate Limit:
1
- Burst Limit:
1
- Partner Mystique Usage Plan:
- This plan will allow the user to make 10requests to the API. This translate to about 36K/min. Since the user also have a higher burst limit, this user can can handle high volume bursty traffic
- Rate Limit:
10
- Burst Limit:
100
For both the plans, we will let AWS create a API-Key for our users. We can retrieve them from the console after the stack is deployed. Initiate the deployment with the following command,
cdk deploy secure-api-with-keys
Check the
Outputs
section of the stack to access theSecureApiWithKeysUrl
- Developer Kon Usage Plan:
-
-
We can use a tool like
curl
orPostman
to query the urls. The Outputs section of the respective stacks has the required information on the urlsIn addition to the urls, you will also need the api-key to make an authorized request to the secure url.
-
In API Management Console, Choose this api secure_api_with_keys_01
-
Navigte to API Keys
-
Choose Developer-Kon-Key (You can retrive the partner key and test them later)
-
On the right hand size, Click Show next to the API key
-
Update the below script with your
SecureApiWithKeysUrl
&Developer-Kon-Key
-
Run the following script from a
bash
terminalThis is going to do make 30 requests to our API with api-key added in the header
X-API-Key
of each request. As we send requests beyound ourrate-limit
API Gateway will respond back withHTTP/429
error message. Likewise, if you make the request with out theX-API-Key
or incorrect api-key value, API GW will throw different errors. We have also set a limit on our backend lambda concurrent executions to20
per second. So any requests more than that will throw an500
error.
LOG_FILE_NAME="miztiik_secure_api_with_keys.log" SECURE_API_WITH_KEYS_URL="https://yy8eanv9j4.execute-api.us-east-1.amazonaws.com/miztiik/secure/greeter" DEV_KON_API_KEY="F9Zufa73OLookingForSometh1nqInLife2tG2xjblFCS" touch "${LOG_FILE_NAME}" > "${LOG_FILE_NAME}" for i in {1..30} do curl -s -w '{"status": "%{http_code}"}\n' \ --header "X-API-Key: ${DEV_KON_API_KEY}" \ -X GET "${SECURE_API_WITH_KEYS_URL}" >> "${LOG_FILE_NAME}" & done
Expected Output(When you open log file
LOG_FILE_NAME
, you should be able to find text similar to the ones shown below){"message":"Too Many Requests"}{"status": "429"} {"message": "Internal server error"}{"status": "500"} {"message": "Hello from Miztiikal World, How is it going?","ts": "2020-08-19 14:38:15.010419"}{"status": "200"}
If you are using Postman tool, Checking the url with and without the api-key.
If you are making too many requests from postman, you can notice the
429
errors,Now if you can repeat the above script with
partner API-Key
and you should be able to see more200
responsesHere we have demonstrated how to secure our API with API Keys and also offer a differentiated user experience with different usage plans and throttling limits. If you are using APIs in any regard, consider these rate limiting techniques to increase security, business impact, and efficiency across the board.
Additional Learnings: You can check the logs in cloudwatch for more information or increase the logging level of the lambda functions by changing the environment variable from
INFO
toDEBUG
-
-
Rate limiting with API Keys are a good way to maintain your APIs. To identify the best usage plans and rate limiting for your APIs try to find answers for the following questions:
- Do all my API need rate limits?
- Does all the APIs that need rate limits have rate limits?
- Does all methods needs rate limits?
- What happens if users exceed the rate limits? Hard Vs Soft Limits
- When users exceed the threshold, do they get throttled with slower responses?
- Or Do they get blocked until they fall below permissible limits?
- Do you charge for overage?
- What status codes are sent if rate limits are exceeded?
- What kind of usage plan should i use to differentiate my services between free and premium tier tiers of the API?
- Do all my API need rate limits?
-
If you want to destroy all the resources created by the stack, Execute the below command to delete the stack, or you can delete the stack from console as well
- Resources created during Deploying The Application
- Delete CloudWatch Lambda LogGroups
- Any other custom resources, you have created for this demo
# Delete from cdk cdk destroy # Follow any on-screen prompts # Delete the CF Stack, If you used cloudformation to deploy the stack. aws cloudformation delete-stack \ --stack-name "MiztiikAutomationStack" \ --region "${AWS_REGION}"
This is not an exhaustive list, please carry out other necessary steps as maybe applicable to your needs.
This repository aims to teach how to enhance api security to new developers, Solution Architects & Ops Engineers in AWS. Based on that knowledge these Udemy course #1, course #2 helps you build complete architecture in AWS.
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional documentation or solutions, we greatly value feedback and contributions from our community. Start here
Buy me a coffee β.
Level: 300