When you use Auth0 for authentication, you can use a custom domain to make your login page respect your branding and look more professional. This is usually accomplished with a simple CNAME record pointing to the Auth0 domain. It's a straightforward process if you use Auth0's managed certificates. However, depending on the popularity of your service you might find yourself under auth attacks that might cause your auth to be down. The way to fix this is by proxying your auth through Cloudflare.

This is a simple process, but the docs have a number of errors that do get on the way. Here's how to do it with terraform:

variable "custom_domain" {
  type = string
  default = "auth.myservice.com"
}

variable "cloudflare_account_id" {
  type = string
  default = "1234567890"
}

variable "cloudflare_zone_id" {
  type = string
  default = "1234567890"
}

variable "tenant" {
  type = string
  default = "myservice-prod"
}

# first create the custom domain
resource "auth0_custom_domain" "custom_domain" {
  domain                  = var.custom_domain
  custom_client_ip_header = "true-client-ip"
  type                    = "self_managed_certs"
}

# then create the verification record
resource "cloudflare_record" "custom_domain_verification_record" {
  zone_id    = var.cloudflare_zone_id
  name       = "_cf-custom-hostname.${var.tenant}"
  value      = auth0_custom_domain.custom_domain.verification[0].methods[0].record
  type       = "TXT"
  depends_on = [auth0_custom_domain.custom_domain]
}

# verify the custom domain
resource "auth0_custom_domain_verification" "custom_domain_verification" {
  custom_domain_id = auth0_custom_domain.custom_domain.id
  timeouts { create = "15m" }
  depends_on = [cloudflare_record.custom_domain_verification_record]
}

# create a CNAME record for the custom domain pointing to the Auth0 origin returned by custom domain verification
resource "cloudflare_record" "custom_domain_record" {
  zone_id    = var.cloudflare_zone_id
  name       = auth0_custom_domain.custom_domain.domain
  value      = auth0_custom_domain_verification.custom_domain_verification.origin_domain_name
  type       = "CNAME"
  proxied    = true
  depends_on = [auth0_custom_domain_verification.custom_domain_verification]
}

# create a page rule that overrides the host header, passing the True-Client-IP header
resource "cloudflare_page_rule" "reverse_proxy" {
  zone_id = var.cloudflare_zone_id
  target  = "${var.custom_domain}/*"
  actions {
    host_header_override  = auth0_custom_domain_verification.custom_domain_verification.origin_domain_name
    true_client_ip_header = "on"
  }
  depends_on = [auth0_custom_domain_verification.custom_domain_verification]
}

# create a worker that will reverse proxy the request to the Auth0 origin
resource "cloudflare_worker_script" "reverse_proxy" {
  account_id = var.cloudflare_account_id
  name       = "reverse-proxy-worker-${var.tenant}"
  content = templatefile("${path.module}/files/workers/reverse_proxy.js", {
    cname_api_key = auth0_custom_domain_verification.custom_domain_verification.cname_api_key
  })
  depends_on = [auth0_custom_domain_verification.custom_domain_verification]
}

# create a worker route that will route all requests to the worker
resource "cloudflare_worker_route" "reverse_proxy" {
  zone_id     = var.cloudflare_zone_id
  pattern     = "${var.custom_domain}/*"
  script_name = cloudflare_worker_script.reverse_proxy.name
  depends_on  = [cloudflare_worker_script.reverse_proxy]
}

For the worker script, you can use the following:

addEventListener('fetch', (event) => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  request = new Request(request);
  request.headers.set('cname-api-key', '${cname_api_key}');
  return await fetch(request);
}

With this setup, you can now use your custom domain proxied through Cloudflare for Auth0 authentication.