

from
Ashutosh Tamhankar
Cloud Engineer
Cloud Engineer
Key learnings from securing APIs on AWS
Intrigued by a recent security flaw in a SaaS platforms API – where certain APIs were accidentally left publicly accessible without any authentication – we set out to learn how to secure APIs using AWS. This article will summarize the key learnings from authenticating and authorizing APIs on AWS.
Problem
In the security incident, unsecured APIs allowed any users through the API to access data that should be protected from unauthorized access. Imagine running a restaurant that such a platform with unprotected APIs which expose data like order details, historical sales data, and even personal information of customers. Now imagine a malicious user placing orders on behalf of customers—without their consent.
Solution
To demonstrate the solution to the above scenario, we built a sample platform for restaurants and shops, focusing on securing the APIs provided by the platform to its users, such as the platform administrator, shop owner, and a customer visiting one of the establishments using the sales platform.
- Every customer can see the products and place an order at the shop they are currently visiting.
- Each customer can only view their own orders. A visitor (guest) customer should be able to view their order status if the application caches the session cookie. A registered customer should be able to view all their historical orders.
- Each shop owner can only access information related to their own shop, including products, orders, and sales.
- The administrator of the SaaS platform can only view aggregated platform-wide statistics.
You can find the code of the demo, developed using the CDK, in the following repo: amanoxsolutions/api-security-demo
The above diagram illustrates the high-level architecture of the sample platform for restaurants . APIs are exposed by the API Gateway, which integrates with Lambdas, which in turn interface with a DynamoDB table. The APIs were secured using the following processes:
- Control API access using AWS_IAM authorization in API Gateway
- Define roles and map them to Cognito Identity Pools (customer, shop owner, platform administrator) to restrict API access based on roles (e.g. a customer can’t access shop management APIs)
- Validate shop tokens and HTTP methods (currently seeing only in resources/lambdas/list_products/main.py)
Key learnings
- Always follow the principle of least privilege— In this context this is done by assigning different IAM Roles to Cognito users based on their role. A customer is assigned an IAM role granting access to a different set of APIs than the IAM role assigned to a shop owner, and different again from the IAM role assigned to a platform administrator.
- Unauthorized access is blocked by clear role mapping. Here’s an example of how unauthorized access is effectively blocked when a customer attempts to retrieve order details without the appropriate permissions. Output from postman:
https://gt4n9vo5yk.execute-api.eu-central-1.amazonaws.com/prod/shop/0001/orders
{
"Message": "User: arn:aws:sts::645143808269:assumed-role/api-security-demo-IdentityPool-AuthenticatedDefaultRole/CognitoIdentityCredentials is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:eu-central-1:********8269:gt4n9vo5yk/prod/GET/shop/0001/orders"
}
Conclusion
By integrating authentication and authorization mechanisms, we successfully secured APIs in our sample application—demonstrating how AWS services can work together to protect sensitive data.