Skip to content

Instantly share code, notes, and snippets.

@singledigit
Last active April 28, 2024 15:12
Show Gist options
  • Save singledigit/2c4d7232fa96d9e98a3de89cf6ebe7a5 to your computer and use it in GitHub Desktop.
Save singledigit/2c4d7232fa96d9e98a3de89cf6ebe7a5 to your computer and use it in GitHub Desktop.
Create a Cognito Authentication Backend via CloudFormation
AWSTemplateFormatVersion: '2010-09-09'
Description: Cognito Stack
Parameters:
AuthName:
Type: String
Description: Unique Auth Name for Cognito Resources
Resources:
# Creates a role that allows Cognito to send SNS messages
SNSRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "cognito-idp.amazonaws.com"
Action:
- "sts:AssumeRole"
Policies:
- PolicyName: "CognitoSNSPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action: "sns:publish"
Resource: "*"
# Creates a user pool in cognito for your app to auth against
# This example requires MFA and validates the phone number to use as MFA
# Other fields can be added to the schema
UserPool:
Type: "AWS::Cognito::UserPool"
Properties:
UserPoolName: !Sub ${AuthName}-user-pool
AutoVerifiedAttributes:
- phone_number
MfaConfiguration: "ON"
SmsConfiguration:
ExternalId: !Sub ${AuthName}-external
SnsCallerArn: !GetAtt SNSRole.Arn
Schema:
- Name: name
AttributeDataType: String
Mutable: true
Required: true
- Name: email
AttributeDataType: String
Mutable: false
Required: true
- Name: phone_number
AttributeDataType: String
Mutable: false
Required: true
- Name: slackId
AttributeDataType: String
Mutable: true
# Creates a User Pool Client to be used by the identity pool
UserPoolClient:
Type: "AWS::Cognito::UserPoolClient"
Properties:
ClientName: !Sub ${AuthName}-client
GenerateSecret: false
UserPoolId: !Ref UserPool
# Creates a federeated Identity pool
IdentityPool:
Type: "AWS::Cognito::IdentityPool"
Properties:
IdentityPoolName: !Sub ${AuthName}Identity
AllowUnauthenticatedIdentities: true
CognitoIdentityProviders:
- ClientId: !Ref UserPoolClient
ProviderName: !GetAtt UserPool.ProviderName
# Create a role for unauthorized acces to AWS resources. Very limited access. Only allows users in the previously created Identity Pool
CognitoUnAuthorizedRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Federated: "cognito-identity.amazonaws.com"
Action:
- "sts:AssumeRoleWithWebIdentity"
Condition:
StringEquals:
"cognito-identity.amazonaws.com:aud": !Ref IdentityPool
"ForAnyValue:StringLike":
"cognito-identity.amazonaws.com:amr": unauthenticated
Policies:
- PolicyName: "CognitoUnauthorizedPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "mobileanalytics:PutEvents"
- "cognito-sync:*"
Resource: "*"
# Create a role for authorized acces to AWS resources. Control what your user can access. This example only allows Lambda invokation
# Only allows users in the previously created Identity Pool
CognitoAuthorizedRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Federated: "cognito-identity.amazonaws.com"
Action:
- "sts:AssumeRoleWithWebIdentity"
Condition:
StringEquals:
"cognito-identity.amazonaws.com:aud": !Ref IdentityPool
"ForAnyValue:StringLike":
"cognito-identity.amazonaws.com:amr": authenticated
Policies:
- PolicyName: "CognitoAuthorizedPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "mobileanalytics:PutEvents"
- "cognito-sync:*"
- "cognito-identity:*"
Resource: "*"
- Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource: "*"
# Assigns the roles to the Identity Pool
IdentityPoolRoleMapping:
Type: "AWS::Cognito::IdentityPoolRoleAttachment"
Properties:
IdentityPoolId: !Ref IdentityPool
Roles:
authenticated: !GetAtt CognitoAuthorizedRole.Arn
unauthenticated: !GetAtt CognitoUnAuthorizedRole.Arn
Outputs:
UserPoolId:
Value: !Ref UserPool
Export:
Name: "UserPool::Id"
UserPoolClientId:
Value: !Ref UserPoolClient
Export:
Name: "UserPoolClient::Id"
IdentityPoolId:
Value: !Ref IdentityPool
Export:
Name: "IdentityPool::Id"
@patrickfoley
Copy link

This was super helpful (I was stuck on IdentityPoolRoleMapping and the two IAM roles - this got me over that hump). Thanks so much!

@multiojuice
Copy link

This is great -- thanks :_)

@ecv-raphaeljambalos
Copy link

Big help, thanks man!

@frank-liu
Copy link

Hey @singledigit that helped a lot!
Quick question: Do you know how to allow users to use an email address or phone number as their “username” to sign up and sign in using through Cloudformation template?
cognito

    [
      
    ](https://user-images.githubusercontent.com/5882081/28852186-b055b6d6-76fd-11e7-9916-40e6e0b50377.gif)
    
        ![cognito](https://user-images.githubusercontent.com/5882081/28852186-b055b6d6-76fd-11e7-9916-40e6e0b50377.gif)
      
    
      
        
          
        
        
          
          
        
      
      [
        
          
        
      ](https://user-images.githubusercontent.com/5882081/28852186-b055b6d6-76fd-11e7-9916-40e6e0b50377.gif)

use this below and put it under properties UsernameAttributes: - email AutoVerifiedAttributes: - emai

UsernameAttributes:
- phone_number
- email

@bannarisoftwares
Copy link

bannarisoftwares commented Oct 31, 2022

How to add custom read and write attributes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment