How can I rotate my access keys for an existing Amazon SES SMTP IAM user?

Last updated: 2021-02-18

I want to rotate my Amazon Simple Email Service (Amazon SES) Simple Mail Transfer Protocol (SMTP) credentials in AWS Identity and Access Management (IAM). How can I create a user name and password that's compatible with Amazon SES?

Resolution

Access keys that you create in the IAM console for an SMTP user don't work with the Amazon SES SMTP interface. The keys generated in the IAM console are in a different format than the format required for the credentials that you need for Amazon SES SMTP servers.

To set up credentials for the Amazon SES SMTP interface, do one of the following:

Create new Amazon SES SMTP credentials

1.    Use the Amazon SES console to create new Amazon SES SMTP credentials.

2.    After you get the new credentials, you can choose to delete the existing Amazon SES credentials in IAM if you don't need them.

Convert your existing secret access key into the Amazon SES SMTP format

Note: You must use Python 3 or later versions with the following steps.

1.    Update the existing IAM user's policy to grant permission for ses:SendRawEmail at minimum.

2.    Copy the Python code for converting a secret access key into an Amazon SES SMTP password.

3.    Paste the Python code into a text editor, and then save the file as seskey.py.

4.    To run the Python script, use the following command:
For --secret, enter your existing secret access key. Then, enter a space and the AWS Region where you're using the SMTP password.

python3 seskey.py --secret YOURKEYrrpg/JHpyvtStUVcAV9177EAKKmDP37P us-east-1

5.    The script outputs a new secret access key that you can use with Amazon SES:

#!/usr/bin/env python3

import hmac
import hashlib
import base64
import argparse

SMTP_REGIONS = [
    'us-east-2',       # US East (Ohio)
    'us-east-1',       # US East (N. Virginia)
    'us-west-2',       # US West (Oregon)
    'ap-south-1',      # Asia Pacific (Mumbai)
    'ap-northeast-2',  # Asia Pacific (Seoul)
    'ap-southeast-1',  # Asia Pacific (Singapore)
    'ap-southeast-2',  # Asia Pacific (Sydney)
    'ap-northeast-1',  # Asia Pacific (Tokyo)
    'ca-central-1',    # Canada (Central)
    'eu-central-1',    # Europe (Frankfurt)
    'eu-west-1',       # Europe (Ireland)
    'eu-west-2',       # Europe (London)
    'sa-east-1',       # South America (Sao Paulo)
    'us-gov-west-1',   # AWS GovCloud (US)
]

# These values are required to calculate the signature. Do not change them.
DATE = "11111111"
SERVICE = "ses"
MESSAGE = "SendRawEmail"
TERMINAL = "aws4_request"
VERSION = 0x04


def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()


def calculate_key(secret_access_key, region):
    if region not in SMTP_REGIONS:
        raise ValueError(f"The {region} Region doesn't have an SMTP endpoint.")

    signature = sign(("AWS4" + secret_access_key).encode('utf-8'), DATE)
    signature = sign(signature, region)
    signature = sign(signature, SERVICE)
    signature = sign(signature, TERMINAL)
    signature = sign(signature, MESSAGE)
    signature_and_version = bytes([VERSION]) + signature
    smtp_password = base64.b64encode(signature_and_version)
    return smtp_password.decode('utf-8')


def main():
    parser = argparse.ArgumentParser(
        description='Convert a Secret Access Key for an IAM user to an SMTP password.')
    parser.add_argument(
        'secret', help='The Secret Access Key to convert.')
    parser.add_argument(
        'region',
        help='The AWS Region where the SMTP password will be used.',
        choices=SMTP_REGIONS)
    args = parser.parse_args()
    print(calculate_key(args.secret, args.region))


if __name__ == '__main__':
    main()

Did this article help?


Do you need billing or technical support?