intermediate~2h

Amazon Cognito

Managed user authentication and identity for your applications — sign-up, sign-in, and temporary AWS credentials for end users, without building auth infrastructure yourself.

Want a visual for this topic?

Generate a diagram tailored to Amazon Cognito — the AI picks whichever visual (architecture, flowchart, ER diagram, etc.) best fits this specific AWS concept.

Sign in to generate a visual →
1
Subtopics

🎓 Learning objectives

  • Explain the difference between a Cognito User Pool and an Identity Pool
  • Explain how Cognito issues and validates JWTs for authenticated API calls
  • Explain how federated (social/enterprise) sign-in works with Cognito
  • Explain when an application needs an Identity Pool in addition to a User Pool

What is it?

Amazon Cognito is a managed service for adding user sign-up, sign-in, and access control to applications. It has two distinct components: User Pools, which are user directories handling authentication (proving who a user is), and Identity Pools, which grant temporary, scoped AWS credentials to authenticated (or even anonymous) users, allowing them to directly call AWS services like S3.

Why it exists

Building secure user authentication from scratch — password hashing, account recovery flows, multi-factor authentication, protection against credential-stuffing attacks, session token management — is genuinely hard to get right, and getting it wrong has serious security consequences. Cognito exists to give applications production-grade, secure authentication as a managed service, so application teams don't need to become security/auth specialists to launch a product with real user accounts.

Problem it solves

User Pools solve the 'who is this user' problem (secure sign-up/sign-in, password policies, MFA, account recovery, and federated sign-in with Google/Facebook/enterprise SAML/OIDC providers, all handled by Cognito rather than custom code). Identity Pools solve the 'what can this user directly do in AWS' problem (issuing temporary, scoped IAM credentials so a mobile app's authenticated user can, for example, upload directly to a specific S3 prefix without the request routing through your backend at all).

Intuition

A User Pool is like a building's front desk that checks ID and issues a visitor badge (proving who you are). An Identity Pool is like a separate system that, once you've shown that valid visitor badge, hands you a specific set of temporary keys that open exactly the doors you're allowed through (temporary AWS permissions) — two related but genuinely different concerns, proving identity versus granting access.

Analogy

Think of a corporate campus: badging in at the front gate (User Pool authentication) proves who you are and gets you a valid badge. That badge then determines, at each individual door across the campus (an Identity Pool granting scoped AWS access), which specific rooms you're actually allowed to enter — the front gate and the individual door locks are two separate systems working together.

Technical explanation

A User Pool issues three JSON Web Tokens (JWTs) upon successful authentication: an ID token (containing user identity claims, meant for your application to read), an Access token (meant for authorizing calls to your own backend APIs, e.g. validated by API Gateway's JWT authorizer), and a Refresh token (used to obtain new ID/Access tokens without requiring the user to log in again). An Identity Pool maps an authenticated User Pool identity (or an unauthenticated/guest identity, if enabled) to a specific IAM role via AWS STS's AssumeRoleWithWebIdentity, issuing temporary credentials scoped to exactly what that role permits — commonly configured so each user can only access their own prefix within a shared S3 bucket, enforced via IAM policy variables referencing the authenticated user's unique Cognito identity ID.

Architecture

A photo-sharing mobile app uses a Cognito User Pool for account sign-up/sign-in (including Google and Apple federated sign-in options), issuing JWTs the app's backend API (behind API Gateway with a Cognito/JWT authorizer) validates on every request. For photo uploads specifically, the app instead uses an Identity Pool to get temporary AWS credentials scoped (via an IAM policy referencing the Cognito identity ID) to only the current user's own folder in a shared S3 bucket, letting uploads go directly device-to-S3 without passing through the backend at all, reducing backend load and upload latency.

Workflow

  1. Create a User Pool, configure sign-up attributes, password policy, MFA settings, and any federated identity providers (Google, Facebook, SAML/OIDC enterprise IdPs) needed. 2) Integrate your application's sign-up/sign-in UI with the User Pool (via Cognito's hosted UI, or the SDK for a fully custom UI). 3) Protect backend APIs (typically via API Gateway) using a JWT authorizer validating User Pool tokens. 4) If the application needs to call AWS services directly from the client (not just your backend), create an Identity Pool, link it to the User Pool, and define IAM roles for authenticated (and optionally unauthenticated/guest) access.

Example

A fitness tracking app's mobile client authenticates users via a Cognito User Pool with email/password and Google sign-in options. The app's backend API validates the resulting JWTs on every request via API Gateway's Cognito authorizer. Separately, an Identity Pool grants each authenticated user temporary credentials scoped to read/write only their own workout data files in a shared S3 bucket (enforced by an IAM policy using ${cognito-identity.amazonaws.com:sub} as a dynamic path segment), letting the mobile app upload workout GPS data directly to S3 without that traffic going through the backend.

Real-world usage

Cognito is AWS's standard recommendation for adding authentication to mobile and web applications built on AWS, extensively documented in AWS's serverless application reference architectures; the User Pool plus API Gateway JWT authorizer pattern is a very common combination for securing serverless APIs without building custom authentication infrastructure.

Trade-offs

