Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cognito user pools - support SES integration #6768

Closed
nija-at opened this issue Mar 17, 2020 · 37 comments · Fixed by #17117
Closed

cognito user pools - support SES integration #6768

nija-at opened this issue Mar 17, 2020 · 37 comments · Fixed by #17117
Assignees
Labels
@aws-cdk/aws-cognito Related to Amazon Cognito effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p1

Comments

@nija-at
Copy link
Contributor

nija-at commented Mar 17, 2020

AWS Docs to the feature: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-email.html#user-pool-email-developer

CloudFormation properties: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cognito-userpool-emailconfiguration.html


This is a 🚀 Feature Request

@nija-at nija-at added feature-request A feature should be added or improved. @aws-cdk/aws-cognito Related to Amazon Cognito labels Mar 17, 2020
@nija-at nija-at self-assigned this Mar 17, 2020
@nija-at nija-at added the effort/medium Medium work item – several days of effort label Mar 18, 2020
@rehanvdm
Copy link

+1

@tom139
Copy link
Contributor

tom139 commented Apr 7, 2020

Hi, I did some research I would like to share:
There are 3 possible sender configuration:

  • default emails are sent from noreply@verificationemail.com and there is the ability to set the replyTo property only;
  • Cognito sender: this allow to specify a custom sender address (via a verified identity in SES) and set the from field (with both email and name);
  • SES sender: this has the same properties as the above cognito sender plus the ability to set a ConfigurationSet to better track sent emails.

The default should be initiable with empty props:

let sender = new DefaultSender({
  replyTo?: "replyToAddress",
});

If the user wish to use cognito must specify all required fields

let emailSender = new CognitoSender({
  from: {
    email: "testaddress@example.com",
    name: "Test Address",
  },
  replyTo: "info@example.com"
  sourceArn: "arn for source"
});

Finally, if the user wants to use SES the user can specify the optional configurationSet property.

let emailSender = new SESSender({
  configurationSet?: "String"
  from: {
    email: "testaddress@example.com",
    name: "Test Address",
  },
  replyTo: "info@example.com"
  sourceArn: "arn for source"
});

As you can see I propose to split the From property in two, allowing better check of correctness (and helping the user understand how to use the field.

/**
 * Represents the From field.
 * If only email is set the output value should be the email address, otherwise
 * the outcome should be `name <email>` (i.e. Test User `<testuser@acme.com>`)
 */
export interface FromEmailAddress {
    /**
     * The email for the From field.
     *
     * @example testuser@example.com
     */
    readonly email: string

    /**
     * The optional sender's name
     *
     * @example Test User
     */
    readonly name?: string
}

To Do

  • check if some role is created and if cdk should perform some operation (e.g. to allow Cognito to use the identity specified in SourceArn);
  • check if some SES resource could be used to auto populate some fields in Cognito and SES senders:
    • CfnConfigurationSet could be accepted in the configurationSet property

I will start working soon on a PR.

@asterikx
Copy link
Contributor

asterikx commented May 31, 2020

Is it possible to import/lookup the sourceArn of a verified email address by its name, e.g. verified@exmaple.com?

Edit: Since the ARN has always the structure arn:aws:ses:${this.region}:${this.account}:identity/${fromEmail}, there is no need to look it up.

Ideally, it should be possible to specify any "from" email, and, if unverified, cdk deploy triggers verification and blocks until the user has received and confirmed the verification email (similarly to the DnsCertificate construct).

@rinde
Copy link

rinde commented Jul 2, 2020

Is there a reason why this issue is not marked as required for graduation in this overview? According to the Cognito limits that come with the default settings, maximum 50 emails can be sent per day, severely limiting the number of people that can use my service. Therefore, I think this is an important feature to have in the CDK.

Is there currently a workaround for a UserPool that is configured using the CDK high level constructs to enable email sending via SES? Or is the only way to rewrite my stack using the lower level CloudFormation constructs for UserPool?

@asterikx
Copy link
Contributor

asterikx commented Jul 2, 2020

@rinde The workaround is quite easy.

Just change the emailConfiguration by modifying the CFN resource encapsulated by the CDK UserPool construct (see CDK Developer Guide here):

const cfnUserPool = userPool.node.defaultChild as cognito.CfnUserPool;

cfnUserPool.emailConfiguration = {
  emailSendingAccount: 'DEVELOPER',
  from: `Someone from MyService <${fromEmailAddress}>`,
  sourceArn: `arn:aws:ses:eu-west-1:${this.account}:identity/${fromEmailAddress}`, // SES integration is only available in us-east-1, us-west-2, eu-west-1
};

I agree that these SES configurations should be added to the CDK construct since almost every customer-facing app requires SES instead of Cognito's built-in email capabilities.

Note that the sending email address (fromEmailAddress above) must be verified in SES (see SES Developer Guide) and the SES account must be moved out of the SES Sandbox to send emails to unverified email addresses (your customers). See the SES Developer Guide here and here for more details.

@gregorypierce
Copy link

I'd specifically like Pinpoint integration. If I've already got a Pinpoint app, I already have a MANAGED mechanism to send emails, texts, etc. I wouldn't want to create a new channel to support Cognito "just because".

@nija-at
Copy link
Contributor Author

nija-at commented Aug 14, 2020

As far as I can tell, Pinpoint is an analytics system. This issue is regarding sending emails and integrating SES with user pools. Please open a separate issue, if you're interested in a different feature.

@gregorypierce
Copy link

I'll open a different issue, but Pinpoint isn't (specifically) an analytics system. It's an aggregation of all the messaging channels for SMS, Voice, Email, Push Notifications, Messaging campaigns, etc. It's closer to Mailchimp than it is anything specifically related to analytics.

@apoorvmote
Copy link

Is there any workaround for adding custom cloudformation include for ses support?

I was learning cloudformation but when I found out about CDK then I abandoned cloudformation and completely forgot everything I learned about cloudformation. I am actually looking for excuse to actually finish learning cloudformation.

But if I learned cloudformation then can I fill gaps of CDK? or I cannot override CDK code with custom cloudformation?

@wichert
Copy link

wichert commented Dec 31, 2020

@asterikx Your workaround only works if you use TypeScript as far as I can see? I don't see how you can do the same thing from Python.

@straygar
Copy link

straygar commented Jan 4, 2021

@wichert Please check the docs on Escape Hatches for how to modify the CFN layer in other CDK languages. :)

