AWS SES integration
Ahena works with Amazon SES in the Region your app sends from: it checks production access, sending status and reputation, verifies your domain and DKIM, creates a missing domain identity and configuration set, and lists the exact DKIM records to publish. Ahena never sends email, not even a test. Your app sends straight to SES through the same generated email code Ahena writes for Resend. SES is its own provider in Ahena, separate from S3.
What Ahena inspects
Read-only: inspecting and Doctor never change anything at AWS SES.
- The credentials, through STS
GetCallerIdentity, and which SES read permissions they have. - The account: sandbox or production access, sending enabled, enforcement status and quota. Contact details are dropped.
- Identities with verification status, and for domains: DKIM status, the three DKIM CNAME records, custom MAIL FROM and the default configuration set.
- Configuration sets and their event destinations (name, event types, destination kind; never ARNs).
What Ahena configures
You declare what you want in ahena.config.ts; ahena plan shows each change with its classification before anything is applied.
| Change | Classification | Notes |
|---|---|---|
| Create the domain identity with Easy DKIM | CONFIRMATION_REQUIRED | Publishing the three DKIM CNAME records is a manual DNS step; Doctor lists them exactly. |
| Create the configuration set | CONFIRMATION_REQUIRED | Name only, default settings. |
| Leave the sandbox (production access) | MANUAL | An AWS support request from the SES console; Doctor gives the steps. |
Refused outright:
- Sending email, including test sends.
- Deleting identities or configuration sets, and changing event destinations.
- Email-address identities (SES sends them a verification email).
Generated code: src/ahena/email/index.ts (email.send, email.raw, the same interface as the Resend adapter), src/ahena/providers/aws-ses.ts and .env.example.aws-ses.
How Ahena verifies
After every write, Ahena reads AWS SES back. Each change ends in one of these states, and the plan's outcome says why:
- VERIFIED: Ahena read the provider back and saw the desired state. The CLI shows ✓ only for VERIFIED.
- APPLIED_UNVERIFIED: The provider accepted the change, but the re-read doesn't show it yet (after bounded polling), or the re-read failed.
Creates are re-read and made only if absent; an AlreadyExists race counts as done. Ahena then plans again: an empty plan is the read-back.
Domain verification completes when SES sees the DNS records; Doctor reports it, with the records, until then.
Identity and configuration-set listings follow NextToken to the end.
If a request may have reached AWS SES but the answer was lost, Ahena re-reads before deciding: done, safe to retry, or “check before retrying”.
What Doctor diagnoses
Key checks from ahena doctor. Each finding says why it matters, where, the impact and whether Ahena can fix it. The full list is in the AWS SES docs.
| Check | What it means |
|---|---|
aws-ses.credential / .region | STS accepts the credentials, and the connection uses the declared Region. |
aws-ses.account.sandbox | FAIL in production while the account is in the sandbox, with the console steps. |
aws-ses.account.sending / .enforcement | Sending enabled; WARNING on probation, FAIL on shutdown. |
aws-ses.domain | The domain identity exists and is verified. |
aws-ses.domain.dkim | DKIM status, with the exact CNAME records to add. |
aws-ses.domain.mail_from / aws-ses.from | Custom MAIL FROM state, and email.from is on the verified domain. |
aws-ses.configuration_set | The declared configuration set exists, with its event destinations. |
More on findings, health and continuous checks: Doctor.
Approvals
AWS SES changes here are classified CONFIRMATION_REQUIRED and MANUAL. Every change is planned and shown as a diff first. Ahena itself enforces who can approve it:
- SAFE changes are applied without asking.
- In production, every other change needs approval in the Ahena dashboard, signed in, by an admin.
- In other environments, CONFIRMATION_REQUIRED changes are approved in the CLI; BILLABLE and DESTRUCTIVE changes always need the dashboard.
- MANUAL steps are never applied by Ahena.
--yes and --allow-billable don't replace a dashboard approval. See approvals for how it works and why the browser.
Manual steps
These are MANUAL: Ahena never does them. It lists them with the exact steps when they apply.
- Publish the three DKIM CNAME records Doctor lists at your DNS host (
--records-fromreads only Resend today). - Request production access in the SES console (Account dashboard → Request production access).
- Create a dedicated IAM user with the minimal policy from the docs; a Deny on sending makes "Ahena never sends" enforceable by AWS.
Credentials and permissions
| Name | Secret | Notes |
|---|---|---|
AWS_ACCESS_KEY_ID | Yes | Access key of a dedicated IAM user for Ahena (AKIA…). |
AWS_SECRET_ACCESS_KEY | Yes | Shown once when the access key is created. |
AWS_SESSION_TOKEN | Yes | Optional, for temporary credentials only. |
AWS_REGION | No | The SES Region your app sends from. Identities, quotas and production access are per Region. |
Least privilege
- Six reads (
ses:GetAccount,ListEmailIdentities,GetEmailIdentity,ListConfigurationSets,GetConfigurationSet,GetConfigurationSetEventDestinations) and two creates (ses:CreateEmailIdentity,ses:CreateConfigurationSet). No sending, delete or tag permissions. - Checked at connect: the three account-wide reads are probed and reported granted, missing or unknown; the per-resource reads and creates are reported unknown.
Each credential Ahena stores gets its own key and is envelope-encrypted, bound to the environment. See security.
Workflow example
Connect, check, plan, then apply. Placeholders (…) stand for your own values.
AWS_ACCESS_KEY_ID=… AWS_SECRET_ACCESS_KEY=… ahena connect aws-ses -e production --set AWS_REGION=us-east-1Connect in the Region your app sends from.
ahena doctor -e productionCheck the sandbox, sending status, domain and DKIM.
ahena plan -e productionSee the identity and configuration-set changes.
ahena apply -e productionApprove and apply, then publish the DKIM records Doctor lists.
ahena generate aws-ses -e productionWrite the email adapter.
Verification status
Available in beta. Every capability is validated by Ahena's automated provider contract and conformance tests; verification against the real service is next.
How AWS SES is tested
- AWS SES is tested against a simulated version of the SES v2 and STS APIs (JSON responses, AWS error types), including pagination, permission probes, the read-back after each write and idempotent re-apply. The simulated API records any send, and the tests check there are none.
- Request signing (SigV4, WebCrypto) is tested against AWS's published SigV4 test suite.
- It hasn't been run against real AWS yet. The generated email code is typechecked against the real AWS SDK, together with app code written for the Resend adapter.
The providers overview explains Ahena's testing methodology and what has been verified for every provider.
Limitations
- Opt-in Regions, GovCloud and China aren't supported.
- DKIM records aren't added to DNS automatically, even on Cloudflare.
- Custom MAIL FROM, Bring Your Own DKIM, dedicated IPs, suppression lists and templates aren't managed.
Disconnecting
ahena disconnect aws-ses removes the stored credentials; deactivate and delete the access key in IAM. Identities, configuration sets and history are untouched.