Custom domains
What custom domains need in the cluster: a routing target, verification resolvers and certificates.
Team admins can add their own host names, such as shop.example.org, and route paths of them to workspaces. The
custom domains guide shows the user's side. This page is what the installation needs.
How a domain goes live
- A team admin adds the name. The console shows the records to set.
- The TXT record
_harthelm.<name>with the team's token proves ownership; it is the only record that does. Core asks the resolvers incustomDomains.resolvers, never the cluster's DNS, so an internal override cannot verify a domain. - A CNAME to
customDomains.cnameTarget, or A/AAAA records ofcustomDomains.publicIPsfor an apex name, routes traffic to your edge. Routing records never verify a domain. - Once verified, core renders one Ingress or HTTPRoute for the name in the release namespace (named
dom-…), with a certificate, to the router.
Verified domains are checked again daily. One whose TXT record is gone for customDomains.lapseDays (7 days)
lapses: it stops serving until a check finds the record again. When no resolver answers at all, nothing changes: your
own DNS outage is not the owner's doing.
Configure
customDomains:
cnameTarget: edge.example.net
issuer: {name: letsencrypt-http, kind: ClusterIssuer, group: cert-manager.io}| Value | Default | Meaning |
|---|---|---|
customDomains.enabled | true | false turns the feature off. |
customDomains.cnameTarget | A host that resolves to your edge, shown to users as the CNAME target. | |
customDomains.publicIPs | The edge's addresses, shown as A/AAAA records for apex names. | |
customDomains.resolvers | 1.1.1.1:53, 8.8.8.8:53, 9.9.9.9:53 | Resolvers for verification. Air-gapped installs name their own. |
customDomains.maxPerTeam | 20 | Domains per team. |
customDomains.createPerTeamPerHour | 10 | Domains a team may add per hour, deleted ones included. |
customDomains.claimDays | 7 | An unverified name is released after this. |
customDomains.lapseDays | 7 | A verified domain whose record is gone lapses after this. |
customDomains.limits | 100 MiB body, 60 s | The router's per-domain defaults and the ceilings a team admin may set. |
Certificates
Each verified domain gets a certificate one of three ways:
| Way | Values |
|---|---|
| Automated, from cert-manager | customDomains.issuer; needs rbac.certManager. HTTP-01 or DNS-01 is the issuer's business. Use a ClusterIssuer that does not need the user's DNS, for example HTTP-01 through your edge. |
| An existing wildcard | customDomains.wildcards: [{domain: "*.example.org", secretName: example-wildcard-tls}]. It covers names one label below; those get no certificate of their own. |
| Uploaded by the team | Team admins upload a certificate and key in the console. |
Without an issuer and without a covering wildcard, a domain serves only with an uploaded certificate.
With routing.edge gatewayAPI, TLS terminates on the Gateway's listeners: the Gateway needs a listener with a
certificate for every custom domain, which the chart cannot add for you. Prefer an Ingress controller when your teams
use custom domains.
Network
With networkPolicy.enabled the chart gives core an egress rule for each resolver (its address, UDP and TCP on its
port). The doctor's custom-domains check and the Capabilities page show whether the feature is usable.