@Elegie
Copy link

Elegie commented Jan 5, 2021

Hello. I've tried using @asterikx 's workaround, but it seems to require one of the following regions: us-east-1, us-west-2, eu-west-1. I think it might be a hard-coded obsolete check, because SES is now available in other regions as well (I'm working in ap-southeast-1 (Singapore), where SES has been made available since summer '20).

Is there another workaround? I'm working with the latest version of CDK, and don't know about Cloudformation (yet). Cheers.

@asterikx
Copy link
Contributor

asterikx commented Jan 5, 2021

@Elegie While SES is available in many regions, Cognito integration with SES is only supported in us-east-1, and us-west-2, eu-west-1, AFAIK.

The English docs state:

Available regions for Amazon SES are US East (N. Virginia)us-east-1, US West (Oregon) us-west-2, and Europe (Ireland)eu-west-1.

The German docs has additional information:

Available regions for Amazon SES are US East (N. Virginia)us-east-1, US West (Oregon) us-west-2, and Europe (Ireland)eu-west-1. Amazon SES does not support receiving emails in the following regions: Asia Pacific (Mumbai), Asia Pacific (Sydney), Canada (Central), Europe (Frankfurt), Europe (London), South America (São Paulo), and AWS GovCloud (USA).

So, I guess, you will need to use one of us-east-1, us-west-2, or eu-west-1 to be able to receive emails (which is important for bounces). I'm guessing here, though.

@misterjoshua
Copy link
Contributor

Hello. I've tried using @asterikx 's workaround, but it seems to require one of the following regions: us-east-1, us-west-2, eu-west-1. I think it might be a hard-coded obsolete check, because SES is now available in other regions as well (I'm working in ap-southeast-1 (Singapore), where SES has been made available since summer '20).

Is there another workaround? I'm working with the latest version of CDK, and don't know about Cloudformation (yet). Cheers.

@Elegie Unless you're restricted by some other policy, you can set up a sender identity in one of those supported regions and use it from a user pool in a different region. But, you'll need to make sure you have SES production access in the SES region.

Here's what I've done in my case - my user pool is in ca-central-1, but I'm using an SES sender identity in us-east-1.
image

@Elegie
Copy link

Elegie commented Jan 14, 2021

