Search code examples
amazon-web-servicesamazon-cognitoamazon-ses

Cognito w/ SES Verified Domain Identity Post User Sign Up Error Page Troubleshooting


I've been trying to figure this one out for a while now with no luck.

I have created an AWS Cognito User Pool for my site. For my users, I am using email address as the username. I am using the hosted UI for user Sign Up, Login, etc. I have configured the user pool to use an SES Verified Domain Identity, which is verified, and a made up no-reply@myverifieddomainidentity email address as the sender. The domain identity still is in the email sandbox. Additionally, I have an additional SES Verified Email Identity that I am using to test the Cognito email integration. This email is my personal Gmail address, not an address in the Verified Domain Identity. Both Cognito and SES resources are created in us-west-2.

I am trying to test the sign up process for new users. From my application, the user clicks the Login button, that takes them to the Cognito hosted UI for the login page. I can click the Sign Up button and be presented with the Sign Up form. I fill in the information, using my personal email address, and click the Sign Up button. Then I am redirected to the /error page.

In my Cognito User Pool, I see the user is added, but I never receive the confirmation email. Looking at SES dashboard, it never reports any emails are sent. This tells me the issue is between the Cognito and SES. I cannot find any means of logging of either Cognito or SES to determine why emails are not going out or why I was redirected to the /error page of the Cognito hosted UI. CloudTrail only shows the Cognito events of the pages fetched, not any failures that I can find.

I have setup my SES verified domain for Congito as described in the AWS documentation (https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-email.html#user-pool-email-configure). In step 3, it says that I don't need to give any extra permissions to Cognito (See "To grant permissions to use your Amazon SES configuration"). However, I tried adding an authorization policy to my SES Verified Domain as outline in Step 3 titled "To grant permissions to use the default email functionality", and this also did not work.

I even performed the Sign Up process via the AWS CLI and that returned successfully, but no email was sent.

I have sent successfully simulated test emails from SES with no issue.

I have read any AWS doc, blog and SO posting I could find to help figure this out. I unfortunately cannot create a support ticket with Amazon as this is my personal project and do not pay for that level of service.

I don't believe that I need to setup any MX records for the verified domain as I don't yet plan on ever receiving any emails, just sending. I also shouldn't have to create additional SES Verified Email addresses for the no-reply@myverifieddomainidentity as outlined in the documentation, but I have tried anyways. I also do not believe that I need to be out of the SES sandbox for this to work as long as I am sending emails to Verified Email Identities, but I could be wrong here.

I'm looking for help in figuring this out. It would be nice if there was a way to be able to monitor Cognito and/or SES to determine explicitly why the two are not working together. I don't see any logging options for Cognito other than to send the CloudTrail events to CloudWatch which doesn't seem helpful. For SES, it seems I can add topics to use to monitor bounced emails and such, but that doesn't help me in this scenario as the emails don't seem to be even getting to Cognito. I can't seem to find out why the hosted UI redirected me to the /error page.

Resources were created with Terraform. Posted here so you can see full configuration.

resource "aws_ses_domain_identity" "this" {
  domain = aws_route53_zone.external.name
}

resource "aws_route53_record" "ses_domain_identity_verification_record" {
  zone_id = aws_route53_zone.external.zone_id
  name    = "_ses_domain_identity_verification" # TODO: need full domain name? "_ses_verification_record.${aws_route53_zone.external.name}"
  type    = "CNAME"
  ttl     = "60"
  records = [aws_ses_domain_identity.this.verification_token]
}

resource "aws_ses_domain_dkim" "this" {
  domain = aws_ses_domain_identity.this.domain
}

resource "aws_route53_record" "ses_dkim_verification_record" {
  count = 3 # resource aws_ses_domain_dkim creates 3 tokens

  zone_id = aws_route53_zone.external.id
  name    = "${element(aws_ses_domain_dkim.this.dkim_tokens, count.index)}._domainkey"
  type    = "CNAME"
  ttl     = "1800"
  records = ["${element(aws_ses_domain_dkim.this.dkim_tokens, count.index)}.dkim.amazonses.com"]
}

resource "aws_cognito_user_pool" "this" {
  name = local.project-deployment-name

  admin_create_user_config {
    allow_admin_create_user_only = false
  }

  password_policy {
    minimum_length                   = 8
    require_lowercase                = true
    require_numbers                  = true
    require_symbols                  = true
    require_uppercase                = true
    temporary_password_validity_days = 1
  }

  username_attributes = ["email"]

  # TODO: see https://github.com/hashicorp/terraform-provider-aws/issues/26726
  #  user_attribute_update_settings {
  #    attributes_require_verification_before_update = ["email"]
  #  }

  email_configuration {
    email_sending_account = "DEVELOPER"
    from_email_address    = "no-reply@${aws_ses_domain_identity.this.domain}"
    source_arn            = aws_ses_domain_identity.this.arn
  }

  account_recovery_setting {
    recovery_mechanism {
      name     = "verified_email"
      priority = 1
    }
  }
  
  schema {
    name                = "email"
    attribute_data_type = "String"
    required            = true
    mutable             = true
  }

  schema {
    name                = "name"
    attribute_data_type = "String"
    required            = true
    mutable             = true
  }

  schema {
    name                = "birthdate"
    attribute_data_type = "String"
    required            = true
    mutable             = true
  }
}

Any help is appreciated. Thank you.

EDIT:

I just tried using Cognito with the default email solution using the default email address of no-reply@verificationemail.com , and I just experienced the same behavior, so the issue may not be between Cognito and SES but with Cognito itself. Hosted UI redirected to error page, user was added to the user pool, and no email was received.


Solution

  • Corrected Answer:

    I realize my issue was actually with not having a value set for auto_verified_attributes set. I wasn't understanding the purpose of that setting correctly. Adding the following configuration to my aws_cognito_user_pool resource above, resolved my specific issue.

    auto_verified_attributes = ["email"] 
    

    Previous Answer:

    So it turns out that the issue was in front of me but not obvious at all.

      # TODO: see https://github.com/hashicorp/terraform-provider-aws/issues/26726
      #  user_attribute_update_settings {
      #    attributes_require_verification_before_update = ["email"]
      #  }
    

    Not having the "Attribute verification and user account confirmation" feature enabled completely breaks the sign up process. I didn't even consider this to be the cause as 1) this is a new feature and I would suspect that signup process prior to this feature would be functional and 2) it's an optional feature.

    I never did find any good means of determining why the users where redirected to the error page during the sign up process. I suspect the only real way to find out is to submit a ticket with AWS. I only discovered this by desperately tweaking configuration until something worked.

    Hopefully this will help someone else that finds themselves in a similar situation.