A simple serverless reference project for AWS, implemented using Node.js, Lambda, DynamoDB, API Gateway, and Cognito.
The app demonstrates how to deploy a minimal API for notes, protected by Cognito User Pool authentication, using AWS SAM.
- API Gateway — REST API secured with Cognito authorizer
- Cognito User Pool — authentication and identity management for users
- AWS Lambda (Node.js) — business logic for handling requests
- DynamoDB — stores notes (single primary key:
noteId
)
- Ensure your IAM user has the required permissions
(see sample IAM policy below) - Clone and build the project:
git clone https://github.com/your-org/notes-app-sam.git cd notes-app-sam sam build
- Deploy with guided setup:
sam deploy --guided
aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --client-id <CLIENT_ID> --auth-parameters USERNAME=<username>,PASSWORD=<password>
If NEW_PASSWORD_REQUIRED
, use respond-to-auth-challenge
as described above.
curl -X POST "https://<API-ID>.execute-api.<region>.amazonaws.com/prod/notes" -H "Content-Type: application/json" -H "Authorization: <IdToken>" -d '{"noteId": "note1", "text": "Hello from Lambda!"}'
curl "https://<API-ID>.execute-api.<region>.amazonaws.com/prod/notes?noteId=note1" -H "Authorization: <IdToken>"
- All API requests require a valid Cognito JWT
IdToken
(passed in theAuthorization
header). - Notes are stored in DynamoDB with a primary key
noteId
. - Important: Any authenticated user with a valid token can access any note by
noteId
. There is no per-user data isolation in this implementation.
{
"Effect": "Allow",
"Action": [
"cloudformation:*",
"lambda:*",
"apigateway:*",
"dynamodb:*",
"iam:PassRole",
"iam:GetRole",
"iam:CreateRole",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:TagRole",
"iam:UntagRole",
"logs:*",
"s3:*",
"cognito-idp:CreateUserPool",
"cognito-idp:CreateUserPoolClient",
"cognito-idp:DescribeUserPool",
"cognito-idp:DeleteUserPool"
],
"Resource": "*"
}
- Add per-user note isolation (by storing notes with userId from Cognito token)
- Implement full CRUD (currently only create/get)
- Input validation
- CI/CD pipeline with GitHub Actions