Hi @misterjoshua and @asterikx , thanks for your comments. I have access to all regions in my context, so have set up Cognito and SES as you two suggested. I could not test it yet, but given that it was correctly provisioned by Cloudformation I'm rather confident it'll work. I think it's a very reasonable solution. Cheers.

@grouchal
Copy link

grouchal commented Mar 4, 2021

👍

@douglasnaphas
Copy link
Contributor

@misterjoshua I have attempted to use the workaround from @asterikx using your advice.

My from-address is in us-east-1, a supported region for SES integration. My Cognito user pool is in us-west-1.

I am getting the following error when I cdk deploy:

Invalid EmailConfiguration.SourceArn. Provided SourceArn must be in the us-west-1 SES region. (Service: AWSCognitoIdentityProviderService; Status Code: 400; Error Code: InvalidParameterException;

My from-address is not yet enabled for production sending, but I would not expect that to lead to this error.

The portion of my code in lib/ where I attempt to implement the workaround is:

    let cfnUserPool;
    if (props?.sesVerificationConfig) {
      cfnUserPool = userPool.node.defaultChild as cognito.CfnUserPool;
      cfnUserPool.emailConfiguration = {
        emailSendingAccount: "DEVELOPER",
        from: `Mad Liberation Verification <${props?.sesVerificationConfig?.fromAddress}>`,
        sourceArn:
          // SES integration is only available in us-east-1, us-west-2, eu-west-1
          `arn:aws:ses:${props?.sesVerificationConfig?.fromRegion}` +
          `:${this.account}:identity/` +
          `${props?.sesVerificationConfig?.fromAddress}`,
      };
    }

props.sesVerificationConfig.fromRegion is us-east-1.

@misterjoshua, @asterikx, or others, any insight into how I might resolve this error would be greatly appreciated.

@misterjoshua
Copy link
Contributor

@misterjoshua, @asterikx, or others, any insight into how I might resolve this error would be greatly appreciated.

@douglasnaphas Haha. This problem is a little slippery. I did manage to get something to deploy in us-west-1, but not with a cross-region sender identity.

new cognito.CfnUserPool(this, 'UserPool', {
  emailConfiguration: {
    emailSendingAccount: 'DEVELOPER',
    // Verified email address instead of domain sender identity.
    sourceArn: 'arn:aws:ses:us-west-1:11111111111111:identity/xxxx@xxxxxxxxx.com',
    from: 'My email <xxxx@xxxxxxxxx.com>',
  },
});

This is what it's looking like in the user pool in us-west-1:

image

@viventra
Copy link

viventra commented Mar 11, 2021

@wichert Please check the docs on Escape Hatches for how to modify the CFN layer in other CDK languages. :)

I am trying to specify SES configuration in CDK in C#.NET.

            var cfnUserPool = userPool.Node.DefaultChild as CfnUserPool;
            cfnUserPool.EmailConfiguration = new Amazon.CDK.CfnResource(this, "userPoolEmailConfig", new Amazon.CDK.CfnResourceProps() {
                Type = "AWS::Cognito::UserPool.EmailConfiguration",
                Properties = new Dictionary<string, object> {
                    ["EmailSendingAccount"] = "DEVELOPER",
                    ["From"] = $"Support <{support_email}>",
                    ["SourceArn"] = $"arn:aws:ses:{this.Region}:{this.Account}:identity/{support_email}"
                }
            });

But, I get the following error:

D:\src\Api>cdk deploy
Unhandled exception. Amazon.JSII.Runtime.JsiiException: Resolution error: Resolution error: Unable to resolve object tree with circular reference. Path: /Resources/${Token[ApiStack.userpool.Resource.LogicalID.1042]}/Properties/emailConfiguration/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node/host/node..
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()

   ... (repetitions elided) ...

   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.Invoke(InvokeRequest request)
   at Amazon.JSII.Runtime.Services.Client.Invoke(ObjectReference objectReference, String method, Object[] arguments)
   at Amazon.JSII.Runtime.Deputy.DeputyBase.<>c__DisplayClass17_0`1.<InvokeInstanceMethod>b__1(IClient client, Object[] args)     
   at Amazon.JSII.Runtime.Deputy.DeputyBase.<InvokeMethodCore>g__GetResult|18_0[T](<>c__DisplayClass18_0`1& )
   at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeMethodCore[T](JsiiMethodAttribute methodAttribute, Object[] arguments, Func`3 beginFunc, Func`3 invokeFunc)
   at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeInstanceMethod[T](Type[] parameterTypes, Object[] arguments, String methodName) 
   at Amazon.CDK.Stage.Synth(IStageSynthesisOptions options)
   at Api.Program.Main(String[] args) in D:\src\Api\Program.cs:line 14
