A practical guide to understanding and using AWS Cognito — from what it actually does to how to set up authentication for your applications and what it will cost you.
Building authentication from scratch is one of those things that sounds straightforward until you are actually doing it. Password hashing, token management, session handling, multi-factor authentication, account recovery, rate limiting login attempts — each piece is individually manageable but together they form a significant surface area for bugs and security vulnerabilities. AWS Cognito exists to handle all of that for you, so you can focus on building your application rather than rebuilding authentication infrastructure that already exists.
Cognito is Amazon's managed authentication and user management service. At its core it gives you a user directory — a place to store user accounts, manage passwords, and handle the entire sign-up and sign-in flow — along with a set of tokens your application can use to verify who a user is and what they are allowed to do. You do not store passwords yourself; Cognito stores them securely. You do not write the login flow; Cognito provides it, either through a hosted UI or through an API your own UI can call.
Cognito has two main components that are worth understanding as separate things. User Pools are for authentication — they store your users, manage their credentials, and issue tokens when a user successfully signs in. Identity Pools, sometimes called Federated Identities, are for authorization — they let authenticated users (from a User Pool or from external identity providers like Google or Facebook) obtain temporary AWS credentials so they can access AWS services directly, like reading from an S3 bucket or calling a Lambda function. The two components can be used together or independently depending on what your application needs.
For most web and mobile applications, User Pools are the part you interact with first. You create a User Pool, configure it with your password requirements and sign-up settings, and then integrate it into your application. Users can sign up with an email address and password, verify their email, sign in, reset their password, and enable MFA — all without you writing any of that logic yourself.
Cognito also supports federated identity — letting users sign in with an existing account from Google, Apple, Facebook, Amazon, or any SAML 2.0 or OpenID Connect provider. This is the feature that powers "Sign in with Google" buttons. You configure the external provider in Cognito, and Cognito handles the OAuth flow and maps the external identity to a user in your User Pool.
Setting up Cognito starts in the AWS Management Console. The process for creating a User Pool walks you through a series of configuration decisions: how users sign in (email, phone number, or a username they choose), what your password policy looks like, whether email verification is required, whether MFA is optional or mandatory, and how the hosted UI should look if you want Cognito to serve the login page for you.
Once your User Pool is created, you create an App Client. An App Client represents an application that is allowed to interact with your User Pool — a web app, a mobile app, a backend service. Each App Client has its own client ID, and optionally a client secret for server-side flows. The App Client configuration controls which OAuth flows are allowed, which scopes can be requested, and which URLs are permitted as redirect targets after sign-in.
There are two main ways to integrate Cognito authentication into your application. The first is the hosted UI — Cognito provides a pre-built login page at a URL you configure, and after a successful login it redirects the user back to your application with an authorization code that you exchange for tokens. This approach requires minimal frontend code and handles everything including MFA prompts and password reset flows, but the UI customization is limited to basic colour and logo changes.
The second approach is using the Cognito API directly through one of the AWS SDKs or the Amplify library. You build your own login form, call the Cognito API with the user's credentials, and receive tokens in response. This gives you full control over the user experience but means you are responsible for calling the right API endpoints for each flow — sign-up, confirm registration, sign-in, refresh tokens, forgot password, and so on. The Amplify library wraps these calls in a higher-level interface that many developers find easier to work with than the raw SDK.
After a successful sign-in, Cognito issues three tokens: an ID token containing the user's identity information, an access token used to authorize calls to your APIs, and a refresh token used to obtain new ID and access tokens when they expire. Access and ID tokens are JSON Web Tokens (JWTs) that your backend can validate without calling Cognito — you verify the signature using Cognito's public keys, check the expiry, and extract the claims. This makes token validation fast and does not add a network call on every authenticated request.
Integrating Cognito with API Gateway is a common pattern. You configure an API Gateway authorizer that validates the Cognito access token on incoming requests. If the token is valid, the request goes through to your Lambda function along with the decoded user information. If it is not valid, API Gateway rejects the request with a 401 response before it ever reaches your Lambda. This gives you authentication at the infrastructure level rather than having to write validation code in every function.
Lambda triggers are another feature worth knowing about. Cognito can call a Lambda function at specific points in the authentication flow — before a user signs up, after they confirm their email, after they sign in, when they request a custom challenge. These hooks let you add custom logic: enriching the token with additional claims, blocking sign-ups from certain email domains, sending a welcome email, or implementing a custom MFA flow.
AWS Cognito Getting Started: https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-cognito-user-pools.htmlCognito pricing is based on the number of Monthly Active Users (MAUs) in your User Pool — a user counts as active if they sign in, sign up, refresh a token, or change their password at least once during the month. Users who exist in your pool but do not interact with it during a given month are not counted and do not incur a charge.
The free tier for Cognito User Pools covers 50,000 MAUs per month with no time limit — this is not a twelve-month free tier like some other AWS services, it is permanent. For the vast majority of personal projects and small applications, you will never pay anything for Cognito authentication.
Beyond 50,000 MAUs, the pricing is tiered. For the next 50,000 users (50,001 to 100,000 MAUs) the price is $0.0055 per MAU. From 100,001 to 1,000,000 MAUs the price drops to $0.0046 per MAU, and it continues to decrease at higher tiers. At typical small-to-medium application scale, the cost is low — 100,000 active users per month would cost roughly $275 per month at current rates.
If you use the advanced security features — which include adaptive authentication, compromised credentials detection, and detailed security event logging — there is an additional charge of $0.050 per MAU. These features are optional and off by default. For most applications they are not necessary, but if you are building something where account security is a significant concern they provide real value.
Federated users — people who sign in through an external provider like Google or Facebook via an Identity Pool — are priced differently. The first 50,000 federated users per month are free, and beyond that the cost is $0.015 per MAU. This is separate from the User Pool MAU pricing.
SMS messages for phone number verification and SMS-based MFA have their own cost through Amazon SNS, typically a few cents per message depending on the destination country. If you use email for verification and MFA instead, there is no additional per-message charge beyond the Cognito MAU pricing.
Full pricing details: https://aws.amazon.com/cognito/pricing/Cognito solves a problem that every application with user accounts eventually has to solve: how do you handle authentication securely without building and maintaining the entire system yourself. The answer it offers is a managed user directory with a complete authentication flow, token issuance, and integrations with both AWS services and external identity providers — all within a free tier that covers 50,000 active users per month permanently.
User Pools are the starting point for most use cases. They store your users, handle sign-up and sign-in, issue JWTs, and support MFA, email verification, and password recovery out of the box. Identity Pools extend this by letting authenticated users obtain temporary AWS credentials to access services like S3 or DynamoDB directly from the client — a pattern common in mobile and single-page applications where you want to avoid routing all data through a backend server.
The integration with API Gateway makes Cognito a natural fit for serverless architectures. A Cognito User Pool authorizer on your API Gateway routes rejects unauthenticated requests at the infrastructure level, so your Lambda functions only receive requests from verified users. This is clean, requires minimal code, and scales automatically.
The hosted UI is the fastest path to a working login flow. It handles all the edge cases — MFA prompts, password requirements, email verification — and requires minimal frontend code. The trade-off is limited visual customization. If your application requires a login experience that matches your brand closely, you will likely end up using the Cognito API directly or through Amplify, which gives you full control over the UI while Cognito handles the authentication logic behind it.
Lambda triggers are worth exploring once you have the basics working. The ability to run custom code at specific points in the authentication flow — pre sign-up, post confirmation, pre token generation — opens up patterns that would otherwise require building additional infrastructure. Custom claims in tokens, domain-based sign-up restrictions, and custom MFA challenges are all achievable through triggers without modifying the core authentication flow.
For most projects, Cognito does not require deep expertise to get started — create a User Pool, configure an App Client, pick the hosted UI or call the API from your frontend, and verify tokens in your backend. The complexity scales with your requirements. Simple email-and-password authentication with email verification can be running in under an hour. More advanced configurations involving federated identity, custom triggers, and fine-grained authorization take more time but are well-documented and follow consistent patterns.