Skip to content

Email Integration -- Infrastructure Design

Infrastructure resources that must be provisioned before the email-sending components can be deployed and function.

Infrastructure resources are scoped to be global to the complete platform (Platform scope), managed as part of an Infrastructure, or as part of a Partition within an Infrastructure

PlantUML diagram

This document is parametrized on the mail root domain — the top-level domain under which all tenant sending subdomains are created. The choice of root domain is an open decision (see DQ-009).

ParameterNotationExample values
Mail root domain{mail-root-domain}One of: ardamails.com, ardamails.net, already owned
DNS registrar{registrar}Amazon (Route53)
  • Root Account (hosting root domain zone): platformRoot, account Id 841876193886

#ResourceScopeNotes
DNS-Z1Hosted zone {mail-root-domain}PlatformCreated as part of domain registration in platformRoot account. NS set at {registrar} (one-time).
DNS-Z2Hosted zone dev.{mail-root-domain}Partition: Alpha002/devDelegated from root zone
DNS-Z3Hosted zone stage.{mail-root-domain}Partition: Alpha002/stageDelegated from root zone
DNS-Z4Hosted zone prod.{mail-root-domain}Partition: Alpha001/prodDelegated from root zone
DNS-Z5Hosted zone demo.{mail-root-domain}Partition: Alpha001/demoDelegated from root zone

The root zone is managed as infrastructure. It contains only NS delegations and parent email authentication records. No runtime-provisioned tenant records live here (see DQ-010).

#TypeNameValue / TargetScope
DNS-R1TXT@ (SPF)v=spf1 include:spf.mtasv.net ~allPlatform
DNS-R2TXT_dmarcv=DMARC1; p=reject; sp=rejectPlatform
DNS-R3NSdev→ DNS-Z2 nameserversPartition: Alpha002/dev
DNS-R4NSstage→ DNS-Z3 nameserversPartition: Alpha002/stage
DNS-R5NSprod→ DNS-Z4 nameserversPartition: Alpha001/prod
DNS-R6NSdemo→ DNS-Z5 nameserversPartition: Alpha001/demo

All partitions use the same FQDN structure: {config-slug}.{tenant-slug}.<partition>.{mail-root-domain}.

Even in v1 (single configuration per tenant), the {config-slug} is present. Its value is TBD. See DQ-002.

EnvironmentSending Domain FQDNExample
Prod{config-slug}.{tenant-slug}.prod.{mail-root-domain}orders.acme.prod.{mail-root-domain}
Demo{config-slug}.{tenant-slug}.demo.{mail-root-domain}orders.acme.demo.{mail-root-domain}
Dev{config-slug}.{tenant-slug}.dev.{mail-root-domain}orders.acme.dev.{mail-root-domain}
Stage{config-slug}.{tenant-slug}.stage.{mail-root-domain}orders.acme.stage.{mail-root-domain}

Per-Tenant DNS Records (runtime provisioned)

Section titled “Per-Tenant DNS Records (runtime provisioned)”

When a tenant is onboarded, the following records are created in the partition zone for the sending domain {config-slug}.{tenant-slug}.<partition>.{mail-root-domain}. These are not infrastructure resources — they are created at runtime by the emailConfiguration service.

Record TypeNameValuePurpose
TXT{DKIMPendingHost} (from Postmark){DKIMPendingTextValue} (from Postmark)DKIM signature verification
CNAMEpm-bounces.{config-slug}.{tenant-slug}pm.mtasv.netReturn-Path / SPF alignment
TXT_dmarc.{config-slug}.{tenant-slug}v=DMARC1; p=none (ramped to quarantine then reject)DMARC policy for the sending domain
MX{config-slug}.{tenant-slug}Not in v1 (Reply-To external). v2+: Postmark inbound MXInbound email routing (procurement inbox)

See Postmark Service Design for the full provisioning flow and API details.

The following names must be excluded from tenant slug allocation (enforced at provisioning time and in validation logic):

mail, dmarc, postmaster, abuse, api, www, admin, arda, arda-cards, platform

DNS records may be created for some of these at a later time to support specific features. For now they are simply blocked from use as tenant slugs.


#ResourceScopeNotes
PM-1PostmarkProd accountInfrastructure: Alpha001Manual, one-time. Live delivery (prod, demo).
PM-2PostmarkNonProd accountInfrastructure: Alpha002Manual, one-time. Sandbox delivery (dev, stage).
PM-3Platform plan on both accountsInfrastructure: Alpha001, Alpha002Manual, one-time. Unlimited servers, domains, streams.
PM-4Account-level API token for PostmarkProdInfrastructure: Alpha001Manual. Stored in SM-1/SM-2 below.
PM-5Account-level API token for PostmarkNonProdInfrastructure: Alpha002Manual. Stored in SM-3/SM-4 below.
Postmark AccountPartitionsServer Type
PostmarkProdprod, demoLive servers (real delivery)
PostmarkNonProddev, stageSandbox servers (delivery to blackhole)

Per-Tenant Provisioning (runtime, not infrastructure)

Section titled “Per-Tenant Provisioning (runtime, not infrastructure)”

The following are provisioned per tenant at runtime by the emailConfiguration service. They are not infrastructure prerequisites:

  • Create Postmark server in the appropriate account
  • Create sending domain; receive DKIM TXT record values and Return-Path CNAME target
  • Publish per-tenant DNS records in the partition zone
  • Configure webhooks with Bearer token auth (POST /webhooks)
  • Encrypt server token with partition-wide encryption key and persist in database
  • DNS verification proceeds asynchronously (see Scenario 1b)

