AWS Cognito is widely used to simplify authentication and authorization for web and mobile applications. It offers built-in features like:
- User sign-up
- User sign-in
- Access control
- Integration with social and enterprise identity providers
When users sign up for an application, Cognito stores their credentials and sends a confirmation email or text message to verify their identity.
However, in most real-world applications, we use Cognito primarily for authentication and authorization. To support other app features — like user profiles or business logic — we often need to store user data in a separate database, such as DynamoDB.
The Problem: How to Store User Data in DynamoDB?
By default, Cognito stores user information in its own user pool. But if we want to save that data in DynamoDB (e.g., to power user profiles or dashboards), we need to transfer it after the user confirms their account.
The Solution: Use the Post-Confirmation Lambda Trigger
The post-confirmation trigger is a Lambda function that executes after a user confirms their email or phone number. This ensures we only store verified users in our database — avoiding clutter and unnecessary storage for unverified sign-ups.
Hands-on Guide
Let’s walk through the steps to automatically create user data in DynamoDB after a successful sign-up confirmation.
Step 1: Update the DynamoDB schema
We’ll use the Amplify Gen 2 schema definition to create a UserProfile model in our project.
// \amplify\auth\resource.tsconst schema = a .schema({// UserProfile: a .model({ id: a.id().required(), // Cognito User Sub as the ID firstName: a.string(), lastName: a.string(), email: a.string().required() }) .authorization((allow) => [allow.authenticated()]), //only authenticated users can access data //}) .authorization((allow) => [ allow.resource(postConfirmation) ]);
Step 2: Create post-confirmation handler file
Next, we’ll write the Lambda function that runs when a user confirms their email.
// amplify\auth\post-confirmation\handler.tsimport type { PostConfirmationTriggerHandler } from 'aws-lambda';import { type Schema } from '../../data/resource';import { Amplify } from 'aws-amplify';import { generateClient } from 'aws-amplify/data';import { getAmplifyDataClientConfig } from '@aws-amplify/backend/function/runtime';import { env } from '$amplify/env/post-confirmation';const { resourceConfig, libraryOptions } = await getAmplifyDataClientConfig(env);Amplify.configure(resourceConfig, libraryOptions);const client = generateClient<Schema>();export const handler: PostConfirmationTriggerHandler = async (event) => { const userId = event.request.userAttributes.sub; const firstName = event.request.userAttributes.given_name; const lastName = event.request.userAttributes.family_name; const email = event.request.userAttributes.email; await client.models.UserProfile.create({ id: userId, firstName, lastName, email }); return event;};
// amplify\auth\post-confirmation\resource.tsimport { defineFunction } from '@aws-amplify/backend';export const postConfirmation = defineFunction({ name: 'post-confirmation',});
Step 3: Update schema file importing post-confirmation function
In here we set access for Post confirmation Lambda function to the *DynamoDB *schema.
// \amplify\data\resource.tsimport { postConfirmation } from '../auth/post-confirmation/resource';//const schema = a .schema({// UserProfile: a .model({ id: a.id().required(), // Cognito User Sub as the ID firstName: a.string(), lastName: a.string(), email: a.string().required() }) .authorization((allow) => [allow.authenticated()]), //only authenticated users can access data //}) .authorization((allow) => [ allow.resource(postConfirmation) // add access to the dynamodb schema ]);
Step 4: Update the auth/resource file
We have to update the auth/resource.ts file by adding Post confirmation function as a trigger
// \amplify\auth\resource.tsimport { defineAuth } from '@aws-amplify/backend';import { postConfirmation } from './post-confirmation/resource';//export const auth = defineAuth({//triggers: { postConfirmation,}//})
That’s It!
Now, whenever a user signs up and confirms their email or phone number, the post-confirmation Lambda will be triggered, and their details will be stored in DynamoDB automatically.