Building a Secure, Scalable Serverless To-Do App with AWS

Introduction

Every developer has that one project that forces them to grow beyond their comfort zone. For me, it was building a secure serverless to-do application from scratch — an end-to-end project that touched every stage of the software development lifecycle.

My goal wasn’t just to build another to-do app. I wanted to prove to myself that I could design, develop, and deploy a full-stack application that followed best practices in scalability, security, and automation.


Why This Project?

I wanted to challenge myself to:

  • Architect and deploy a serverless backend that is scalable and production-ready.

  • Build a modern frontend that feels responsive and secure.

  • Integrate user authentication and authorization using Amazon Cognito.

  • Implement a CI/CD pipeline with GitHub Actions to automate testing, security scans, and deployments.

  • Treat security as a first-class citizen by embedding it directly into the development pipeline.

Codebase: https://github.com/VishuPatel-27/serverless-secure-todo-app.git


Architecture at a Glance

The application architecture is fully serverless, built entirely on AWS.

Frontend:

  • Hosted on Amazon S3, served globally through CloudFront (with HTTPS support).

  • Built with HTML, JavaScript, and Tailwind CSS.

Authentication:

  • Managed by Amazon Cognito, which provides user sign-up/sign-in flows and JWT-based authentication.

Backend:

  • API Gateway to expose REST endpoints.

  • AWS Lambda functions for CRUD operations on todos.

  • DynamoDB as the NoSQL data store, partitioned by userId.

CI/CD:

  • GitHub Actions workflows to build, test, scan, and deploy both frontend and backend.

  • Integrated security scans (SCA, SAST, IaC).


Flow (User Journey)

  1. User visits CloudFront-distributed frontend (from S3).

  2. Frontend integrates with Cognito for sign-up/sign-in → receives JWT token.

  3. User performs CRUD actions → frontend calls API Gateway with JWT token in headers.

  4. API Gateway validates token with Cognito authorizer.

  5. API Gateway invokes the appropriate Lambda function.

  6. Lambda function queries/updates DynamoDB.

  7. Response is returned to API Gateway → frontend → user.

  8. GitHub Actions pipeline ensures automated deploys and security gates.
    Challenges I Faced


Like most real-world projects, things didn’t go smoothly from day one. Here are some of the roadblocks I ran into:

  • API Data Parsing: At first, API responses were Response objects with ReadableStream bodies instead of plain JSON. Debugging this was a mini battle in itself.

  • CI/CD Pipeline Integration: Orchestrating one workflow to handle both frontend (Webpack → S3 + CloudFront) and backend (SAM → Lambda, DynamoDB) deployments was trickier than expected.

  • Automated Security Gating: Researching and integrating multiple security tools (SCA, SAST, IaC scanning) into GitHub Actions took time — but it paid off in catching vulnerabilities early.

  • Build & Dependency Management: SAM builds initially caused out-of-memory errors. After digging deeper, I learned about .samignore limitations and the quirks of BuildMethod: makefile.

  • No Prior SAM Experience: This was my first serious AWS SAM project, and I had to learn its conventions quickly.

  • CORS & Cognito: Getting CORS right was a puzzle, especially since Cognito by default applies the default authorizer on preflight requests.

  • CloudFront & HTTPS: I had to use CloudFront because Cognito requires HTTPS callback URLs.


What I Learned

  • How to think in serverless-first architecture.

  • The importance of security shift-left — making security checks part of CI/CD, not an afterthought.

  • Deepened my understanding of AWS SAM, API Gateway authorizers, and CloudFront edge cases.

  • How to keep a project maintainable by splitting backend/frontend workflows but orchestrating them together.


Improvements I Want to Add

The project is far from “done.” A couple of features are on my roadmap:

  • Password reset flow for Cognito users.

  • Todo modification after creation.

  • More advanced logging and monitoring using CloudWatch.


Closing Thoughts

This project wasn’t just about building a to-do app — it was about building confidence in my ability to design and deploy secure, scalable applications in the cloud.

If you’re starting with serverless, my advice would be:

  • Expect roadblocks — debugging cloud quirks is part of the journey.

  • Treat CI/CD and security as integral parts of your design, not add-ons.

  • Learn by doing — nothing beats hands-on experimentation.


That was my journey of building a Secure Serverless To-Do Application with AWS. If you’re exploring serverless or security in the cloud, I’d love to connect and exchange learnings.

#Serverless #AWS #DevOps #Cognito #CI/CD #Security #GitHubActions #APIGateway #Todo #DevSecOps

1
Subscribe to my newsletter

Read articles from Vishukumar Patel directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Vishukumar Patel
Vishukumar Patel

Hi there! I’m a DevOps enthusiast, certified in AWS, and passionate about crafting innovative cloud solutions. From designing scalable CI/CD pipelines to deploying microservices on cloud platforms, I’ve immersed myself in transforming ideas into impactful technologies.