How to Isolate Sending Permissions with Amazon SES

To isolate sending permissions so that Website A cannot send emails using Website B’s domain, you need to create dedicated IAM Users for each website with a restricted IAM Policy.
The easiest and cleanest way to do this is using the AWS Console.

Step 1: Get the ARN of Your Domain Identity in SES

  1. Go to Configuration $\rightarrow$ Verified identities.
  2. Click on your website’s domain (e.g., example.com).
  3. Copy the Identity ARN at the top of the details page. It looks like this:

    Plaintext

    arn:aws:ses:us-east-1:123456789012:identity/example.com
    

Step 2: Create a Restricted IAM Policy for the Website

  1. Open the IAM Console.
  2. In the left menu, click Policies $\rightarrow$ Create policy.
  3. Select the JSON tab and paste the following policy (replace the Resource ARN with the one you copied in Step 1):

JSON

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListAndVerifySES",
            "Effect": "Allow",
            "Action": [
                "ses:ListIdentities",
                "ses:GetIdentityVerificationAttributes"
            ],
            "Resource": "*"
        },
        {
            "Sid": "RestrictSESToSpecificDomain",
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "arn:aws:ses:us-east-1:123456789012:identity/example.com"
        }
    ]
}
What this does: It permits the user to send emails only if the “From” address belongs to example.com (or subdomains like mail.example.com). If Website A attempts to spoof Website B’s email address, SES will reject it.
  1. Click Next, name the policy SES-Send-Policy-example.com, and click Create policy.

Step 3: Create the IAM User & Get Credentials

Depending on how your website sends emails (via SMTP or AWS SDK/API), follow the corresponding method below:

Option A: If your website connects via SMTP (WordPress, Joomla, etc.)

  1. Go to the IAM Console $\rightarrow$ Users $\rightarrow$ Create user.
  2. Name the user (e.g., smtp-user-example.com).
  3. Under Permissions options, select Attach policies directly.
  4. Search for and select the custom policy you created (SES-Send-Policy-example.com).
  5. Click Next $\rightarrow$ Create user.
  6. Click on the newly created user $\rightarrow$ go to the Security credentials tab.
  7. Scroll down to Access keys $\rightarrow$ click Create access key.
  8. Select Application running outside AWS $\rightarrow$ click Next $\rightarrow$ Create access key.
  9. Copy your Access Key ID and Secret Access Key.
  10. Convert to SMTP Credentials:
    AWS Access Keys are not raw SMTP passwords. To convert your Secret Access Key into an SES SMTP password:
    • In the SES Console, go to SMTP settings.
    • (Or) Use an online convert tool / Python script (AWS Official Converter) to generate the SMTP Password from your Access Key.

Option B: If your app uses the AWS SDK/API (Laravel, Node.js, Python, etc.)

  1. Follow steps 1–8 from Option A.
  2. Put the Access Key ID and Secret Access Key directly into your application’s .env file or environment settings (e.g., AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY).

Repeat for Each Additional Website

For every new website:
  1. Copy its domain Identity ARN from SES.
  2. Create a new IAM Policy containing that specific ARN.
  3. Create a dedicated IAM User attached only to that policy.

Bonus Tip: How to enforce strict “From” address matching

If you want to prevent a user from sending as another email on the same domain (e.g., force website1 to only send as noreply@example.com and not admin@example.com), add a condition to your IAM Policy:

JSON

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "arn:aws:ses:us-east-1:123456789012:identity/example.com",
            "Condition": {
                "StringEquals": {
                    "ses:FromAddress": "noreply@example.com"
                }
            }
        }
    ]
}

Leave a Reply

Your email address will not be published. Required fields are marked *