Edge Hostnames and domains
Every slice answers at <user>-<slice>.ondrift.eu, over HTTPS, from the moment it exists. A custom domain adds a hostname of your own beside it, and fronting lets one slice hand one of its hostnames to another slice of yours.
On every request the router resolves the Host header to the slice that owns it, and that slice's rules are the ones applied. A host that names no slice, or names one that does not exist, is answered by the router itself:
HTTP/1.1 404 Not Found
Content-Type: application/json
{"error":"not found"}Custom domains
Declare each hostname as a domain block inside edge, labelled with the host:
edge {
domain "forms.example.org" {}
domain "tenants.example.org" {
wildcard = true # every subdomain reaches this slice
}
}drift apply attaches every declared host the slice does not have yet and prints one line for each:
✓ domain added: forms.example.org (verify with `drift slice domain verify forms.example.org` once DNS is live)and, when there was nothing to add, · domains in sync (2 declared). It never removes a hostname: one that is live on the slice and missing from the file stays attached and is named in the report at the end of the apply. Attaching is best effort, so a host that cannot be added is reported and the rest of the deploy carries on. drift plan lists each declared host as domain forms.example.org added, or unchanged when the slice already has it.
The free slice grants no custom domain, so a file with billing = "free" that declares a domain block is refused: Driftfile:2:13: Not the free slice: billing is "free", and the file declares 1 custom domain(s), and the free slice grants none. Make the shape smaller, or write billing = "monthly".
Adding a host does not finish the job. Point its DNS at the slice, publish the TXT record the platform asks for, then verify: that checks the record and issues the certificate.
| Command | What it does |
|---|---|
drift slice domain add <host> | Attach a hostname to the active slice and print the DNS records to create |
drift slice domain add <host> --wildcard | The same, and route every subdomain of host to this slice too |
drift slice domain verify <host> | Re-check the TXT record and, once it matches, issue the certificate |
drift slice domain list | Every hostname on the slice, with its status, whether it is a wildcard, and the TXT token while it is pending |
drift slice domain remove <host> | Detach the hostname, with its certificate and its routing |
verify reports the state it found. A host that is serving prints ✔ forms.example.org is live.; one that has just verified says the certificate is being issued and to check progress with drift slice domain list; any other state prints Status: and, where the platform gave one, Detail:.
wildcard is routing, not certificates.
wildcard = true in a domain block, or --wildcard on the command, sends every subdomain of a host to the slice, one label deep, and each subdomain still gets its own certificate on its first request. Telling the subdomains apart is your app's job: see A subdomain per tenant. drift apply attaches a new host with the wildcard its block declares; a host already on the slice keeps the setting it was attached with, so changing it means drift slice domain remove <host> and attaching it again.Fronting a linked slice
The hosts attribute of edge hands a hostname this slice owns to another slice of yours: a request for the host is served by the slice it maps to. One slice can then own the hostnames for a set of slices, each hostname answered by the slice that does the work.
edge {
links = ["admin"]
hosts = { "admin.example.com" = "admin" } # served by the linked slice
domain "admin.example.com" {}
}hosts is a map from a hostname to the slice that serves it. Two conditions hold, and both are checked when the apply sends the list:
- The host is a verified custom domain of this slice. Declare it with a
domainblock, verify it, then declare it inhosts. - The slice is linked from this slice, and belongs to the same account. Declare it in
links; the apply sets links before hosts, so one file can do both.
Each refusal names the command that fixes it. A host that is not a verified domain of this slice is refused with edge.hosts: "admin.example.com" is not a verified custom domain of this slice. Add it with `drift slice domain add admin.example.com`, verify it with `drift slice domain verify admin.example.com`, then declare it again.
A slice that is not linked is refused with edge.hosts: "admin.example.com" is to be served by "admin", which this slice does not link to. Declare it in edge.links, or run `drift slice link add admin`, then declare the host again.
A host appears once in the map, and an entry naming this slice itself is refused because the host already serves it. Each accepted host is printed as ✓ fronted host: admin.example.com → admin, and hosts = {} stops fronting all of them. drift plan lists each as host admin.example.com → admin added, with - for a host the file no longer names.
A fronted host is served under the target slice's rules, all of them. Its address allowlist, its site gate and its rate limit apply rather than this slice's, and its requests spend the target's per-minute budget. So fronting can never reach a slice around the rules it declares for itself. The link stays the authority: it is checked again whenever the host is resolved, and removing the link makes the host answer 404 straight away.
Limits
| Limit | Value |
|---|---|
| Verification | A DNS TXT record, the only method |
| Wildcard reach | One label: a wildcard on example.org covers a.example.org, not a.b.example.org |
| Certificates | One per hostname, issued on demand; there is no wildcard certificate |
| Who a fronted host may name | A slice this one links, in the same account |