Using Cognito's hosted UI is the fastest path to a working sign-up/sign-in flow but offers limited visual customization; building a fully custom UI against the Cognito SDK gives complete control over the user experience but is significantly more implementation work. Using an Identity Pool to let clients call AWS services directly reduces backend load and latency for specific operations, but means some access-control logic now lives in IAM policies rather than centrally in your backend code, which some teams find harder to reason about and audit compared to funneling everything through backend-enforced authorization.

Visual explanation

Picture a mobile app's sign-up/sign-in screen talking to a Cognito User Pool, which returns JWTs (an ID token proving identity, an access token for calling your own backend APIs, and a refresh token) upon successful authentication. If the app also needs to call AWS services directly (e.g. uploading a photo straight to S3 from the device), it exchanges its Cognito User Pool tokens with an Identity Pool, which returns temporary AWS credentials (via STS) scoped by an IAM role, letting the app make signed AWS API calls directly, with no backend server in that specific path at all.

Advantages

  • Production-grade authentication (password policies, MFA, account recovery, federated sign-in) without building it from scratch

  • Native integration with API Gateway (JWT authorizer) and IAM (via Identity Pools) removes significant custom integration code

  • Identity Pools let client applications call AWS services directly with properly scoped, temporary credentials, reducing backend load for specific operations like file uploads

  • Supports federated sign-in with major social providers and enterprise SAML/OIDC identity providers out of the box

Disadvantages

  • The distinction between User Pools and Identity Pools is a common source of confusion for teams new to Cognito, since they solve genuinely different problems that are easy to conflate

  • Customizing the hosted UI beyond basic branding has real limitations, pushing many teams toward building a fully custom UI against the SDK instead

  • JWT token expiration and refresh logic needs to be correctly handled client-side, and mishandling it causes confusing session-expiry bugs

  • Complex custom authentication flows (e.g. very specific MFA requirements) sometimes require Lambda triggers, adding real implementation complexity beyond the out-of-the-box configuration

Common mistakes

  • Using an Identity Pool without a User Pool (or another identity provider) when the application genuinely needs to know who a specific user is, not just grant generic authenticated-or-anonymous AWS access

  • Confusing the ID token and Access token's intended purposes — using the ID token to authorize backend API calls when the Access token is the one designed for that purpose

  • Not scoping Identity Pool IAM roles tightly enough, granting authenticated users broader AWS access than their specific use case (e.g. direct S3 upload) actually requires

  • Hardcoding or mismanaging token refresh logic client-side, causing users to be unexpectedly logged out or hitting expired-token errors mid-session

  • Building custom authentication logic that duplicates what Cognito already handles securely (password hashing, MFA, brute-force protection) instead of using Cognito's built-in capabilities

In the AWS Console

  1. 1

    AWS Console → Cognito → User pools → Create user pool

    Configure sign-in options (email, username, phone), password policy, MFA requirements, and add any federated identity providers (Google, Apple, SAML) needed.

    Enable MFA at least optionally for any production application handling sensitive user data — it's a low-effort, high-value security improvement.

  2. 2

    Cognito → User pools → [your pool] → App integration → Create app client

    Create an app client representing your specific application (web or mobile), configuring allowed OAuth flows and callback URLs if using the hosted UI.

    Do NOT generate a client secret for a mobile or single-page web application — client secrets can't be kept confidential in those environments and public clients should be configured without one.

  3. 3

    AWS Console → Cognito → Identity pools → Create identity pool

    Link it to your existing User Pool as an authentication provider, and configure the IAM role that authenticated users will assume.

    Scope the authenticated role's IAM policy tightly — commonly using policy variables like ${cognito-identity.amazonaws.com:sub} to restrict each user to only their own resources within a shared bucket or table.

  4. 4

    API Gateway → [your API] → Authorization → Create authorizer → JWT

    Point the JWT authorizer at your Cognito User Pool's issuer URL, and attach it to routes needing authentication.

    This validates the Access token (not the ID token) by default — confirm your client is sending the correct token type in the Authorization header.

🎤 Interview questions

What's the difference between a Cognito User Pool and an Identity Pool? (Listen for: User Pool handles authentication — who the user is, sign-up/sign-in, issues JWTs; Identity Pool grants temporary AWS credentials to authenticated (or anonymous) users for directly calling AWS services.)

What are the three tokens a Cognito User Pool issues, and what's each used for? (Listen for: ID token — identity claims for the app; Access token — authorizing calls to backend APIs; Refresh token — obtaining new tokens without re-login.)

Why would a mobile app need an Identity Pool in addition to a User Pool? (Listen for: to call AWS services directly from the device — e.g. uploading straight to S3 — with properly scoped temporary credentials, rather than routing every such call through a backend server.)

How would you ensure each user can only access their own files in a shared S3 bucket via an Identity Pool? (Listen for: an IAM policy on the authenticated role using a policy variable like ${cognito-identity.amazonaws.com:sub} to dynamically scope the resource path to that specific user's identity.)

What security capabilities does Cognito provide out of the box that a team would otherwise have to build themselves? (Listen for: secure password hashing/storage, MFA, account recovery flows, brute-force/credential-stuffing protections, federated social/enterprise sign-in.)

📂 Subtopics

💬 Deep Dive with AI

Related concepts

iam-fundamentalsapi-gatewaykms-encryption

Next Step

Continue to AWS WAF & Shield