Docs

Behavior & Limits

Guarantees, limits, and update semantics for Alien Email.

Email is currently available only on AWS, backed by SES.

Guarantees

Your domains, your reputation. Mail is sent through SES in the customer's AWS account, from domains they own. Sending reputation, quotas, and deliverability belong to that account — there is no shared sending pool.

Easy DKIM on every domain. Every identity — seed or runtime-created — is provisioned with Easy DKIM. The resource outputs carry three DKIM CNAME records per seed domain; SES verifies the domain asynchronously once the records exist in DNS. Verification status is not part of the outputs because it can't be known at provisioning time — read it from ses:GetEmailIdentity.

Runtime identities survive the stack. Identities created through the email/manage-identities grant are application data: they are not tracked by the deployment and are not removed when the stack is deleted. Their lifecycle — including deletion — belongs to the application. Seed domains, by contrast, are CloudFormation-managed: removing one from domains deletes its identity and DKIM verification state.

Catch-all inbound. The provisioned receipt rule has no recipient filter, so mail for any identity the account receives mail for — including identities verified at runtime — lands in the linked Storage bucket without an infrastructure change. Each message is written as a raw MIME object, with spam and virus scanning enabled.

Complete event coverage. With .events(), SES publishes send, delivery, bounce, complaint, delivery-delay, and reject events for all mail sent through the configuration set, delivered to the linked queue via an SNS topic with raw message delivery.

Limits

LimitValueNotes
id[A-Za-z0-9-_], max 64 charsImmutable after create.
Seed domainsuniqueListing the same domain twice is rejected.
Events queueone Email resource per queueSQS supports a single effective policy per queue; two Email resources targeting the same queue would overwrite each other's policy.
Inbound regionsSES receiving regions onlySES email receiving is available in a subset of AWS regions; deploying .inbound() elsewhere fails at the CloudFormation layer.
Active receipt rule setsone per AWS accountSee below.

Changing a live resource. domains is append-friendly: adding a domain provisions a new identity, removing one deletes its identity (and its DKIM verification state), and the list may be empty. .inbound() and .events() can be added, removed, or repointed; removing them tears down the corresponding receipt rule set or event destination wiring. The id is immutable.

Inbound Activation

SES allows only one active receipt rule set per AWS account, and CloudFormation has no resource that activates one. Activating the provisioned rule set is a manual post-deploy step:

aws ses set-active-receipt-rule-set --rule-set-name <ruleSetName>

The rule set name is surfaced in the resource outputs (ruleSetName). Until it is activated, inbound mail is not delivered to the bucket.

What Gets Provisioned

  • One shared AWS::SES::ConfigurationSet, named after the stack and resource id.
  • Per seed domain, an AWS::SES::EmailIdentity with Easy DKIM enabled and the configuration set associated.
  • With .events(): a configuration set event destination publishing to an SNS topic, subscribed to the linked SQS queue (raw delivery), plus the queue policy that lets the topic send.
  • With .inbound(): a receipt rule set and a catch-all receipt rule whose S3 action writes into the linked bucket, plus the bucket policy statement that allows SES to write (scoped to the account).
  • IAM policies attaching any granted email/* permission sets to the owning workload roles.

Platform Notes

AWS — SES

The only supported platform. New AWS accounts start in the SES sandbox (verified recipients only, low quotas); production access is an account-level request to AWS, outside Alien's scope. Sending quotas and reputation are per-account.

Other Platforms

Email is not available on GCP, Azure, Kubernetes / on-prem, or Local.

Design Decisions

Infrastructure, not domain lifecycle. The resource owns the configuration set and the event/inbound topology. The domain lifecycle belongs to the application: email products typically create identities via API when a customer adds a domain, hand over the DNS records, poll verification, and delete the identity when the domain is removed. Seed domains exist for day-0 bootstrap and static-domain products.

No domain list in the binding. Identities come and go at runtime, so a deploy-frozen list would be stale by design. Applications discover the current identities via ses:ListEmailIdentities.

No high-level send API. Workloads send with the AWS SDK directly using the email/send grant. Every backend is SES, so wrapping the SDK would add a layer without adding portability.

Frozen-only. The Email resource is always frozen: setup owns the durable routing state end to end.

On this page