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

16,778

Solution 1

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.

Solution 2

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

Solution 3

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/

Share:
16,778
Ryan Shillington
Author by

Ryan Shillington

This is my next start-up. I'm very excited about it: QbDVision by CherryCircle Software, Inc. Find me on LinkedIn: https://www.linkedin.com/in/ryanshillington/

Updated on June 06, 2022

Comments

  • Ryan Shillington
    Ryan Shillington almost 2 years

    I am calling adminInitiateAuth and getting back a strange AccessDeniedException for my own lambdas.

    Here is the code I'm calling:

          var params = {
            AuthFlow: "ADMIN_NO_SRP_AUTH",
            ClientId: "@cognito_client_id@",
            UserPoolId: "@cognito_pool_id@",
            AuthParameters: {
              USERNAME : username,
              PASSWORD : tempPassword
            },
          };
          cognitoIdentityServiceProvider.adminInitiateAuth(params, function(error, data) {
            if (error) {
              console.log("ERROR! Login failed: " + JSON.stringify(error), error.stack);
            } else {
              console.log("Login sent back: " + JSON.stringify(data));
            }
          });
    

    The error message I'm getting is:

    ERROR! Login failed: {"message":"arn:aws:lambda:us-east-1:201473124518:function:main-devryan-users_onCognitoLogin failed with error AccessDeniedException.","code":"UnexpectedLambdaException","time":"2017-02-25T18:54:15.109Z","requestId":"ce42833f-fb8b-11e6-929b-2f78b63faa12","statusCode":400,"retryable":false,"retryDelay":1.0853444458916783} UnexpectedLambdaException: arn:aws:lambda:us-east-1:201473124518:function:main-devryan-users_onCognitoLogin failed with error AccessDeniedException.
    

    Does anybody know why I might be getting this error?

  • Nirojan Selvanathan
    Nirojan Selvanathan over 5 years
    Thanks, Saved my Day !
  • wascou
    wascou over 5 years
    Thanks, this was what was missing.
  • Adam B
    Adam B over 5 years
    You, good sir, have saved my sanity today! Had done exactly the same (i.e. using serverless) and this fixed it.
  • Prince Antony P
    Prince Antony P over 5 years
    Worked like charm,...Thank you
  • Ciryon
    Ciryon over 5 years
    This is crazy. Also, the drift detection feature for Cloud Formation templates cannot see any difference after re-saving the trigger.
  • DenisH
    DenisH over 5 years
    Yup it took me ages to get to the same conclusion. Just add the permission under Resources. I set the SourceArn to arn:aws:cognito-idp:<your region>:<your account>:userpool/* so as to give access to all our pools.
  • Ryan Shillington
    Ryan Shillington over 5 years
    I updated my answer to include the changes we made to get it working in CloudFormation. Kudos to @shanewwarren's answer below (although honestly we'd figured it out a few months before he posted his answer).
  • Randy L
    Randy L about 5 years
    I agree with @Ciryon this IS crazy and AWS apparently hates its customers.
  • Randy L
    Randy L about 5 years
    If anybody else is setting Cognito up using Terraform, there's an open issue around the lambda permissions.
  • Ciryon
    Ciryon almost 5 years
    @the0ther I wonder if AWS scans Stack Overflow with sentiment analysis and picks up comments like ours. :)
  • David Ben Ari
    David Ben Ari over 4 years
    Hey you all, I get this error after deploying the cloud formation with amplify-cli, I have tried to add this kind of permission all sorts of places and in many other formats as well, they never where deployed. does anyone know in which cloud formation template and where exactly should this permission be placed to be deployed successfully ?
  • David Ben Ari
    David Ben Ari over 4 years
    Hey you all, I get this error after deploying the cloud formation with amplify-cli, I have tried to add this kind of permission all sorts of places and in many other formats as well, they never where deployed. does anyone know in which cloud formation template and where exactly should this permission be placed to be deployed successfully ?
  • C.K Munn
    C.K Munn over 4 years
    You sir are nothing short of a gee nee uss. Just to add I used FunctionName: "my-function-name" without the .Arn
  • snehanshu.js
    snehanshu.js almost 4 years
    Although my solution was different, still, you're such a lifesaver!
  • badfun
    badfun over 3 years
    Still relevant. The documentation is really confusing around Cognito triggers. thanks!
  • Emil Styrke
    Emil Styrke almost 3 years
    This error is completely unrelated to the OP - it indicates that the user running cloudformation does not have access to create the Cognito User Pool.
  • fmquaglia
    fmquaglia almost 3 years
    Sir, if I could upvote this answer twice, I would do it. Stumbled with the same problem like 1 year after I upvoted it and here I am, giving you again my appreciation. thanks a lot, again!