carlos / platform Public

App owners cannot choose their own hostname: every path to a custom domain requires operator credentials Feature Request open

Migrated from github.com/carlosframework/platform issue #102, opened 2026-08-07. GitHub issues are closed for this repo; see AGENTS.md, "Work is tracked on amadan, not GitHub".

Still outstanding: Instance-per-tenant apps still cannot self-serve an instance under a custom domain; -domain is refused in signed-in mode.

---

> Users should be able to set an arbitrary domain for their applications > without having access to the box, and without operator credentials.

The gap

An app owner cannot choose their own hostname on CARLOS today. The platform domain (<app>.<sqid>.<apps-domain>) is the only self-serve option. Every path to anything else requires operator authority:

  • carlos instances enable refuses -domain in signed-in mode (instances_cli.go:99) — the console pins the manifest to <sqid>.<apps-domain>. The flag exists only in store mode.
  • The manifest holds exactly one Domain string (internal/provision/provision.go:50), and every instance host is validated against it (internal/console/apiinstances.go:238). There is no "domains this account has attached" set.
  • Attaching a custom domain from the console is unbuilt (#82); the honest recipe today is carlos add on the box, an operator act.

So the entire namespace axis is operator-owned. That is a bigger gap than "custom domain attach is unbuilt" — #82 is one mechanism within it, not the whole of it.

Store mode is not the workaround

The available answer today is store mode: set CARLOS_DEPLOYMENT_BUCKET and write the manifest directly. That is not a lesser form of box access, it is a greater one — raw write credentials for the control plane of every account on the deployment. A tenant on someone else's CARLOS will never have them, and should not.

"You can run it from your laptop" is not a mitigation. The question is not where the command runs, it is what authority it requires.

This is the repo's own recorded rule, in CLAUDE.md:

> If a day-to-day task has no API/CLI command, that is a product gap, not a > license to drop to AWS.

Store mode is that drop. Reaching for it should be read the same way as reaching for the aws CLI: evidence of a missing capability, not a way to get the job done.

The principle worth adopting

Any capability an app owner needs must be expressible with app-owner authority. Where the only path is store mode, that is a gap to be filed rather than a route to be documented.

Stated generally because it is not specific to domains — it is the test to apply whenever the answer to "how does a user do X" turns out to be "an operator does it for them".

What done looks like

An account owner with no bucket credentials, and no shell on any box, can point a domain they control at their app and have it serve. Including instance space: an app whose model is instance-per-tenant should be able to mint instances under that domain, which is the question raised on #82 and still open.

Encountered as

Trying to serve echo from a domain other than the platform domain, from a laptop, as the app's owner. Every route led to store mode.