Skip to content
intermediate Phase 9 · AWS Advanced Services

Cognito Authentication

Add user authentication and authorization with Amazon Cognito.

1h
0 problems
Topic Progress 0%

Cognito User Pools

Cognito User Pools

Cognito User Pools are user directories that provide sign-up and sign-in functionality.

Create User Pool

# Create user pool
aws cognito-idp create-user-pool \
  --pool-name my-user-pool \
  --policies '{
    "PasswordPolicy": {
      "MinimumLength": 12,
      "RequireUppercase": true,
      "RequireLowercase": true,
      "RequireNumbers": true,
      "RequireSymbols": true
    }
  }' \
  --auto-verified-attributes email \
  --username-attributes email \
  --mfa-configuration ON \
  --enabled-mfas SOFTWARE_TOKEN_MFA

# Create app client
aws cognito-idp create-user-pool-client \
  --user-pool-id us-east-1_xxxxx \
  --client-name my-app \
  --explicit-auth-flows ALLOW_USER_PASSWORD_AUTH ALLOW_REFRESH_TOKEN_AUTH \
  --generate-secret

User Pool Features

Feature Description
Sign-up Self-registration with verification
Sign-in Username/email/phone authentication
MFA SMS or TOTP multi-factor authentication
Password Policy Configurable complexity requirements
Social Login Google, Facebook, Apple integration
SAML/OIDC Enterprise federation

User Pool Schema

# Add custom attributes
aws cognito-idp create-user-pool \
  --pool-name my-pool \
  --schema '[{
    "Name": "custom:department",
    "AttributeDataType": "String",
    "Mutable": true,
    "Required": false
  }, {
    "Name": "custom:role",
    "AttributeDataType": "String",
    "Mutable": true,
    "Required": false
  }]'

Authentication Flows

Authentication Flows

Sign-Up

import boto3

client = boto3.client('cognito-idp')

# Sign up
response = client.sign_up(
    ClientId='your-client-id',
    Username='user@example.com',
    Password='SecurePass123!',
    UserAttributes=[
        {'Name': 'email', 'Value': 'user@example.com'},
        {'Name': 'name', 'Value': 'John Doe'}
    ]
)

# Confirm sign up
client.confirm_sign_up(
    ClientId='your-client-id',
    Username='user@example.com',
    ConfirmationCode='123456'
)

Sign-In

# User password authentication
response = client.initiate_auth(
    ClientId='your-client-id',
    AuthFlow='USER_PASSWORD_AUTH',
    AuthParameters={
        'USERNAME': 'user@example.com',
        'PASSWORD': 'SecurePass123!'
    }
)

# Get tokens
id_token = response['AuthenticationResult']['IdToken']
access_token = response['AuthenticationResult']['AccessToken']
refresh_token = response['AuthenticationResult']['RefreshToken']

# Refresh tokens
response = client.initiate_auth(
    ClientId='your-client-id',
    AuthFlow='REFRESH_TOKEN_AUTH',
    AuthParameters={
        'REFRESH_TOKEN': refresh_token
    }
)

Password Recovery

# Forgot password
response = client.forgot_password(
    ClientId='your-client-id',
    Username='user@example.com'
)

# Confirm forgot password
client.confirm_forgot_password(
    ClientId='your-client-id',
    Username='user@example.com',
    ConfirmationCode='123456',
    Password='NewSecurePass123!'
)

Cognito Identity Pools

Cognito Identity Pools

Identity pools provide temporary AWS credentials for accessing AWS services.

Create Identity Pool

# Create identity pool
aws cognito-identity create-identity-pool \
  --identity-pool-name my-identity-pool \
  --allow-unauthenticated-identities false \
  --cognito-identity-providers '[{
    "ProviderName": "cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxx",
    "ClientId": "your-client-id",
    "ServerSideTokenCheck": true
  }]'

# Set IAM roles for authenticated users
aws cognito-identity set-identity-pool-roles \
  --identity-pool-id us-east-1:xxxxx \
  --roles '{
    "authenticated": "arn:aws:iam::xxx:role/CognitoAuthenticatedRole",
    "unauthenticated": "arn:aws:iam::xxx:role/CognitoUnauthenticatedRole"
  }'

IAM Role for Authenticated Users

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:xxxxx"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    }
  ]
}

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-bucket/${cognito-identity.amazonaws.com:sub}/*"
    }
  ]
}

Cognito Triggers

Cognito Triggers

Lambda triggers customize authentication flows.

Pre Sign-Up Trigger

# Validate email domain before sign-up
def lambda_handler(event, context):
    email = event['request']['userAttributes']['email']
    domain = email.split('@')[1]
    
    allowed_domains = ['company.com', 'partner.com']
    if domain not in allowed_domains:
        raise Exception('Email domain not allowed')
    
    return event

Post Confirmation Trigger

# Create user profile after confirmation
def lambda_handler(event, context):
    user_id = event['userName']
    email = event['request']['userAttributes']['email']
    
    # Create user in DynamoDB
    dynamodb = boto3.client('dynamodb')
    dynamodb.put_item(
        TableName='Users',
        Item={
            'UserId': {'S': user_id},
            'Email': {'S': email},
            'CreatedAt': {'S': datetime.now().isoformat()}
        }
    )
    
    return event

Available Triggers

Trigger When
Pre Sign-Up Before user registration
Post Confirmation After email confirmation
Pre Authentication Before login
Post Authentication After login
Custom Message Customizing messages
Define Auth Challenge Custom authentication
Verify Auth Challenge Custom challenge verification
Token Generation After token creation

Cognito Security and Best Practices

Cognito Security and Best Practices

Security Configuration

# Enable advanced security
aws cognito-idp update-user-pool \
  --user-pool-id us-east-1_xxxxx \
  --user-pool-add-ons '{
    "AdvancedSecurityMode": "ENFORCED"
  }'

# Enable compromised credentials check
aws cognito-idp update-user-pool \
  --user-pool-id us-east-1_xxxxx \
  --user-pool-add-ons '{
    "AdvancedSecurityMode": "ENFORCED"
  }'

# Configure account takeover protection
aws cognito-idp update-user-pool \
  --user-pool-id us-east-1_xxxxx \
  --user-pool-add-ons '{
    "AdvancedSecurityMode": "ENFORCED"
  }'

Integration with API Gateway

# Configure Cognito authorizer
aws apigateway create-authorizer \
  --rest-api-id abc123 \
  --name CognitoAuthorizer \
  --type COGNITO_USER_POOLS \
  --provider-arns arn:aws:cognito-idp:us-east-1:xxx:userpool/us-east-1_xxxxx \
  --identity-source method.request.header.Authorization

# Protect API methods
aws apigateway update-method \
  --rest-api-id abc123 \
  --resource-id xyz789 \
  --http-method GET \
  --patch-operations 'op=replace,path=/authorizationType,value=COGNITO_USER_POOLS' 'op=replace,path=/authorizerId,value=xxx'

Best Practices

  1. Enable MFA for all users
  2. Use strong password policies
  3. Enable advanced security features
  4. Use Lambda triggers for custom validation
  5. Monitor with CloudWatch
  6. Use token validation on protected endpoints
  7. Implement refresh token rotation
  8. Use attribute-based access control (ABAC)

Pricing

Feature Cost
Monthly Active Users (MAU) First 50K free, then $0.0055/MAU
Advanced Security $0.05/MAU
SMS Standard SMS rates
Federated Identities First 50K free