Brian Zimmel
Brian Zimmel

Reputation: 134

CloudFormation template for Cognito gets NotAuthorizedException error

I am having trouble creating a stack with my CloudFormation template. When it reaches the IdentityPoolRoleAttachment I get the error:

Access to Role 'CognitoIdentityUnauthenticated' is forbidden. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: NotAuthorizedException; Request ID: 0866b3a1-15ab-11e9-82dd-1b30dc4a6a4d)

I've matched everything to what was created through the console and cannot figure out the problem. Can anyone see what I might be missing?

AWSTemplateFormatVersion: 2010-09-09
Description: AWS Script to create Cognito User and Identity pools

Resources:
  CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: cognito-userpool
      Schema:
        - Name: email
          AttributeDataType: String
          Mutable: false
          Required: true
      Policies:
        PasswordPolicy:
          MinimumLength: 8
          RequireLowercase: true
          RequireNumbers: true
          RequireUppercase: true
  CognitoUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      ClientName: cognito-app-client
      ExplicitAuthFlows:
        - ADMIN_NO_SRP_AUTH
      GenerateSecret: false
      ReadAttributes:
        - email
      RefreshTokenValidity: 30
      UserPoolId: !Ref CognitoUserPool
  CognitoIdentityPool:
    Type: AWS::Cognito::IdentityPool
    Properties:
      IdentityPoolName: cognito_identity_pool
      AllowUnauthenticatedIdentities: true
      CognitoIdentityProviders:
        - ClientId: 
            Ref: CognitoUserPoolClient
          ProviderName:
            Fn::GetAtt: 
            - CognitoUserPool
            - ProviderName

  CognitoIdentityAuthenticatedRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: CognitoIdentityAuthenticated
      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: CognitoIdentityPool
              "ForAnyValue:StringLike":
                "cognito-identity.amazonaws.com:amr": authenticated

  CognitoIdentityUnauthenticatedRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: CognitoIdentityUnauthenticated
      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: CognitoIdentityPool
              "ForAnyValue:StringLike":
                "cognito-identity.amazonaws.com:amr": unauthenticated

  # Create policy to allow authenticated user role to invode API lambda function
  CognitoAuthInvokeLambdaPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: CognitoAuthInvokeLambdaPolicy
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
          - mobileanalytics:PutEvents
          - cognito-sync:*
          - cognito-identity:*
          Resource: 
          - "*"
        - Effect: Allow
          Action:
          - execute-api:Invoke
          Resource:
          - "arn:aws:execute-api:us-east-1:*:xxxxxxxxxx/*"
        - Effect: Allow
          Action: 
          - "s3:*"
          Resource: 
          - "*"
      Roles:
        - Ref: CognitoIdentityAuthenticatedRole

  # Create policy to allow unauthenticated user role (currently only has access to Cognito - add additional resources if needed)
  CognitoUnauthPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: CognitoUnauthPolicy
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
          - mobileanalytics:PutEvents
          - cognito-sync:*
          - cognito-identity:*
          Resource: 
          - "*"
      Roles:
        - Ref: CognitoIdentityUnauthenticatedRole

  # Assigns the role to the Identity Pool
  CognitoIdentityPoolRoleMapping:
    Type: "AWS::Cognito::IdentityPoolRoleAttachment"
    Properties:
      IdentityPoolId: !Ref CognitoIdentityPool
      Roles:
        authenticated: !Ref CognitoIdentityAuthenticatedRole
        unauthenticated: !Ref CognitoIdentityUnauthenticatedRole


#Output IDs and ARNs
Outputs:
  CognitoUserPoolID:
    Value: 
      Ref: CognitoUserPool
    Export:
      Name: !Sub "${AWS::StackName}-CognitoUserPoolID"
  CognitoUserPoolClientID:
    Value:
      Ref: CognitoUserPoolClient
    Export:
      Name: !Sub "${AWS::StackName}-CognitoUserPoolClientID"
  CognitoIdentityPoolID:
    Value:
      Ref: CognitoIdentityPool
    Export:
      Name: !Sub "${AWS::StackName}-CognitoIdentityPoolID"

I see a similar question posted but no answer was provided: Access to Role 'cognito role' is forbidden

Upvotes: 0

Views: 756

Answers (1)

Brian Zimmel
Brian Zimmel

Reputation: 134

I figured it out. The unauthenticated role needs the Arn and not the logical ID.

  CognitoIdentityPoolRoleMapping:
    Type: "AWS::Cognito::IdentityPoolRoleAttachment"
    Properties:
      IdentityPoolId: !Ref CognitoIdentityPool
      Roles:
        authenticated: !GetAtt CognitoIdentityAuthenticatedRole.Arn
        unauthenticated: !GetAtt CognitoIdentityUnauthenticatedRole.Arn

Upvotes: 1

Related Questions