DNS and TLS
The console host and the workspace domain, their records and certificates, the edge, in-cluster TLS and trusted proxies.
Two domains
Harthelm serves two kinds of hosts:
| Host | Value | Serves |
|---|---|---|
The console, console.example.com | platform.host | the console, the API, sign-in |
*.example.net | platform.workspaceDomain | dev URLs <id>-<port>.example.net, the IDE ide-<id>.example.net, the hosts of workspace services, and since 1.4.0 the hosts of managed services ms-<n>.example.net |
They must be different registrable domains, not a domain and its subdomain: workspaces run code your users write,
and that code must not be able to set cookies for the console. The chart refuses only the nested case
(console.example.com with example.com); it cannot know the public suffix list, so the rest is up to you.
Records
Point both names at your Ingress controller or Gateway:
console.example.com. A 203.0.113.10
*.example.net. A 203.0.113.10
edge.example.net. A 203.0.113.10edge.example.net is optional: a name your users can CNAME their custom domains
to (customDomains.cnameTarget).
Certificates
The workspace domain needs a wildcard certificate. Choose one of two ways.
The chart creates two Certificates. The issuer must solve DNS-01 for the wildcard.
routing:
tls:
certManager:
enabled: true
issuerRef: {name: letsencrypt-dns, kind: ClusterIssuer, group: cert-manager.io}See routing.tls.certManager.enabled and routing.tls.certManager.issuerRef. The platform track pages show
DNS-01 for Route 53, Azure DNS and Cloud DNS.
The edge
routing.edge decides which objects route the two hosts:
| Value | Result |
|---|---|
auto (default) | Gateway API if the HTTPRoute CRD exists and routing.gatewayAPI.parentRefs is set, else Ingress. |
ingress | Two Ingresses with routing.ingress.className and routing.ingress.annotations. |
gatewayAPI | Two HTTPRoutes attached to routing.gatewayAPI.parentRefs. TLS belongs to the Gateway's listeners, so the Gateway needs a certificate for both hosts. |
none | Nothing. Route the console host to the Service <release>-core and *.<workspace domain> to <release>-router (both port 8080) yourself. |
Whatever routes the traffic must pass WebSockets (the IDE and terminals), and must run as pods in the cluster: core
and the router accept traffic on port 8080 only from pods in the namespaces networkPolicy.edgeNamespaceSelector
selects (empty: any namespace).
With gatewayAPI, routing.gatewayAPI.timeouts.request and
routing.gatewayAPI.timeouts.backendRequest apply where your implementation honours them.
Trusted proxies
Set trustedProxies to the addresses of the pods in front of core and the router (the Ingress controller's or
Gateway's pods). Only from those peers do core and the router believe X-Forwarded-For, so the per-address limits
(for example 30 CLI sign-ins per address in 10 minutes), audit rows and the sign-in approval page see the real client.
trustedProxies: [10.0.0.0/16]Empty, nobody is trusted and every request seems to come from the ingress pod, so the sign-in limit is shared by the
whole installation. Never set 0.0.0.0/0. While in-cluster TLS is off, workspace pods can reach core's plain port:
then list only the ingress pods' own addresses, never the whole pod range.
When a cloud load balancer sits in front of the controller, keep the client address with its client IP preservation or proxy protocol; the EKS track shows how.
In-cluster TLS
internal.tls encrypts the traffic inside the cluster: between the routers, workspace agents, hart and git in
workspaces on one side and core on the other.
| Mode | Effect |
|---|---|
auto (default) | On when the cluster serves cert-manager, else off. |
on | Always; cert-manager must be installed. |
off | Plain HTTP inside the cluster. |
Without internal.tls.issuerRef the chart makes its own CA with cert-manager (ten years, the key kept on renewal)
and a server certificate for core that renews itself; core and every client reload renewed files without a restart. A
named issuer must put ca.crt into its Secrets: a CA or Vault issuer, not ACME.
While it is on, workspace pods reach core only on its TLS ports (8443, 8444 and the git proxy's 8445). A workspace pod started before you switched it on reaches core again after its next restart.
Check it:
kubectl -n harthelm-system get certificate
hart admin doctorThe doctor's internal-tls check fails when the certificate is missing or expires within 14 days.