Skip to content

Client Domain Intake Checklist

Client Domain Intake, Zero-Downtime SSL Pre-Validation & Cutover Checklist

Lifecycle Scope & Architectural Alignment

This operational runbook governs the end-to-end procedure for onboarding a client’s external production domain onto SiteSwarm using Cloudflare for Platforms (Custom Hostnames) and Dual-Route Worker Bindings as specified in CLOUDFLARE_FOR_PLATFORMS_AND_DOMAIN_INGRESS.md.

Use this checklist after completing post-discovery KYC intake (CLIENT_INTAKE_CHECKLIST.md) and promoting the tenant application workspace (CLIENT_INTAKE_AND_ONBOARDING.md) to execute a zero-downtime DNS cutover while preserving the client’s existing registrar ownership, authoritative nameservers, and MX/SPF/DKIM/DMARC email records.

flowchart LR
Step1["1. Registrar & DNS Discovery"] --> Step2["2. Manifest & Lockfile Sync\n(pnpm run manifest:lock)"]
Step2 --> Step3["3. Terraform Provisioning\n(cloudflare_custom_hostname + ingress CNAME)"]
Step3 --> Step4["4. TXT DCV Pre-Validation\n(Zero-Downtime SSL Issuance)"]
Step4 --> Step5["5. Registrar CNAME Cutover\n(& Apex Flattening / Forwarding)"]
Step5 --> Step6["6. Dual-Route Edge Verification\n(Grey Cloud & O2O Resilience)"]

1. Registrar & DNS Discovery Assessment

Before provisioning infrastructure or sending DNS instructions to the client, audit the existing domain state to prevent email disruption or TLS handshake gaps:

  • Target Client Slug (<client_slug>): apps/<client_slug>/
  • Canonical Production Domain (<production_domain>): (e.g., greenleafbakery.com)
  • Authoritative DNS Provider & Registrar Identified: (e.g., GoDaddy, Namecheap, AWS Route 53, Porkbun, DNSimple, Squarespace, or external client Cloudflare Zone)
  • Authorized Technical Contact Verified: Confirm stakeholder or IT administrator holds edit permissions on the authoritative DNS zone.
  • Existing Email & Productivity Records Snapshot (MX, TXT, SPF, DKIM, DMARC):
    Terminal window
    dig +noall +answer <production_domain> MX
    dig +noall +answer <production_domain> TXT
    dig +noall +answer _dmarc.<production_domain> TXT
    • Invariant: Authoritative nameservers (NS) MUST NOT be migrated away from the client’s DNS provider unless explicitly requested, ensuring zero email disruption.
  • Current A, AAAA, and CNAME Baseline Recorded (For Instant Rollback):
    Terminal window
    dig +noall +answer <production_domain> A AAAA
    dig +noall +answer www.<production_domain> CNAME A AAAA
  • External Cloudflare Zone Detection (Grey Cloud vs. Orange-to-Orange O2O):
    • Check whether <production_domain> uses Cloudflare nameservers (*.ns.cloudflare.com):
      Terminal window
      dig +short <production_domain> NS
    • If the client is on their own Cloudflare account, recommend Grey Cloud (DNS-Only) for single-hop edge latency and guaranteed instant CMS cache invalidation while relying on SiteSwarm’s Dual-Route Binding so accidental Orange Cloud (O2O) toggles never break routing.
  • Apex (@) Capability Assessment:
    • Does the client’s DNS provider support CNAME flattening (ALIAS / ANAME) at the zone apex (@)?
    • [ ] Yes (Route 53, Porkbun, DNSimple, Cloudflare): Apex @ can point directly to <client_slug>-ingress.<platformZone>.
    • [ ] No (GoDaddy, Namecheap, legacy registrars): Configure www.<production_domain> as a standard CNAME to <client_slug>-ingress.<platformZone> and configure registrar root forwarding from <production_domain> to https://www.<production_domain>.

