Sending Transactional Email From Auth0 with AWS SES

Tutorial

As I’ve written ad nauseum, I’m working on a web application that uses Auth0 to manage user authentication. It’s a fantastic service that’s relatively easy to try out. They even manage all of the emails one of your users would need to get, like confirming their email address, resetting a password, etc.

While an app is in development the Auth0 email service can be used, but to put an app into production, they require you to use your own email provider. I recently set this up with AWS SES, so for future reference here are the steps I took.

Why SES?

Currently, Auth0 is integrated with a small handful of email providers which you can link to your account: Mandrill, SendGrid, SparkPost, and Amazon Web Services’ Simple Email Service (which, now you can understand why I will refer to it as SES going forward!).

You can also use SMTP credentials to send from any other service or email provider that allows this. This includes free providers like Gmail or Yahoo!Mail, but there are a few reasons I discovered why using free email isn’t likely to be very successful:

  1. You may have to change your email account settings to allow less secure apps to access it. Not a great solution—what’s to stop an app other than Auth0 from doing this?
  2. If you do choose to change this setting, the email provider may still block Auth0 from sending emails on your behalf until you confirm that it wasn’t a fraudulent action. I changed the setting, confirmed it wasn’t fraud and successfully sent emails from my Gmail account one day…two days later it flagged the emails again, even so. Going in to verify that Auth0’s emails are legit every few days isn’t a good permanent solution!
  3. Using an email address from your own domain (that is, hello@mycoolcompany.com instead of mycoolcompany@yahoo.com) leaves a much better impression anyway!

So that leaves the paid services, which—for a tiny-for-now app like mine—makes SES the obvious choice. Each has a free trial tier, but once you hit a certain level of sending, the pricing jumps dramatically (starting from $15/month) for all of the providers except SES. By contrast, SES lets you send more emails for pennies, and scales up or down depending on your sending volume. So while all of these providers are built with the ability to scale (as in tens of thousands of emails being sent per day), AWS is the only option on this list with a simple, non-committal, entry-level option.

Now, I use the word ‘simple’ with a grain of salt! As with most things in AWS land, there is a learning curve.

How To Set It Up

The Auth0 docs lay out a step-by-step guide for doing this. I’ll go through each of their steps with some added info about what you actually have to do to connect SES through SMTP:

1. Sign up for an Amazon AWS account, or login.

Actually this is pretty straightforward. Here is a pretty easy guide to follow.

2. Verify your domain.

This step requires some familiarity with your DNS provider. In the SES dashboard, click the ‘Verify new domain’ button at the top, and then enter the domain name. It will then generate a Domain Verification Record which needs to be added as a record in your DNS settings.

The Amazon docs include some instruction on this, and for understanding DKIM records I found the Protonmail docs to be useful.

3. Request production access - THE WRENCH!

New SES accounts can only send email to verified email addresses…not very useful for sending emails to newly signed up users (how will you pre-verify them!?). So you need to get production access granted in SES, which allows you to send emails to any email address.

While the instructions are quite clear, the form you have to fill out to request this access is not! What should I ask for my limit to be? And what constitutes a ‘good’ process to handle bounces and complaints? What is a complaint anyway?? This really felt like overkill given all I wanted to do what let Auth0 send account setup emails to people who requested it.

Well whatever I answered, I got it wrong—my request was rejected after a 36-hour wait:

Thank you for contacting the Amazon SES team. Unfortunately, we cannot grant you a sending limit increase because it does not seem like you have a process in place to handle bounces and complaints. …

Some research showed that this happens to other people too, and for seemingly harmless requests. In any case, I tried to address their concern which led down another rabbit hole…

Long story short, I roped in another AWS service—Simple Notification Service (SNS)—to email me if there are any email bounces or complaints. Their docs helped when setting this up. Then I wrote back to AWS to say I’d done this:

Thank you for explaining how I can gain production access for the SES service. At your suggestion I have added notifications via SNS for bounces and complaints. On receipt these email addresses will be removed and no future emails will be sent to them. To confirm this service is in use for transactional application emails (sign-up confirmation, reset password) which require a voluntary double opt-in. An unsubscribe link is included in the footer of each email as required by law.

After another 36-hour wait, they finally approved!

Thank you for submitting your request to increase your sending limits. Your new sending quota is 50,000 messages per day. Your maximum send rate is now 14 messages per second. We have also moved your account out of the Amazon SES sandbox. …

So several days later, I could finally move on to the next steps…

4. Get Your SMTP Credentials.

You can actually do this before getting production access granted, but there’s little point if the emails won’t go through. Thankfully it’s much simpler than the previous step.

After the wait, back in the SES dashboard, navigate to SMTP settings then click Create My SMTP Settings. Copy the server from the dashboard page, and take note of the username and password that get generated.

5. Share these credentials with Auth0

Back in the Auth0 dashboard, copy and paste these details into the SMTP Provider Settings fields. Some tips:

  • To get emails to show up from a name instead of just the email address, include a name before the email in angle brackets in the From field: My Company Name <hello@mycompany.com>
  • Port: I picked 587

Save it and send a test email. Hopefully it works!

Why not AWS API credentials?

I started down this route initially and it led to setting up new IAM users and permission policies and key generation. No thanks.

A Note On Email Hosting

An assumption I’ve made in writing this is that you already have email hosting set up on your domain. I didn’t actually have that before I started this process, so here are some things I learned about this:

You do need email hosting.

Many domain providers will allow you to set up email forwarding for ‘aname@mycooldomain.com’ so that you can receive emails without having full-blown email hosting, but this isn’t actually enough. There are a lot of email hosts out there with costs that vary quite a bit. In the end I decided to use ProtonMail because:

  1. I already use it for my personal email.
  2. They prioritize privacy and security, which I appreciate.
  3. It’s less expensive on an annual basis than most of the other email hosts I researched.

That said, I view this as a temporary solution…ProtonMail may not actually be the best choice in the long run for a few reasons:

  1. Currently, you can only add a domain to one ProtonMail account—if you ever want someone else to manage an account on the same domain, you’ll need to grant them access to your account.
  2. The daily sending limit for the most basic paid account is not very high.

For comparison, other popular email hosting choices include G Suite, Zoho Mail, AWS WorkMail, RackSpace, and AtMail. Do with this information what you will when selecting your host!

…And It Means More DNS Configuration

This may be an extra annoyance if you prefer not to spend time doing devops stuff. ProtonMail has some very good step-by-step documentation for verifying the domain and setting up SPF and DKIM records. As a result I didn’t find it too painful…this may be something to research when making a choice alongside service & pricing.

Conclusion (with 25 days’ hindsight)

This ended up being a much more arduous process than felt necessary, and the “simplicity” of setting up SES probably contributes to why the other email service providers are able to charge as much as they do. As often turns out to be the case with AWS, if time is short and money is not an object it’s probably easier to get started with one of the other email providers instead of SES.

That said, since initially setting this up, I’ve started looking into marketing email providers to send email updates, and that’s yet another cost to add onto the pile, once your volume gets big enough. In the end—partially due to the fact that I’ve already gone through this whole SES process— I was able to choose Email Octopus (that’s a referral link!), a reputable and well-reviewed service that charges lower rates since they sit on top of your own SES account. So…in the end, it’s a win!