When I try to login using AWS Cognito I get an AccessDeniedException about my custom Lambda trigger

This was happening because I recreated my API Gateway & Lambdas (using serverless) and it turns out that the Cognito console sneakily adds permissions to contact a given Lambda function when added as a trigger through the console.


To fix this in your CloudFormation / serverless.yml file:

resources:
  Resources:
    OnCognitoSignupPermission:
      Type: 'AWS::Lambda::Permission'
      Properties:
        Action: "lambda:InvokeFunction"
        FunctionName:
          Fn::GetAtt: [ "UsersUnderscoreonCognitoSignupLambdaFunction", "Arn"]
        Principal: "cognito-idp.amazonaws.com"
        SourceArn:
          Fn::Join: [ "", [ "arn:aws:cognito-idp", ":", Ref: "AWS::Region", ":", Ref: "AWS::AccountId", ":", "userpool/", "@cognito_pool_id@" ] ]

To fix this in the AWS console:

  • Go to the Cognito Console
  • Choose your user pool
  • Go to "Triggers"
  • Remove your custom trigger (set it to None) and click "Save"
  • Now reset it back and click "Save" again

Here's an interesting Amazon forum post that led me down the right track.


I had a problem similar to yours except I was trying to configure the Lambda with my Cognito User Pool through CloudFormation.

In the link that Ryan had posted there was a code sample someone posted. Namely Cognito needed the proper permissions to invoke the lambda function.

MyLambdaInvocationPermission:
  Type: AWS::Lambda::Permission
  Properties:
    Action: lambda:InvokeFunction
    FunctionName: !GetAtt MyLambdaFunctionName.Arn
    Principal: cognito-idp.amazonaws.com
    SourceArn: !GetAtt MyCognitoUserPoolName.Arn

For someone ending up here, trying to add cognito triggers via terraform, all you need to do is to add an aws_lambda_permission resource:

resource "aws_lambda_permission" "allow_execution_from_user_pool" {
  statement_id = "AllowExecutionFromUserPool"
  action = "lambda:InvokeFunction"
  function_name = aws_lambda_function.<lambda>.function_name
  principal = "cognito-idp.amazonaws.com"
  source_arn = aws_cognito_user_pool.<pool>.arn
}

Found in this great post: https://www.integralist.co.uk/posts/cognito/