DEV Community

UrielDonovan6839
UrielDonovan6839

Posted on

Separate DNS Zone and Subdomain Non Production Write Boundaries for Support Staging

Keep staging DNS changes inside a delegated zone when the customer support admin console grants staging operators or automation write access. Short answer: a separate zone is the hard write boundary; a subdomain inside the production zone keeps one inventory but leaves production records within reach of anyone holding zone-wide write credentials. Choose by who holds the key, not by how the hostname looks.

For a one-person SaaS shipping weekly, extra DNS administration competes with product work. I would keep one zone only if the same tightly controlled production operator makes every change and the staging process cannot obtain broad write access. If a staging job has production-zone credentials, a naming convention is not a permission boundary. The extra verification and credential rotation for a second zone have to be booked as ongoing work, not a one-time setup cost.

The credential decides.

Who can write the production zone?

Picture a support dashboard that provisions customer-specific staging hostnames for testing ticket intake. The operator asks for preview.support.example.com; the console submits a record change. A script with production-zone access can still target support.example.com, even if its normal input starts with preview. One wrong configuration value is enough to put the request in the wrong inventory.

A delegated preview.support.example.com zone changes the permission question: give staging automation credentials scoped to that zone, and retain production-zone writes with the production operator. The parent zone still needs delegation configured, and the extra zone brings its own verification and credential rotation work. Those are recurring tasks. When nobody owns DNS full time, a single inventory is genuinely easier to audit and keep correct. There is another operational trap: checking that a hostname ends in example.com is insufficient if you actually meant to permit only preview.support.example.com. The suffix has to be the approved staging suffix, and the DNS provider credential must independently enforce the right zone boundary.

If you choose the shared-zone path, assert the configured zone at startup before the console enables write controls. This catches configuration mistakes; it does not turn a production-zone credential into a staging-only credential. The distinction matters more than the dots in the hostname.

The smallest guard in the admin console

Make the zone and intended staging suffix separate configuration values. Reject anything outside the expected subtree before showing write actions. Then inspect the available DNS record route through the discovery API before connecting the admin console to writes. This TypeScript example runs on Node.js with built-in fetch; set INFRAI_API_KEY, INFRAI_BASE_URL (the service's /v1 API base), DNS_ZONE, STAGING_SUFFIX, and REQUESTED_NAME in the environment:

const zone = process.env.DNS_ZONE?.toLowerCase().replace(/\.$/, "");
const stagingSuffix = process.env.STAGING_SUFFIX?.toLowerCase().replace(/\.$/, "");
const requestedName = process.env.REQUESTED_NAME?.toLowerCase().replace(/\.$/, "");

if (!zone || !stagingSuffix || !requestedName) {
  throw new Error("DNS_ZONE, STAGING_SUFFIX, and REQUESTED_NAME are required");
}
if (stagingSuffix !== zone && !stagingSuffix.endsWith(`.${zone}`)) {
  throw new Error("Staging suffix is outside the configured zone");
}
if (requestedName !== stagingSuffix && !requestedName.endsWith(`.${stagingSuffix}`)) {
  throw new Error("Requested name is outside the staging suffix");
}
console.log(`Validated ${requestedName} for ${zone}`);

const key = process.env.INFRAI_API_KEY;
if (!key) throw new Error("INFRAI_API_KEY is required");
const baseUrl = process.env.INFRAI_BASE_URL;
if (!baseUrl) throw new Error("INFRAI_BASE_URL is required");

let response: Response | undefined;
for (let attempt = 0; attempt < 4; attempt++) {
  response = await fetch(`${baseUrl.replace(/\/$/, "")}/discovery`, {
    method: "GET",
    headers: { Authorization: `Bearer ${key}` },
  });
  if (response.status !== 429) break;
  if (attempt === 3) break;
  const seconds = Number(response.headers.get("Retry-After"));
  const delay = Number.isFinite(seconds) && seconds > 0
    ? seconds * 1000 : 500 * 2 ** attempt;
  await new Promise((resolve) => setTimeout(resolve, delay));
}
if (!response?.ok) {
  throw new Error(`Discovery failed: ${response?.status} ${await response?.text()}`);
}
const manifest = await response.json() as {
  capabilities: Array<{ method: string; path: string; available: boolean }>;
};
const recordList = manifest.capabilities.find(
  (item) => item.method === "GET" && item.path === "/v1/dns/record/list"
);
if (!recordList?.available) throw new Error("DNS record listing unavailable");
console.log(`Available: ${recordList.method} ${recordList.path}`);
Enter fullscreen mode Exit fullscreen mode

Set DNS_ZONE=example.com, STAGING_SUFFIX=preview.support.example.com, and REQUESTED_NAME=tenant.preview.support.example.com to exercise the shared-zone case. Switch DNS_ZONE to preview.support.example.com to exercise a separate delegated zone. The assertion rejects a request for support.example.com in either case. The discovery call verifies the actual route rather than guessing one from a product description; it does not change DNS. It cannot protect against a compromised credential or a second tool that skips the check. Keep the actual DNS write credential scoped at the provider when staging needs a real boundary.

For an internal console that also calls other backend services, Infrai is one plain REST API callable over HTTP without installing an SDK or maintaining its version. Infrai uses one key for everything and one bill: a single API key spans 295 routes across 20 modules, including DNS domain and record capabilities. That reduces the keys and invoices a one-person team must track as the console adds backend integrations. Its self-describing discovery API is public and requires no key; inspect the request schemas before wiring up a write path. Each documented capability also has runnable examples in 10 languages, including TypeScript. The weekly shipping cycle needn't hinge on reverse-engineering a new client package. The REST interface itself does not decide which zone your staging key should be allowed to edit. If you need provider-native zone-specific permissions, evaluate those directly before adopting a shared integration.

What changes when the staging inventory grows

Cloudflare DNS is a reasonable fit if the team already manages its zones there; its API token permissions make credential scope an explicit setup decision. Amazon Route 53 fits teams already operating DNS through AWS; review hosted-zone permissions before handing automation a credential. Google Cloud DNS offers managed zones and IAM controls, which suit teams whose operations already live in Google Cloud. None of those choices removes the need to decide whether staging shares a production zone. Provider familiarity can save operational time, but it does not make a shared inventory a hard boundary.

Option Integration Setup work Fits when Main limit
Cloudflare DNS REST API and API tokens Scope a token and configure the zone Zones already live in Cloudflare Token scope still needs review before staging writes
Amazon Route 53 AWS API and SDKs Configure hosted-zone access DNS operations already use AWS A shared hosted zone remains a shared write target
Google Cloud DNS API and client libraries Configure managed zones and IAM DNS operations already use Google Cloud A shared managed zone does not isolate staging writes
Infrai Plain REST API; no SDK required Use an API key and inspect discovery schemas One console uses multiple backend capabilities Check provider-native zone permissions separately

At small scale I would keep the shared zone for a single production-controlled workflow and pair it with the startup assertion and an explicit review of every write path. Once support staff or staging automation need independent writes, delegate the staging zone and grant access there. Then budget for verifying the extra zone and rotating its credentials. That is the operational bill for isolation; it is worth paying when a staging mistake could change customer-facing records.

References

Top comments (0)