← Technical library
architecturesecuritydraft

Tenant TLS and Custom Domains: Automating DNS, Certificates, and Ownership Checks

Chart
Cloudflare + Gateway API
Intent
mofu
Author
OpenTenant

A secure tenant-domain workflow spanning hostname ownership, Cloudflare DNS, Gateway API routing, cert-manager issuance, readiness, renewal, and offboarding.

Hostname to trusted endpoint

A domain is active only when the whole path agrees.

Ownership, DNS, route attachment, certificate coverage, and tenant identity are verified as one lifecycle.

Ownership

Unique hostname claim

A tenant-bound challenge proves control

Cloudflare DNS

Edge record

Proxy mode and record type match the domain purpose

Gateway API

Hostname route

Listener intersection binds one backend service

cert-manager

Certificate lifecycle

SAN coverage, renewal, and Secret readiness converge

External probe

SNI + tenant proof

The served certificate and response match the claim

hostname → durable unique ownerSNI → certificate SANpublic response → expected tenant release

Tenant TLS and domain automation

Direct answer

A tenant domain is not complete when a DNS record exists. The platform must prove hostname ownership, prevent duplicate claims, create the correct edge record, bind the hostname to exactly one Kubernetes route, issue a matching certificate, verify readiness, and remove access safely during suspension or deletion. OpenTenant automates that lifecycle with Cloudflare, Gateway API, and cert-manager while keeping every step tied to the tenant record.

Wildcard DNS can simplify routing for platform-owned subdomains. It must not be used as authorization for customer-owned domains.

Model domain ownership before provisioning

OpenTenant treats a hostname as a unique resource with an owner and a state machine:

requested → verification pending → verified → provisioning
→ certificate pending → route ready → active
→ suspended → released

A database-level uniqueness rule should prevent two tenants from claiming the same normalized hostname. Normalize case and trailing dots, reject public-suffix claims, and distinguish a platform subdomain such as acme.example.com from a customer domain such as app.customer.com.

For customer-owned domains, require a DNS challenge that contains a random, tenant-bound value. Recheck ownership before activation and periodically where the threat model requires it. A CNAME pointing at the platform proves routing intent only when the expected verification process defines it that way.

Cloudflare DNS: proxied versus DNS-only

Cloudflare documents two relevant modes for A, AAAA, and CNAME records. A proxied record returns Cloudflare anycast addresses and sends HTTP traffic through Cloudflare, enabling edge controls and hiding the origin address. A DNS-only record returns the actual origin and does not receive Cloudflare HTTP protection or analytics.

Cloudflare notes that verification, email, and some non-HTTP records should remain DNS-only. OpenTenant therefore compiles record type and proxy status from the domain purpose instead of enabling the proxy indiscriminately.

For platform subdomains, a wildcard record can reduce per-tenant DNS operations. The application layer still needs an explicit tenant hostname registry. For custom domains, OpenTenant creates or validates the required record without assuming control of the customer's entire zone.

Gateway API binds hostnames to services

Gateway API separates infrastructure-owned Gateways from application-owned Routes. An HTTPRoute names its hostnames and attaches to a compatible Gateway listener.

Gateway API hostname rules use hostname intersection between listeners and routes. A wildcard listener such as *.example.com can accept matching tenant routes, while a specific hostname gets the more specific match. For TLS termination, the intersected hostname must appear on the certificate and the client's SNI must match.

A tenant route can be rendered as:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: tenant-acme
  namespace: tenant-acme
spec:
  parentRefs:
    - name: public-gateway
      namespace: gateway-system
  hostnames:
    - acme.example.com
  rules:
    - backendRefs:
        - name: web
          port: 8080

Cross-namespace attachment requires deliberate Gateway allowedRoutes behavior and may require a ReferenceGrant for some references. OpenTenant generates route ownership from trusted tenant identity and does not allow an arbitrary values file to attach itself to another tenant's service.

cert-manager turns listeners into certificates