Secrets follow the Arda naming convention: {infrastructure}-{namespace}-I-{secretName}.

#ResourceNameScopeHolds
SM-1Postmark account API tokenAlpha001-prod-I-EmailPostmarkAccountTokenPartition: Alpha001/prodPM-4 token
SM-2Postmark account API tokenAlpha001-demo-I-EmailPostmarkAccountTokenPartition: Alpha001/demoPM-4 token (same value as SM-1)
SM-3Postmark account API tokenAlpha002-dev-I-EmailPostmarkAccountTokenPartition: Alpha002/devPM-5 token
SM-4Postmark account API tokenAlpha002-stage-I-EmailPostmarkAccountTokenPartition: Alpha002/stagePM-5 token (same value as SM-3)
SM-5Tenant server token encryption keyAlpha001-prod-I-EmailEncryptionKeyPartition: Alpha001/prodSymmetric key for encrypting per-tenant Postmark server tokens in the database
SM-6Tenant server token encryption keyAlpha001-demo-I-EmailEncryptionKeyPartition: Alpha001/demoSymmetric key for encrypting per-tenant Postmark server tokens in the database
SM-7Tenant server token encryption keyAlpha002-dev-I-EmailEncryptionKeyPartition: Alpha002/devSymmetric key for encrypting per-tenant Postmark server tokens in the database
SM-8Tenant server token encryption keyAlpha002-stage-I-EmailEncryptionKeyPartition: Alpha002/stageSymmetric key for encrypting per-tenant Postmark server tokens in the database

Each partition gets its own secret entries, even when the underlying value is shared (e.g., PostmarkProd token is the same for prod and demo). This follows the convention that secrets are scoped per partition.

Per-tenant Postmark server tokens are not stored in Secrets Manager. They are encrypted with the partition-wide encryption key and persisted in the database by the emailConfiguration service. See functional.md for the encryption approach.

Secrets are delivered to the component via the existing External Secrets Operator (ESO) pattern, the same mechanism used for database credentials:

  1. Secrets are created in AWS Secrets Manager (SM-1 through SM-8)
  2. ESO syncs them to Kubernetes Secrets (polled every 1 hour)
  3. Kubernetes mounts secrets as files at /app/secret/ in the pod
  4. HOCON configuration reads values from secrets.properties at startup

The component does not call Secrets Manager at runtime. All secret values are available as HOCON configuration properties after pod startup.

The ESO ExternalSecret definitions and the HOCON property mapping are configured in the ShopAccess/Email module. See functional.md for the module-level configuration.


#ResourceAccessScopeZones
IAM-1Email DNS provisioning roleRoute53 write (scoped to zone ARNs). AssumeBy trust for pod service account role.Infrastructure: Alpha002DNS-Z2, DNS-Z3
IAM-2Email DNS provisioning roleRoute53 write (scoped to zone ARNs). AssumeBy trust for pod service account role.Infrastructure: Alpha001DNS-Z4, DNS-Z5

Each role:

  • Is scoped to the partition zone ARNs — the zone ARN inherently restricts writes to records within that zone
  • Has an AssumeBy trust policy with ArnLike condition matching the pod service account role pattern, following the same pattern as the S3 presigning role for image upload
  • Does not include Secrets Manager permissions (secrets are handled by ESO)
  • Alpha001 provisioning role cannot touch Alpha002 zones and vice versa (separate roles per infrastructure)
  • Reserved subdomain names are enforced at the application layer (emailConfiguration service validation), not IAM

Resources in the platformRoot account, applying to the platform as a whole.

#TypeResource
DNS-Z1Route53 ZoneRoot hosted zone {mail-root-domain}
DNS-R1Route53 RecordSPF TXT at {mail-root-domain}
DNS-R2Route53 RecordDMARC TXT at _dmarc.{mail-root-domain}

Resources shared across prod and demo partitions.

#TypeResource
PM-1PostmarkPostmarkProd account (Platform plan)
PM-4PostmarkPostmarkProd account API token
IAM-2IAM RoleDNS provisioning role (zones: DNS-Z4, DNS-Z5)

Resources shared across dev and stage partitions.

#TypeResource
PM-2PostmarkPostmarkNonProd account (Platform plan)
PM-5PostmarkPostmarkNonProd account API token
IAM-1IAM RoleDNS provisioning role (zones: DNS-Z2, DNS-Z3)
#TypeResource
DNS-Z4Route53 Zoneprod.{mail-root-domain}
DNS-R5Route53 RecordNS delegation prod in root zone
SM-1SecretHolds: PM-4 token
SM-5SecretTenant server token encryption key
#TypeResource
DNS-Z5Route53 Zonedemo.{mail-root-domain}
DNS-R6Route53 RecordNS delegation demo in root zone
SM-2SecretHolds: PM-4 token (same value as SM-1)
SM-6SecretTenant server token encryption key
#TypeResource
DNS-Z2Route53 Zonedev.{mail-root-domain}
DNS-R3Route53 RecordNS delegation dev in root zone
SM-3SecretHolds: PM-5 token
SM-7SecretTenant server token encryption key
#TypeResource
DNS-Z3Route53 Zonestage.{mail-root-domain}
DNS-R4Route53 RecordNS delegation stage in root zone
SM-4SecretHolds: PM-5 token (same value as SM-3)
SM-8SecretTenant server token encryption key