Managed custom-domain connections: platform-owned verification + cert status, not just attach/detach Feature Request open
Migrated from github.com/carlosframework/platform issue #299, opened 2026-08-26. GitHub issues are closed for this repo; see AGENTS.md, "Work is tracked on amadan, not GitHub".
Still outstanding: The domains-list door is not safe for a real status poller at scale, and the console Settings page still uses pre-state wording.
---
Context
titogo (Tito Go) now offers per-account custom domains. On the CARLOS-fronted fleet it uses platform#151 (attach/detach a hostname on a route) to bind a verified domain to the account's edge route, with HTTP-01 cert issuance at the edge. That works and is deploying.
The gap
platform#151 is a raw doorknob — "attach hostname X to route Y" — and assumes the app has already (a) proven the domain is controlled by the claiming account, (b) confirmed DNS is actually pointed at the edge, and (c) that the cert will provision and the hostname is live. So titogo reimplements all of that app-side:
- DNS ownership proof — a per-claim TXT challenge + CNAME-chain verification
- Propagation detection — recursive view vs an authoritative-nameserver walk, to tell "wrong record" from "not visible yet"
- A status poller — re-checking pending claims on a 2-min→hourly cadence
- Lifecycle/failure states — attach-failed-retry, detach-failed-still-remove, cert-not-ready
Every app offering custom domains rebuilds exactly this. The platform already models domains-on-an-app (carlos domains list shows hostnames with status), so this extends an existing concept rather than greenfield.
Proposed: a managed custom-domain connection resource
Raise attach/detach to a managed connection:
- App POSTs a desired hostname on a route → platform returns the DNS records the user must set (CNAME target, or apex A/ALIAS + ownership TXT)
- Platform polls DNS itself, provisions + tracks the cert, and exposes ONE status:
pending-dns → verifying → issuing-cert → live → failed(+ a human-readable reason) - App receives status; detach as today
Division of responsibility this restores:
- App owns: who may claim a domain (account authz), which route/home-page it opens on, the canonical redirect. (Correctly app-specific.)
- Platform owns: proving control, DNS-pointing detection, cert provisioning, and status. (Infrastructure.)
Secondary: self-describing edge capability
The app currently can't ask "am I behind an edge that supports hostname attach?" — titogo gates on out-of-band flags (CarlosFronted / TITO_CUSTOM_DOMAINS / TITO_EDGE_ATTACH_URL). A managed-domain resource that's simply present-or-absent removes that guesswork.
HA / multi-edge note (relevant to the about-to-deploy HA work)
titogo's apex-domain path currently hard-pins a single edge IP (TITO_EDGE_IP) and verifies an apex A record by exact match against it. Under multi-edge HA that gives apex domains no failover and would falsely reject an apex correctly pointed at a different edge / anycast / ALIAS set. A managed-connection resource that owns the apex target (and returns the right ALIAS/anycast value per the HA topology) also solves this — otherwise every app hard-codes an edge IP that HA invalidates. Three specifics worth confirming for custom domains under HA: (1) does HA change the apex A-record target or move it to anycast/ALIAS; (2) is attach fleet-wide or per-edge; (3) is the issued cert / HTTP-01 challenge shared across edges.
Reference (titogo side that would collapse onto this)
internal/carlos/domains.go (verification + poller), the attach client in internal/carlos/router.go. Design record: docs/superpowers/specs/2026-08-11-custom-domains-design.md.
Filed on behalf of the Tito Go team (titogo custom-domains work, issue teamtito/titogo#1597).