elmeg-demo/docs/AWS_SES_SETUP.md
fullsizemalt cc694ed5bb docs: Add comprehensive AWS SES setup guides
- AWS_SES_SETUP.md: Complete setup with prod/dev env separation
- AWS_SES_BROWSER_AGENT.md: Step-by-step for browser-based agent
- Explicit security notes about IAM scoping and key handling
2025-12-21 14:40:20 -08:00

141 lines
3.2 KiB
Markdown

# AWS SES Email Setup
## Environment Configuration
### Production (`elmeg.xyz`)
```bash
AWS_ACCESS_KEY_ID=AKIA... # IAM user with SES send-only perms
AWS_SECRET_ACCESS_KEY=...
AWS_SES_REGION=us-east-1 # Must match region where domain is verified
EMAIL_FROM=noreply@elmeg.xyz # Must be on SES-verified domain
FRONTEND_URL=https://elmeg.xyz
NODE_ENV=production
APP_ENV=production
```
### Development (`elmeg.runfoo.run`)
```bash
FRONTEND_URL=https://elmeg.runfoo.run
APP_ENV=development
# AWS keys optional in dev - emails log to console instead
```
---
## SES Setup Checklist
### 1. Verify Domain in SES
1. AWS Console → SES → Verified Identities → Create identity
2. Select "Domain" → enter `elmeg.xyz`
3. Add DNS records AWS provides:
- **TXT record** for domain verification
- **3 CNAME records** for DKIM signing
> [!IMPORTANT]
> Add DKIM records or mail will get flagged as spam
### 2. Move Out of Sandbox
By default SES is sandboxed (can only send to verified emails).
1. SES → Account dashboard → Request production access
2. Fill out:
- Mail type: **Transactional**
- Website URL: `https://elmeg.xyz`
- Use case: "User registration verification, password reset for live music rating platform"
3. Wait for approval (~24hrs)
### 3. Create IAM User
1. IAM → Users → Create user: `elmeg-ses-sender`
2. Attach inline policy (SES send only):
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail"
],
"Resource": "*"
}
]
}
```
3. Security credentials → Create access key
4. Save credentials securely
> [!CAUTION]
> **Never commit AWS keys.** Use environment variables only. Never use root AWS credentials - always create a scoped IAM user.
---
## DNS Records Required
Add these to `elmeg.xyz` DNS (exact values from SES console):
| Type | Name | Value |
|------|------|-------|
| TXT | `_amazonses.elmeg.xyz` | (provided by SES) |
| CNAME | `xxxx._domainkey.elmeg.xyz` | (DKIM 1) |
| CNAME | `xxxx._domainkey.elmeg.xyz` | (DKIM 2) |
| CNAME | `xxxx._domainkey.elmeg.xyz` | (DKIM 3) |
---
## Deployment
### Add to production server
```bash
ssh root@tangible-aacorn
cd /srv/containers/elmeg-demo
```
Edit `docker-compose.yml` backend environment:
```yaml
backend:
environment:
- DATABASE_URL=postgresql://elmeg:elmeg@db:5432/elmeg
- AWS_ACCESS_KEY_ID=AKIA...
- AWS_SECRET_ACCESS_KEY=...
- AWS_SES_REGION=us-east-1
- EMAIL_FROM=noreply@elmeg.xyz
- FRONTEND_URL=https://elmeg.xyz
- APP_ENV=production
```
Rebuild and restart:
```bash
docker compose build backend
docker compose restart backend
```
---
## Cost
- **$0.10 per 1,000 emails**
- No monthly minimum
- First 62,000 emails/month free if sending from EC2
---
## Troubleshooting
| Issue | Solution |
|-------|----------|
| "Email address is not verified" | Domain not verified, or still in sandbox |
| "Access Denied" | Check IAM policy has `ses:SendEmail` |
| Emails not sending | Check `docker compose logs backend` |
| Emails in spam | Verify DKIM records are set correctly |
| Wrong links in emails | Check `FRONTEND_URL` matches prod domain |