Subprocess exited with error 3762504530

Please help. Also, my REGION is ap-south-1. The verified email Arn is

arn:aws:ses:{this.Region}:{this.Account}:identity/{support_email}

Should I be verifying the email address with SES in one of the SES integration supported regions (say us-west-2) in addition to verifying it in ap-south-1 and use the ARN of the us-west-2 verified address?

@viventra
Copy link

viventra commented Mar 11, 2021

I figured it out. I used the Amazon.CDK.AWS.Cognito.CfnUserPool.EmailConfigurationProperty type.

        const string sesRegion = "us-west-2";

        cfnUserPool.EmailConfiguration = new Amazon.CDK.AWS.Cognito.CfnUserPool.EmailConfigurationProperty() {
            EmailSendingAccount = "DEVELOPER",
            From = $"Support <{support_email}>",
            SourceArn = $"arn:aws:ses:{sesRegion}:{this.Account}:identity/{support_email}"
        };

Also, note the sesRegion coded to use a supported SES region.

@mikerudge
Copy link

+1

1 similar comment
@sdeby
Copy link

sdeby commented Apr 15, 2021

+1

@BinyominCohen
Copy link

+1

@spifd
Copy link

spifd commented Jul 20, 2021

If you would like this to be implemented, give this issue a +1. Until then, you can use the cfn layer to configure this.

+1

@ghost
Copy link

ghost commented Jul 29, 2021

+1

3 similar comments
@alehatsman
Copy link

+1

@guzmonne
Copy link

+1

@vramanlal
Copy link

+1

@bykka
Copy link

bykka commented Sep 12, 2021

+1

6 similar comments
@OuFinx
Copy link

OuFinx commented Sep 16, 2021

+1

@myron-semack
Copy link

+1

@mavarazy
Copy link

+1

@giomarino
Copy link

+1

@am-cc
Copy link

am-cc commented Oct 14, 2021

+1

@mavarazy
Copy link

+1

@jinmingtng
Copy link

+1

@mergify mergify bot closed this as completed in #17117 Nov 15, 2021
mergify bot pushed a commit that referenced this issue Nov 15, 2021
add support for SES integration by introducing a new property for
configuring email settings for a user pool. This feature supports both
types of integration with SES.

1. Using the COGNITO_DEFAULT sending account, but providing a custom
   email address
2. Using the DEVELOPER sending account

This feature does not automate any configuration on SES since that is
not currently possible with CloudFormation and requires a manual
verification step. To use the SES integration introduced in this feature
the user will have had to already configured a verified email address in
Amazon SES and followed the steps outlined here:
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-email.html

closes #6768

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

mpvosseller pushed a commit to mpvosseller/aws-cdk that referenced this issue Nov 16, 2021
add support for SES integration by introducing a new property for
configuring email settings for a user pool. This feature supports both
types of integration with SES.

1. Using the COGNITO_DEFAULT sending account, but providing a custom
   email address
2. Using the DEVELOPER sending account

This feature does not automate any configuration on SES since that is
not currently possible with CloudFormation and requires a manual
verification step. To use the SES integration introduced in this feature
the user will have had to already configured a verified email address in
Amazon SES and followed the steps outlined here:
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-email.html

closes aws#6768

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
TikiTDO pushed a commit to TikiTDO/aws-cdk that referenced this issue Feb 21, 2022
add support for SES integration by introducing a new property for
configuring email settings for a user pool. This feature supports both
types of integration with SES.

1. Using the COGNITO_DEFAULT sending account, but providing a custom
   email address
2. Using the DEVELOPER sending account

This feature does not automate any configuration on SES since that is
not currently possible with CloudFormation and requires a manual
verification step. To use the SES integration introduced in this feature
the user will have had to already configured a verified email address in
Amazon SES and followed the steps outlined here:
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-email.html

closes aws#6768

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-cognito Related to Amazon Cognito effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p1
Projects
None yet
Development

Successfully merging a pull request may close this issue.