🎯 Goal
To send email using AWS Simple Email Service (SES) in Account A, while accessing SMTP credentials stored in Secrets Manager of the same account (Account A) from a Lambda function or script running in Account B.
📘 Why This is Useful
- Centralized secret management — avoid duplicating credentials.
- Follows security best practices using IAM roles and resource-based policies.
- Helps maintain separation of concerns between environments or teams.
- Good for multi-account setups (e.g., Dev/Prod or Service/Infra separation).
✅ Setup Overview
Account A:
- Owns SES identity/domain.
- Has SMTP credentials stored in AWS Secrets Manager.
Account B:
- Has a Lambda or Python script that sends email via SES.
- Needs access to the secret in Account A.
🔐 Step 1: Secrets Manager Resource Policy in Account A
On the secret in Secrets Manager (Account A), attach a resource-based policy like this:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCrossAccountSecretAccess", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<ACCOUNT_B_ID>:role/<LAMBDA_EXEC_ROLE>" }, "Action": "secretsmanager:GetSecretValue", "Resource": "*", "Condition": { "StringEquals": { "aws:PrincipalOrgID": "o-xxxxxxx" # Optional (AWS Organization ID) } } } ] }
Tips:
- Replace
*
in"Resource"
with full ARN of the secret for tighter security. - You can also specify multiple roles under
Principal
if needed.
🛠️ Step 2: Python Script in Account B to Access Secret and Send Email
import boto3 import json import smtplib from email.mime.text import MIMEText from botocore.exceptions import ClientError AWS_REGION = "us-east-1" SECRET_ARN = "arn:aws:secretsmanager:us-east-1:<ACCOUNT_A_ID>:secret:<SECRET_NAME>" def get_ses_credentials(): try: client = boto3.client("secretsmanager", region_name=AWS_REGION) response = client.get_secret_value(SecretId=SECRET_ARN) secret_dict = json.loads(response["SecretString"]) return { "server": secret_dict["SMTP_SERVER"], "port": int(secret_dict["SMTP_PORT"]), "username": secret_dict["SMTP_USERNAME_PROD"], "password": secret_dict["SMTP_PASSWORD_PROD"], } except ClientError as e: print("Error getting SES credentials:", e) raise def send_email(): creds = get_ses_credentials() msg = MIMEText("Hello from AWS SES via cross-account secrets!") msg["Subject"] = "Test Email" msg["From"] = creds["username"] msg["To"] = "recipient@example.com" with smtplib.SMTP(creds["server"], creds["port"]) as server: server.starttls() server.login(creds["username"], creds["password"]) server.send_message(msg) print("Email sent!") send_email()
To allow your Lambda in Account B to access the secret from Account A, add this permission to the Lambda role:
{ "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": "arn:aws:secretsmanager:REGION:ACCOUNT_A_ID:secret:secret-name-*" }
Replace placeholders with your actual values. This step is required even if Account A already trusts the role.
🧠 Reminder
- SES SMTP credentials are not IAM credentials. They are stored in Secrets Manager after being created via the SES console.
- Use the ARN of the secret (not the name) when accessing cross-account.
- Ensure the Lambda or script role in Account B has permission to call
secretsmanager:GetSecretValue
.
🔄 Summary
This pattern is useful when you want to:
- Keep your SMTP credentials in a single secure location (Account A).
- Allow other accounts (like Account B) to send emails without duplicating secrets.
- Follow AWS security best practices and support growth for multi-account strategies.
📘 References
Further Reading & Official AWS Documentation
- AWS blog: Design patterns to access cross‑account Secrets Manager secrets (how to share secrets across accounts via KMS & IAM roles) Amazon Web Services, Inc.
- AWS documentation: Access AWS Secrets Manager secrets from a different account (step‑by‑step resource and key policy setup) AWS Documentation
- AWS blog: How to grant another SES account or user permission to send emails (sending authorization in SES) Amazon Web Services, Inc.
- AWS solution: Automated SMTP credential rotation via Secrets Manager (securely manage SES SMTP credentials) Amazon Web Services, Inc.