QUANHEX.
Infrastructure

Implementing Custom Domains With Cloudflare for SaaS

How Cloudflare for SaaS enables white-label custom domain provisioning for multi-tenant applications — the setup, the pitfalls, and the certificate automation.

· 7 min read

Custom domains are a premium feature that every serious SaaS product eventually needs to offer. Your customers want their app at app.theirdomain.com, not theirdomain.yourapp.com. The technical challenge: you need to serve the right tenant’s content for arbitrary incoming hostnames, and you need valid SSL certificates for all of them.

Cloudflare for SaaS solves this at the infrastructure level in a way that would take weeks to replicate manually.

How It Works

Cloudflare for SaaS lets you issue SSL certificates and proxy traffic for custom hostnames belonging to your tenants, without those tenants needing to configure anything on your Cloudflare account.

The flow:

  1. Your customer points app.theirdomain.com at your Cloudflare-provided CNAME (e.g., proxy.yourapp.com)
  2. You provision a “Custom Hostname” for app.theirdomain.com via the Cloudflare API
  3. Cloudflare automatically issues a certificate via Let’s Encrypt or DigiCert
  4. Traffic arrives at your origin servers with the original hostname in the CF-Worker-Route header

Provisioning via API

const response = await fetch(
  `https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/custom_hostnames`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${CF_API_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      hostname: tenant.customDomain,
      ssl: {
        method: 'http',
        type: 'dv',
        settings: {
          http2: 'on',
          min_tls_version: '1.2',
        },
      },
    }),
  }
);

Store the returned custom_hostname_id on your tenant record. You’ll need it to check certificate status and delete the hostname when a tenant leaves.

Certificate Validation

DV certificates (the default) validate via HTTP challenge. Cloudflare handles the ACME challenge automatically as long as the CNAME is pointing to your Cloudflare zone. You just need to poll the custom hostname status until ssl.status is active.

If validation takes more than 15 minutes, the customer’s DNS isn’t propagated yet. Build a status UI so tenants know where they are in the provisioning flow.

Routing Tenant Traffic at the Origin

Once traffic reaches your origin, you need to identify which tenant the request is for. Two patterns:

Header-based routing: Cloudflare passes the original Host header. Your origin looks up the tenant by custom domain.

$host = $request->header('Host');
$tenant = Tenant::where('custom_domain', $host)->firstOrFail();

Fallback origin routing: For a Laravel application with multi-tenant middleware, this lookup happens early in the middleware stack and sets the tenant context for the duration of the request.

The Pricing Reality

Cloudflare for SaaS is not free. You pay per custom hostname per month above the free tier. Budget this cost into your pricing model before you offer the feature — at scale, it’s meaningful.

The alternative — running your own ACME cert management, nginx vhosts, and certificate renewal infrastructure — costs far more in engineering time. Cloudflare for SaaS is almost always the right trade at any reasonable scale.