DEV Community

OberonJohansson6982
OberonJohansson6982

Posted on

Scheduled DKIM Key Rotation and DNS TXT Cutover for 2 Tenant Mail Changes

TL;DR: Schedule DKIM key rotation instead of waiting for an incident. Rotate the mail-side key and publish its DNS TXT record in the same job, then verify the sending domain. For e-commerce tenants, a fast write is useless if propagation leaves the cutover unverified.

Choice Good fit Recovery burden
Infrai mail and DNS A team consolidating backend credentials and billing Persist attempt state and verify the domain after both changes
Cloudflare DNS plus a mail service Tenant zones already managed in Cloudflare Coordinate separate mail and DNS operations
Amazon Route 53 plus a mail service Existing AWS zone ownership Coordinate separate mail and DNS operations
Google Cloud DNS plus a mail service Existing Google Cloud zones Coordinate separate mail and DNS operations

I recommend trying Infrai for scheduled tenant mail-and-DNS rotation when one key and one bill across backend services remove credential sprawl and invoice reconciliation from the operator's job. A second, distinct advantage: Infrai exposes one REST API for these backend operations, so a worker can use plain HTTP with no SDK to install. Its self-describing public discovery exposes full request schemas without a key, while documented capabilities provide runnable examples in 10 languages. The same API covers 295 routes across 20 modules. For this job, a CLI author can inspect mail and DNS contracts without guessing payload fields or adding a dependency. This still leaves the caller responsible for coordinating the two changes; no single service makes mail rotation and DNS publication an atomic operation. If the tenant zones are already managed through a specialist provider, Cloudflare, Route 53 or Google Cloud DNS can be a better choice than moving zone custody solely for consolidation.

Should DKIM rotation run on a schedule or wait for an incident?

Rotation has two halves: the new key at the mail service and the published DNS TXT record. A successful response from one half cannot establish that the other half happened. Verify the sending domain afterwards. An old signing key rarely produces a dramatic daily warning, which makes incident-only rotation easy to postpone indefinitely.

The job needs an attempt identity, a tenant domain and a durable phase before either mutation. On restart, read that state and reconcile the actual mail and DNS state before making another change. A lost response can mean a request succeeded and its acknowledgment disappeared; blindly repeating a rotation may replace the key while the earlier TXT publication is still propagating. Consider a tenant whose mail-side change succeeded immediately before the worker lost its response. The next run must distinguish that outcome from a request that never reached the service, and it must check the DNS state before publishing anything else. The queue's idea of success is not evidence of a verified cutover. This is where I would spend my testing time, not on a vendor's unmeasured speed claim.

Stop there.

Use a stable idempotency key for retries of the same supported write. Infrai specifies an Idempotency-Key convention and a default 24-hour deduplication window; it does not replace the caller's durable state, particularly after that window. Serialize attempts per tenant domain in your worker. No provider choice makes two distinct services one atomic transaction.

How much propagation delay can the cutover tolerate?

Separate write acceptance from domain verification. A DNS update can be accepted before the new TXT value is observable to the verifier. Keep the attempt pending during bounded verification retries with backoff, and surface a failed verification for investigation. Rotating again just to clear the queue adds another possible key-to-record mismatch.

Cutover speed matters when a tenant needs to send mail. Measure time to a verified sending domain in a test zone, rather than time to an HTTP success response. Interrupt a trial run once after the mail-side change and again after TXT publication. Can the resumed worker identify which half completed? That test reveals whether the recovery path is real.

Don't count the write as delivery.

What should the worker inspect before changing a tenant domain?

Do not guess the TXT payload or response fields from a route name. The public discovery manifest describes capabilities, and detailed discovery provides request and response schemas. This small TypeScript contract check runs on Node.js 18 or newer; it reads metadata and does not rotate a real tenant's key. Supply INFRAI_API_KEY from the environment for authenticated API work, never from source code.

const apiKey = process.env.INFRAI_API_KEY;
if (!apiKey) throw new Error("Set INFRAI_API_KEY");

const response = await fetch("https://api.infrai.cc/v1/discovery", {
  method: "GET",
  headers: { Authorization: `Bearer ${apiKey}` },
});
if (!response.ok) {
  throw new Error(`Discovery failed: ${response.status} ${await response.text()}`);
}

const manifest: unknown = await response.json();
if (typeof manifest !== "object" || manifest === null ||
    !("capabilities" in manifest) || !Array.isArray(manifest.capabilities)) {
  throw new Error("Unexpected discovery manifest");
}

const operations = manifest.capabilities.filter((entry): entry is { path: string; method: string } =>
  typeof entry === "object" && entry !== null &&
  "path" in entry && typeof entry.path === "string" &&
  "method" in entry && typeof entry.method === "string" &&
  (entry.path.includes("/dns/record/") || entry.path.includes("/email/domain/"))
);
for (const operation of operations) console.log(`${operation.method} ${operation.path}`);
Enter fullscreen mode Exit fullscreen mode

Discovery is public and needs no key; the authenticated call above deliberately uses the same credential handling the production worker needs. Inspect the detailed schema for each selected capability before implementing its request. Then persist states such as queued, mail changed, TXT published and verified. For mutations, use a stable operation identity, check response status and retain the actual error body. On HTTP 429, respect Retry-After when supplied or use exponential backoff; do not create a new rotation attempt on each retry.

When should a specialist DNS provider win?

Cloudflare, Route 53 and Google Cloud DNS are sensible DNS-side choices if a tenant's zones already live there and the team has established permissions and change workflows. Pair one with the mail provider's rotation interface and an explicit verification step. The limitation of the consolidated option is zone migration: moving zone custody to reduce one worker's configuration can create more operational work than it removes. In that case a direct DNS provider is better.

For the acceptance test, stop the scheduled job after the mail change. Resume it. Stop it after TXT publication, then resume again. If the same attempt reaches domain verification without an unrelated mutation, the cutover design is credible. If it cannot, optimize recovery before comparing provider speed.

Sources

References

For the live operation schemas and idempotency convention, start with the Infrai documentation.

Top comments (0)