2. Manifest & Dual-Route Lockfile Synchronization

SiteSwarm’s root Terraform configuration (infra/main.tf) ingests external tenant domains directly from platform.lock.json via native HCL jsondecode(file("${path.module}/../platform.lock.json")) without external adapter scripts.

  • Declare productionDomain in apps/<client_slug>/swarm.config.ts:
    • Ensure deployment.productionDomain is set to the canonical external domain (<production_domain>).
  • Bind Dual Production Routes in apps/<client_slug>/wrangler.jsonc:
    • Under env.production.routes, bind both the Custom Hostname route and the per-client Platform Ingress target route:
      "production": {
      "name": "<worker-name>",
      "vars": {
      "ENVIRONMENT": "production"
      },
      "routes": [
      {
      "pattern": "<production_domain>",
      "custom_domain": true
      },
      {
      "pattern": "<client_slug>-ingress.jacobmiller22.com",
      "custom_domain": true
      }
      ]
      }
    • Under env.staging.routes, verify single-level hyphenated Universal SSL compliance (<client_slug>-staging.jacobmiller22.com).
  • Regenerate & Verify platform.lock.json:
    Terminal window
    pnpm run manifest:lock
    pnpm run manifest:check
    pnpm run swarm audit
    • Confirm platform.lock.json contains updated manifestSignatures["apps/<client_slug>/wrangler.jsonc"] and swarm audit reports Full Dual-Route Ingress Compliant.

3. Terraform Custom Hostname & Ingress CNAME Provisioning

Once platform.lock.json is synchronized, infra/main.tf automatically derives <client_slug> => <production_domain> into module.tenant_domain["<client_slug>"] (infra/modules/tenant-domain/).

  • Validate & Plan Terraform Changes:
    Terminal window
    terraform -chdir=infra fmt -check -recursive
    terraform -chdir=infra init
    terraform -chdir=infra validate
    terraform -chdir=infra plan -var-file=terraform.prod.tfvars
  • Verify Planned Resources for <client_slug>:
    • module.platform.cloudflare_custom_hostname_fallback_origin.platform: Anchors fallback.<platformZone> as the platform zone’s Cloudflare for SaaS Fallback Origin.
    • module.tenant_domain["<client_slug>"].cloudflare_custom_hostname.tenant: Registers <production_domain> with DV TLS (min_tls_version = "1.2", http2 = "on", tls13 = "on", method = "txt").
    • module.tenant_domain["<client_slug>"].cloudflare_record.ingress: Provisions proxied CNAME <client_slug>-ingress.<platformZone> pointing to fallback.<platformZone>.
  • Apply Terraform Configuration & Extract dns_intake_map Package:
    Terminal window
    terraform -chdir=infra apply -var-file=terraform.prod.tfvars
    terraform -chdir=infra output -json dns_intake_map | jq '."<client_slug>"'
  • Record Extracted Client DNS Handshake Package:
    • cname_target: <client_slug>-ingress.jacobmiller22.com
    • ownership_verification.name: _cf-custom-hostname.<production_domain>
    • ownership_verification.value: <txt-dcv-uuid-token>
    • ssl_validation_records: <ca-txt-validation-records>

4. Zero-Downtime TXT DCV & SSL Pre-Validation

