# Amazon SES Tenant Management — Reference Implementation

Reference IaC and scripts for the FactualMinds guide [Amazon SES Tenant Management: Enterprise Guide](https://www.joinhorizon.co/blog/amazon-ses-tenant-management-enterprise-guide/).

## Prerequisites

- AWS account with **SES production access** (sandbox blocks `PutSuppressedDestination`)
- **AWS CLI v2.28.0+** (`aws --version`)
- Verified SES identity and configuration set in the target region
- SES **V2 API** only (tenant APIs are not in SES v1)

## Quick start

```bash
# Set your region and tenant name
export AWS_REGION=us-east-1
export TENANT_NAME=acme-retailer-01
export IDENTITY_ARN=arn:aws:ses:us-east-1:123456789012:identity/retailer.example.com
export CONFIG_SET_ARN=arn:aws:ses:us-east-1:123456789012:configuration-set/acme-retailer-cs

./scripts/onboard-tenant.sh
```

Or deploy via CloudFormation (identity and config set must already exist):

```bash
aws cloudformation deploy \
  --template-file cloudformation/tenant-onboarding.yaml \
  --stack-name ses-tenant-acme-retailer-01 \
  --parameter-overrides \
    TenantName=acme-retailer-01 \
    IdentityArn="$IDENTITY_ARN" \
    ConfigurationSetArn="$CONFIG_SET_ARN" \
    SuppressionScope=TENANT \
  --region "$AWS_REGION"
```

## Contents

| Path | Purpose |
|------|---------|
| `cloudformation/tenant-onboarding.yaml` | `AWS::SES::Tenant` with resource associations and tenant suppression |
| `iam/tenant-admin-policy.json` | Full tenant lifecycle (onboarding roles) |
| `iam/tenant-sender-policy.json` | Least-privilege send scoped with `ses:TenantName` |
| `iam/tenant-readonly-policy.json` | Security/compliance read-only |
| `eventbridge/tenant-reputation-rule.json` | Event pattern for reputation findings and pause events |
| `scripts/onboard-tenant.sh` | CLI wrapper for create + associate |
| `diagrams/*.drawio` | Architecture diagrams linked from the enterprise guide |

## EventBridge

Deploy the rule pattern in `eventbridge/tenant-reputation-rule.json` to your default event bus. Target a Lambda, SNS topic, or SQS queue for tenant pause automation.

## IAM notes

- Replace `ACCOUNT_ID`, `REGION`, and tenant names in policy ARNs before attaching.
- Sender policies **must** include `ses:TenantName` — without it, applications can send through any tenant.

## Related AWS documentation

- [Tenants — SES Developer Guide](https://docs.aws.amazon.com/ses/latest/dg/tenants.html)
- [Tenant-level suppression lists](https://docs.aws.amazon.com/ses/latest/dg/sending-email-suppression-list-tenant-level.html)
- [AWS::SES::Tenant](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ses-tenant.html)