cert-manager's Gateway integration can create Certificate resources from annotated Gateway listeners. The listener must include a hostname, use TLS termination, and reference a Secret in the same namespace as the Gateway for the documented automatic flow.

That namespace rule affects architecture. A central Gateway may keep certificates in the gateway namespace, while tenant HTTPRoutes live in tenant namespaces. The platform should choose that topology explicitly rather than copying an Ingress pattern into Gateway API.

Gateway API also warns integrations not to infer wildcard certificate issuance merely from a wildcard hostname. Wildcard certificates should be deliberate Certificate resources, normally using DNS-01 validation, with tightly controlled access to the resulting private key.

Platform subdomains versus custom domains

Platform-owned subdomains

For tenant.platform.example, OpenTenant can validate the tenant slug, reserve the hostname, attach an HTTPRoute, and use a platform-managed wildcard or specific certificate strategy. Wildcard certificates reduce issuance volume but increase the impact of key compromise.

Customer-owned domains

For app.customer.com, OpenTenant records a verification challenge, waits for DNS proof, provisions the Cloudflare/SaaS or external DNS binding supported by the deployment profile, and requests a certificate containing that exact hostname. The route does not become active until DNS, certificate, and backend readiness agree.

Administrative hostnames

Separate customer traffic from operator and tenant-admin traffic. admin.tenant.example should have its own Access policy and, where practical, its own route and certificate reference. A wildcard certificate does not imply a wildcard authorization policy.

How OpenTenant reconciles the domain lifecycle

tenant requests hostname
  → normalize and reserve unique claim
  → issue ownership challenge when external
  → verify DNS control
  → create or validate Cloudflare record
  → render Gateway listener/route relationship
  → request or attach certificate
  → verify DNS, SNI, certificate chain, and backend
  → activate tenant route

The tenant status remains pending until every required controller reports readiness. A successful DNS API response is not enough; OpenTenant probes the public hostname, validates the certificate SAN and expiry, and confirms the response belongs to the expected tenant release.

Renewal, suspension, and deletion

Certificate issuance is only the first event. cert-manager renews certificates according to issuer and Certificate configuration, but the platform must monitor Certificate conditions and public expiry. Alert before the certificate enters a risky window, and test that a renewed Secret is actually served by the Gateway implementation.

Suspension should block edge access before stopping the application. Deletion should remove routes and Access policy, then DNS, then certificates and release resources according to retention policy. Keeping a DNS record pointed at a deleted or reassigned backend creates takeover risk.

Releasing a custom-domain claim should require proof that no active route, certificate, or edge binding remains. Consider a quarantine period before another tenant can claim the same hostname.

Security guardrails

  • Scope Cloudflare API tokens to the required account, zone, and operations.
  • Separate hostname verification records from proxied application records.
  • Store DNS and issuer credentials in Vault, not tenant chart values.
  • Reserve platform labels and Route attachment fields through admission policy.
  • Prevent duplicate normalized hostnames with durable uniqueness enforcement.
  • Limit access to wildcard private keys and prefer specific certificates for higher-risk boundaries.
  • Verify the served certificate and tenant identity from outside the cluster.
  • Record every ownership, DNS, route, and certificate transition in the tenant audit trail.

Verification checklist

  • Duplicate and mixed-case hostname claims are rejected.
  • Customer domains cannot activate before ownership verification.
  • DNS records use the intended proxied or DNS-only mode.
  • Gateway and HTTPRoute hostnames intersect as expected.
  • The served certificate contains the exact hostname and valid chain.
  • Tenant A cannot attach a route to tenant B's service.
  • Suspension removes access before workloads stop.
  • Renewal updates the certificate served at the edge.
  • Deletion leaves no dangling DNS or reusable route.

Sources

OpenTenant makes the domain, route, certificate, and tenant release one reconciled object—so “active” means the public security path is actually ready, not merely that an API call succeeded.

From chart installation to tenant operations.

See how OpenTenant models release, secrets, domain, and lifecycle boundaries.

Inspect Architecture