Security on AWS — Serverless
At GumGum, the security of infrastructure inside and outside of Amazon Web Services (AWS) is one of our top priorities. Our main goal is to avoid managing an excess of instances with our applications or databases. Therefore AWS plays a large role in our success, providing serverless services such as Lambda, Amazon API Gateway, DynamoDB, RDS and Cloudfront which are responsible for maintenance, high availability and a physical layer of security. We as engineers are responsible for and manage the logical security layer of these services. In this blog post, I will show examples of our infrastructure with a simple application based on serverless services, with an introduction to the services that will be used, and how we can secure them.
Prerequisites
- Basic knowledge of AWS Services and Python
- Have installed a `make` application
- Basic knowledge of SAM or Terraform
- Have installed SAM cli or Terraform
Our infrastructure to implement

Lambdas are written as Python scripts, and we can use Boto3 (AWS SDK for Python) to communicate with a DynamoDB database to PUT/GET logs.
To set up the infrastructure, we will be using the AWS Serverless Application Model (SAM) or Terraform as infrastructure as a code https://aws.amazon.com/serverless/sam/.
Services used to implement the infrastructure
Cloudfront
Cloudfront (CDN) provides a high performance network and cost optimization. In our case, it improves security with its traffic encryption and access controls to resources. It uses AWS Shield Standard to defend against DDoS attacks at no additional charge. We can also attach an AWS Web Application Firewall (WAF) service as an additional layer of security.
API Gateway
We use API Gateway as our entry point to lambda functions. API Gateway is a public service with a public endpoint, and supports three types of resource policies such as AWS Account Allowlist, IP Range Denylist, and Source VPC Allowlist. To prevent the invoking of our API Gateway endpoint apart from the CloudFront service, we have used an Authorizer as a part of authorization requests.

Lambda
Lambda gives us the ability to run our code without setting up additional infrastructures such as ECS, EKS or EC2 instances. AWS is provisioning and managing this infrastructure, but we have to ensure that the functions are secured by setting up the least privileges to run the code.
DynamoDB
DynamoDB is a serverless no-SQL database. We use it to store our data such as timestamp, type and payload. This service has a public endpoint, so we have to create a policy for the lambda functions which have the ability to communicate with it.
AWS Web Application Firewall
AWS Web Application Firewall (AWS WAF) is a basic system which provides the ability to protect our website or API from attackers who use vulnerabilities in the application. We use this service to prevent a connection from the Tor network.
Implementation
Authorization of Lambda
This function is used to check incoming requests from Cloudfront based on headers. We use the JWT header which has a token and compare it with the JWT environment variable. If both variables are equal, then the request is allowed.
Writer Lambda
Writer lambda is used as a writer to DynamoDB. It receives JSON data which has type and payload keys, and also uses a bleach library to clean the HTML fragment of malicious content before returning it.
Reader Lambda:
The reader function is used to return all records from DynamoDB.
Let’s start implementing our infrastructure using SAM or Terraform tools.
SAM implementation:
Terraform implementation:
Deploying the infrastructure
We have two implementations of the infrastructure. The first is implemented in Terraform and the second one in SAM. You can compare both and choose better for you.
Terraform:
make terra-deploy
SAM:
make deploy bucket=<bucket-name-for-lambda-pkgs
After deploy:
We can check the Authorizer function by invoking the /stats
endpoint directly and through the Cloudfront:
$ curl -XGET https://pwv7jgz47c.execute-api.us-west-2.amazonaws.com/Prod/stats
{"message":"Unauthorized"}$ curl -XGET https://d1rq3npiu56bw.cloudfront.net/stats
[]
Let’s also check our WAF rule from the Tor browser. We will get an access denied message:

Summary
Summing up, security on AWS is important, and we have to focus on our implementation and provide the least privileges for services such as lambdas, EC2 instances or users and so on.
I hope that the post helps you understand a mechanism where and how you can secure your serverless application using custom security such as the JWT token, WAF or CDN.