While the client’s legacy site remains live at their existing host, pre-validate domain ownership and issue the edge TLS certificate so the subsequent CNAME cutover experiences zero TLS provisioning delay.

  • Send Pre-Validation TXT Records to Client DNS Contact:
    • Instruct the client (or execute on their DNS panel) to add the TXT record(s) from dns_intake_map["<client_slug>"]:
      • Record 1 (Hostname Ownership Verification):
        • Type: TXT
        • Host / Name: ownership_verification.name (e.g., _cf-custom-hostname)
        • Value: ownership_verification.value
        • TTL: Auto or 300 seconds
      • Record 2 (Certificate Authority DCV, if separate in ssl_validation_records):
        • Type: TXT
        • Host / Name: ssl_validation_records[0].txt_name
        • Value: ssl_validation_records[0].txt_value
  • Verify Public Authoritative TXT Propagation:
    Terminal window
    dig +short _cf-custom-hostname.<production_domain> TXT
  • Confirm Custom Hostname & SSL Status Transition to active:
    • Refresh Terraform state and inspect dns_intake_map:
      Terminal window
      terraform -chdir=infra refresh -var-file=terraform.prod.tfvars
      terraform -chdir=infra output -json dns_intake_map | jq '."<client_slug>" | {status, ssl_status}'
    • Gate: Do NOT proceed to Step 5 CNAME cutover until both status and ssl_status report "active".

5. Registrar CNAME Cutover & Apex Flattening

Once the Custom Hostname SSL certificate is active, cut over web traffic to the client’s dedicated ingress CNAME target:

  • Update Client DNS Records to Point to <client_slug>-ingress.<platformZone>:
    • Scenario A — Registrar Supports Apex CNAME Flattening (ALIAS / ANAME / Cloudflare DNS):
      • Point @ (<production_domain>) CNAME / ALIAS to <client_slug>-ingress.jacobmiller22.com.
      • Point www CNAME to <client_slug>-ingress.jacobmiller22.com.
      • If on Cloudflare DNS, set proxy status to Grey Cloud (DNS-Only) (recommended default).
    • Scenario B — Traditional Registrar Without Apex Flattening (GoDaddy, Namecheap):
      • Point www CNAME to <client_slug>-ingress.jacobmiller22.com.
      • Configure Registrar 301 Root Forwarding from <production_domain> to https://www.<production_domain>.
  • Verify Existing Email Records Remain Intact Post-Edit:
    Terminal window
    dig +noall +answer <production_domain> MX TXT

6. Dual-Route Edge Verification & Rollback Procedure

6.1 Post-Cutover Edge Verification

  • Verify Custom Hostname Route (Grey Cloud / Direct Edge Ingress):
    Terminal window
    curl -sSI https://<production_domain> | head -n 20
    • Confirm HTTP 200 OK, valid TLS certificate for <production_domain>, and expected Worker response headers.
  • Verify Target Hostname Route (O2O Fallback / Ingress Subdomain):
    Terminal window
    curl -sSI https://<client_slug>-ingress.jacobmiller22.com | head -n 20
    • Confirm HTTP 200 OK served by the exact same <client_slug> Worker.

6.2 Emergency Rollback Procedure

If an unexpected application issue occurs during cutover:

  1. Restore the client’s DNS A/AAAA/CNAME record at their registrar to the baseline value recorded in Step 1.
  2. Because TTL was lowered prior to cutover and authoritative nameservers were never changed, traffic reverts to the legacy host immediately without touching MX email delivery or deleting the pre-validated Custom Hostname in Cloudflare.
  3. For planned tenant offboarding and data portability export, follow CLIENT_OFFBOARDING.md.

7. Decisions Intentionally Deferred

Per AGENTS.md §6.4 (Minimal Viable Abstraction & Deferred Decisions), the following capabilities are intentionally deferred until operational scale warrants them:

  1. Automated Registrar API DNS Mutation: SiteSwarm intentionally outputs structured dns_intake_map verification records rather than storing third-party registrar OAuth credentials (GoDaddy/Namecheap API tokens) inside platform state.
  2. Multi-Hostname Array per Tenant (www + Apex Custom Hostname Fan-Out in platform.lock.json): infra/main.tf currently derives the primary external production domain per tenant slug from platform.lock.json. Multi-domain fan-out per tenant is deferred until a tenant requires multiple distinct external domains mapped to the same Worker without registrar forwarding.
  3. Automated Polling Webhook for DCV State Transitions: DCV status transitions (pending $\to$ active) are verified via Terraform state refresh during onboarding rather than running a dedicated background polling daemon.