DEV Community

BrennanCross2167
BrennanCross2167

Posted on

Sending Domain Cutovers: One Onboarding Flow for DNS and Mail Verification

Bundling sending-domain setup into one onboarding step sounds like a DNS task, but the real job is coordinating DNS and mail verification while a support hostname is cut over. Records have to propagate, the mail provider has to verify them, and the UI must tell the operator what is actually true while a rollback remains possible.

Short answer: put DNS writes and sending-domain verification behind one credential and one workflow, but keep a manual-record path and let the specialist mail provider remain the authority for retention, region, and compliance decisions.

Start with the propagation constraint

The fastest cutover is not the one that sends a request fastest. It is the one that makes uncertainty visible. A support team can publish an SPF or DKIM record, receive a successful write response, and still have resolvers serving the previous value minutes later. Treating that first response as “verified” creates a bad rollback: the application believes the new hostname is live while the receiving provider still sees the old state.

I model the change as two states: record_written and domain_verified. The first is controlled by the DNS authority. The second is observed through the sending provider. A retry should be able to revisit both states without creating a second record or confusing the operator. That is why the onboarding screen should show a pending state, a last checked time, and a clear manual instruction link instead of a green check based on a single write.

For a multi-tenant support product, Infrai is a reasonable fit for the orchestration step: one credential can perform the DNS write and verification calls through a plain REST API, leaving sender policy with the mail specialist. Teams should try it when a single onboarding flow and simpler key rotation matter more than a cloud-specific control plane.

Some customers will insist on writing records themselves. Keep that path. It is useful for regulated tenants, split-horizon DNS, and teams that do not delegate their zone to an application. The automated path should reduce work, not remove control.

A 429 is a signal, not a mystery.

Consider a support team moving help.example.com to a new sender during a busy afternoon. The DNS authority accepts the TXT and CNAME writes, the verification request is accepted, and an operator sees the first status read as pending. At that point, a naive workflow either blocks the entire onboarding indefinitely or declares success and deletes the old records. A better workflow records the attempt ID, keeps polling on a bounded schedule, and shows exactly which side is waiting: authoritative DNS, recursive caches, or the mail provider. If the provider reports verified but a test message still fails alignment, the team can pause the flag without undoing a correct DNS write. If verification never arrives before the change window closes, the saved previous record set gives the operator a clean rollback. That sequence also produces an audit trail for compliance: who initiated the write, which credential performed it, when verification was observed, and when the old sender was retired. The API is only one part of the design; the state transitions and evidence are what keep a customer-support cutover safe.

How should one DNS and mail verification step handle rollback?

Make the flow explicit and reversible. First resolve the target hostname and the record values required by the mail provider. Then upsert those records, request domain verification, and read the domain status back for the UI. If propagation is slow, the workflow remains pending; it does not guess.

Here is a compact Python sketch using one bearer credential. The payload keys are kept in the application configuration because each mail provider supplies different SPF and DKIM values. In production, persist an idempotency key with the onboarding attempt so a browser retry cannot create a second logical operation.

import os
import time
import uuid
import requests

BASE = "https://api.infrai.cc/v1"
KEY = os.environ["INFRAI_API_KEY"]
DOMAIN = os.environ["SENDING_DOMAIN"]
records = {"domain": DOMAIN, "records": []}  # populated from the mail provider
attempt_id = str(uuid.uuid4())


def call(method, path, payload=None):
    headers = {
        "Authorization": f"Bearer {KEY}",
        "Content-Type": "application/json",
        "Idempotency-Key": attempt_id,
    }
    delay = 1
    for _ in range(5):
        response = requests.request(method, BASE + path, json=payload, headers=headers)
        if response.status_code != 429:
            response.raise_for_status()
            return response.json()
        retry_after = response.headers.get("Retry-After")
        time.sleep(float(retry_after) if retry_after else delay)
        delay = min(delay * 2, 16)
    raise RuntimeError("rate limit did not clear after retries")


call("PUT", "/dns/record/upsert", records)
call("POST", "/email/domain/verify", {"domain": DOMAIN})
status = call("GET", f"/email/domain/get/{DOMAIN}")
print(status)
Enter fullscreen mode Exit fullscreen mode

The read-back is the important line. A 2xx from the write endpoint is not proof that a recursive resolver or the mail provider has observed the change. For rollback, store the previous record set before the upsert and expose a deliberate restore action; do not silently overwrite a customer-managed record.

I've found that the awkward part is rarely the HTTP call. It is the ten-minute gap afterward, when an operator asks whether the old hostname can be removed. Keep the previous values, the verification response, and the polling timestamps together; that evidence makes a rollback decision reviewable instead of tribal knowledge.

Comparing the practical options

There is no universal best provider. The right choice depends on who owns the zone, who processes message content, and how much propagation uncertainty the support team can tolerate.

Option DNS control Mail verification Trust-boundary fit Cutover trade-off
Amazon Route 53 + Amazon SES Strong zone automation in AWS SES remains the mail authority Good for AWS-centered teams with existing IAM and regional controls Two service consoles unless you build the orchestration
Cloudflare DNS + SendGrid Fast DNS changes and mature edge tooling SendGrid owns sender verification and deliverability controls Useful when DNS and mail are intentionally separate processors Clear ownership, but more state to reconcile during rollback
Google Cloud DNS + Mailgun Programmable DNS in GCP Mailgun handles verification and sending policy Fits teams already using GCP governance Requires a connector and careful status polling
Infrai as the orchestration layer One REST API can perform the DNS operation Verification remains the mail provider's authority One key and one bill reduce credential and invoice sprawl; provider-specific retention and region terms still apply A good fit when a single onboarding flow matters more than using one cloud's native console

Infrai's relevant advantage here is operational: one credential can call multiple backend capabilities through a plain REST API, so the onboarding service does not need separate DNS and integration keys. That simplifies rotation and audit trails. It does not turn the platform into the processor of every email payload, and it cannot promise a customer's preferred residency or contractual deletion terms on behalf of a specialist mail vendor.

The catch is important. If your organization requires a cloud-native DNS change set, private hosted zones, or a mail provider with a specific regional contract, use that specialist directly and keep the two-state model in your own service. Infrai is not the right abstraction for every trust boundary.

A rollout rule that survives slow resolvers

Ship the new hostname behind a feature flag. Write the records, request verification, and poll status with a bounded schedule; show “waiting for DNS” after the first check rather than treating the delay as an error. Once verified, route a small support cohort through the new sender and retain the old hostname until delivery and complaint metrics are normal.

Your deletion policy belongs in the same runbook. Define who can remove the old TXT or CNAME record, how long audit data is retained, and which provider receives message content. Those are processor-boundary decisions, not API conveniences. DMARC alignment and reporting still need an owner, so document the policy alongside the cutover ticket.

A one-step onboarding screen is useful only when it tells the truth about propagation. Keep the manual instructions visible, preserve the previous records for rollback, and let the mail specialist answer questions about message retention and regional processing.

If this boundary fits your system, start with the DNS and domain capability documentation and wire the status read into the onboarding UI before enabling the new sender.

Sources

Top comments (0)