← All stories

BRANCH · ef-060-email-masking

Email masking — SPF/DKIM customer-domain sending

EF-060Persona: Organizer + adminRoots in: event-setup

EF-060 is absent. This story ships as a gap probe documenting the desired contract: domain verification UI, DNS TXT records, status pills, sender enforcement, and suspended or expired-domain handling.

Preconditions

Fixture tenant lacks SPF/DKIM email masking implementation and should show the EF-060 not implemented panel.

Desired contract

  1. Add sending domain.

    Admin enters a customer domain and receives SPF/DKIM TXT records to copy into DNS.

  2. Verify records.

    Status pills show pending, verified, failed, suspended, and expired states.

  3. Send from verified domain.

    Send-time enforcement blocks unverified From addresses and audits the selected sender domain.

Failure modes

Parity gap probe

Trigger: EF-060 route is opened before implementation.

Resolution: a visible EF-060 not yet implemented panel remains until the SPF/DKIM UI ships.

Unverified domain blocked

Trigger: organizer selects an unverified From domain.

Resolution: send is blocked with 409 DOMAIN_NOT_VERIFIED and no email leaves.

DNS record mismatch

Trigger: DNS TXT record exists but value differs from Voyage.

Resolution: verification fails with copyable expected and observed values.

SPF missing

Trigger: DKIM exists but SPF is missing.

Resolution: status stays partial and sender enforcement blocks customer-domain From.

DKIM missing

Trigger: SPF exists but DKIM is missing.

Resolution: status stays partial and send remains blocked.

DNS lookup timeout

Trigger: verification provider times out.

Resolution: retryable warning appears and status remains pending, not failed.

Suspended domain handling

Trigger: deliverability team suspends a domain.

Resolution: status pill changes to suspended and sends are blocked.

Expired verification

Trigger: DNS records disappear after prior verification.

Resolution: status becomes expired and sender enforcement blocks future sends.

Cross-tenant domain isolation

Trigger: tenant A tries to use tenant B's verified domain.

Resolution: 404/403 without leaking DNS tokens.

Retry on transient verification failure

Trigger: DNS provider returns transient failure.

Resolution: verification retries with backoff and a single audit row per attempt.

Audit sender enforcement

Trigger: a masked-domain send is accepted or blocked.

Resolution: audit log captures actor, domain, From address, and enforcement result.

Stable test attributes

Visibility teeth. Each attribute must be effectively visible when active.

email-masking-pagePageMasking surface
email-masking-gap-panelPageAbsent feature
domain-add-formPageAdd domain
domain-dns-recordsPageTXT records
domain-verification-statusPageStatus pill
domain-verify-ctaPageVerify
sender-domain-pickerSend formFrom domain
sender-enforcement-warningSend formBlocked sender

Agent test plan

- email-masking-gap-visible
- add-domain-contract
- sender-enforcement-contract
- audit-enforcement-contract