Configuring an Intermediary Domain for DKIM
As an email service provider (ESP), there are many different priorities and considerations that you’re factoring – especially when starting out – and one of the most important is for your customers to have an easy onboarding experience. You want customers to successfully set up their integration with your platform with as few barriers as possible, and you want these messages to perform well so that your customers have as positive of an experience as possible when sending through your platform.
The Challenge: Striking a Balance Between Customer Set-Up and Customer Success
One of the factors that will affect whether your customers’ first messages are successfully delivered, and affect whether their first impression with your platform is positive, is for the messages to properly authenticate with DKIM. Messages that fail DKIM authentication, or that don’t DKIM sign the messages at all, are more likely to be placed in the spam folder or be rejected by the mailbox provider – especially if the sending domain has DMARC configured.
A concern I frequently hear from email service providers is that they worry their customers are not familiar enough with DNS and that configuring DKIM records may be confusing for them. Others worry that onboarding may become burdensome, and adoption may be affected if they have to get the DKIM record from SparkPost, provide it to their customer, wait for the customer to update DNS, and then the customer may proceed with onboarding. These ESPs want:
- Their customer to be able to use their own domain when sending messages through the platform for brand alignment
- To implement an easily understood onboarding process with as few steps as possible
- To ensure the messages successfully pass DKIM upon delivery for the best customer experience
With SparkPost, creating a frictionless onboarding experience for your customers can be accomplished by using an intermediary domain that you manage, which your customers then CNAME to. This allows for a streamlined setup process that’s consistent for each customer and can be easily documented, communicated in advance, and performed in parallel with other onboarding steps.
How to Configure an Intermediary Domain for DKIM
When configuring your SparkPost account to take advantage of an intermediary domain for DKIM signing, the following steps can be taken:
- Generate a private and public key pair to use. The same key pair used by the intermediary domain will need to be used for the customer domains. Since the private key is not accessible for SparkPost-generated key pairs (as private keys should remain private), you will need to generate your own key pair.
- Add the intermediary domain into your SparkPost account using the API, and pass the private and public key pair in the API call. Note that you will need to include the “dkim” object in the API payload to add the key pair and the selector. The selector can be any value, but in the below example I’ve used “scph0421”.
- Add the DKIM record to DNS for your intermediary domain as a TXT record.
- Verify the intermediary domain within your SparkPost account either through the UI or by using the verify API endpoint.
- Create a CNAME record on the customer domain that points to the DKIM record of the intermediary domain. Note that the hostname of the CNAME record will need to have a DKIM format (<selector>._domainkey.*).
- Add the customer domain to your SparkPost account with the API using the same private/public key pair as the intermediary domain.
- Verify the customer domain using the /verify API endpoint.
An Intermediary Domain for DKIM Example
The following is an example of configuring an intermediary domain for DKIM on SparkPost, and using CNAME records to add customer domains.
Intermediary domain: intermediary.trymsys.net
Sending (customer) domain: customer.trymsys.net
- First, I created a 1024 bit private and public key pair using openssl with the following commands:
- Private Key:
openssl genrsa -out private.key 1024
- Public Key:
openssl rsa -in private.key -pubout -out public.keyFirst, I created a 1024 bit private and public key pair using openssl with the following commands:
- Private Key:
- Then I added the intermediary domain (intermediary.trymsys.net) to my SparkPost account using the key pair. Within DNS, I created the DKIM TXT record at the hostname domainkey hostname (scph0421._domainkey.intermediary.trymsys.net) and verified within SparkPost, as shown below:
- The domain in SparkPost:
- The DKIM record in DNS:
- Next, I created a CNAME record (scph0421._domainkey.customer.trymsys.net) that points to the DKIM record of the intermediary domain (scph0421._domainkey.intermediary.trymsys.net), as can be seen in DNS:
- Finally, I added the customer domain (customer.trymsys.net) to my SparkPost account using the same DKIM key pair as the intermediary domain and verified it:
This enables me to send a message from customer.trymsys.net. As can be seen in the message headers, the customer domain (customer.trymsys.net) was used for both the From address, as well as for DKIM signing:
Is There an Easier Way?
I’m glad you asked! I’ve created a Python application that will generate the private and public key pair, store your key pair locally, and add your intermediary domain to your SparkPost account. The application will also add your customer domains to your SparkPost account using the private and public key pair that was created for the intermediary domain.
When your customer is onboarding with your sending platform, you can tell them as part of your set-up instructions that they should create a CNAME record that points to your intermediary domain, as described in the steps above. If your customer creates the CNAME record ahead of time, you can immediately verify your customer’s domain on your SparkPost account. Alternatively, you can add your customer’s domain to your SparkPost account first, and once your customer has updated their DNS with the CNAME record, you can then run “verifyDomain” which will verify your customer’s domain within your SparkPost account.
Your customer can now successfully send messages and pass DKIM using their domain.
A Discussion for Advanced Users
One benefit of adding your intermediary domain to your SparkPost account is that SparkPost will format the DNS record for you; however, some users may be comfortable with formatting their own DNS records. For those users who are comfortable with creating their own DKIM TXT records, you can technically support the intermediary domain model without adding the intermediary domain to your SparkPost account. You can simply create the TXT records in DNS and have your customer domains CNAME to the DNS record as described above. In this scenario, you’ll still need to add the customer domains to your SparkPost account using the same private and public key pair used for the intermediary domain, but it will save you the step of adding the domain to your SparkPost account. The examples in this post add the intermediary domain to SparkPost for simplicity, to make it easier for readers to visualize the steps that are being taken, and to take advantage of SparkPost formatting the DNS record.
Additionally, the python application described above can be modified to generate a 2048-bit key pair for a more secure DKIM signature. One important note for those interested in implementing a 2048-bit key pair is that the DKIM TXT record within DNS will need to be split due to a character limit in DNS. SparkPost can support a 2048-bit key pair, but SparkPost will not generate the split TXT record – the record will need to be manually split.
One possible enhancement to the python application would be for the application to generate the DNS records that will be needed. This would support users who wish to skip the step of adding their intermediary domain to their SparkPost account. This enhancement would also segue nicely into another enhancement to support 2048-bit key pairs, where the application would then provide the split TXT records that need to be added to DNS. These enhancements will be saved for a future post.
Set Up Sending Customers for Success
In conclusion, using an intermediary domain for DKIM enables a customer to successfully send from your platform using their domain with only one step – add a CNAME record pointing to a predetermined domain. This can be implemented into your onboarding process by communicating to your customers in advance that they should create the CNAME record.
E.g.: Add CNAME xyz._domainkey.<your.domain> that points to xyz._domainkey.<platform.domain>.
All of your customers will have the same record to create, which means it can be configured at any time, and with minimal impact to your customer’s overall onboarding experience.
I’d be interested to hear any suggestions or issues that you may have for future enhancements.