Domain relocation
A relocation renames your server from old.example to new.example. The operator, database, accounts, passwords, devices, guilds and history stay the same. The server and its peers rewrite every reference to the old name.
A relocation moves no data and asks users for nothing. To move a single account or guild between two servers, use migration instead. To close a server for good, see Sunset.
-
Announce. As a server admin:
POST /_telium/v1/admin/sunset{ "mode": "relocate", "new_domain": "new.example", "effective_at": <ms>, "message": "We are moving to new.example" }effective_atdefaults to 30 days from now. The server mints a successor signing key, signs a relocation record, publishes it asrelocationin/.well-known/telium/server, and pushes it to every server it knows, retrying with backoff. Peers verify it and wait. Nothing is renamed yet. -
Point DNS. Point
new.exampleat the server and keepold.examplepointed at it too. -
Restart under the new name. Set
server_name = "new.example"and updatepublic_base_url, then restart. At boot, before anything else reads the database, the server:- records each account’s OPAQUE credential identifier so existing passwords keep working,
- fails account migrations still in their cooling-off window (their grants name the old id; users start them again),
- rewrites the database,
- files the old name’s keys under
old.exampleand makes the successor key current, - writes a local
domain movedtombstone, clears the sunset notice, and queues anappliednotice to every peer.
-
Peers confirm. On its next contact with
new.example(the pushed notice, a discovery, or a recheck every ten minutes), each peer finds the successor key in the new name’s key document and applies the rewrite.
To change the destination or withdraw before the cutover, post again with a different new_domain, or with mode: "none". Withdrawing deletes the successor key, so the abandoned record can never be confirmed.
Sessions and access tokens survive the rename. A client that knew old.example reads moved_to from the old name’s discovery document, checks that its token still works, and updates its stored home. Logins typed as @alice:old.example map to the new name.
Keep the old name answering
Section titled “Keep the old name answering”After the cutover the server answers requests whose Host is a former name with a discovery document pointing at the new one, for /.well-known/telium/server and /_telium/v1/keys:
{ "server_name": "old.example", "api": "https://new.example", "moved_to": "new.example", "relocation": {}, "keys": {}}Keeping the old DNS name pointed at the server is enough. Everything in the document is signed by the old name’s keys, so you can also host it as a static file:
GET /_telium/v1/relocation/old.example/discoveryIf the old name disappears early:
| Peer state | Result |
|---|---|
| Already applied the relocation | Unaffected. It holds the record and the old keys. |
| Saw the announcement, not yet confirmed | Confirms once it reaches the new name. |
| Never heard of it | Cannot verify it. Its references to old.example go stale, and it meets @alice:new.example as a new id. |
Push the announcement weeks before the cutover so the last case stays rare.
What a peer checks
Section titled “What a peer checks”A peer applies a relocation only when both names vouch for it:
- The record is signed by a key
old.examplevouches for now, or by a retired key whileold.example’s own discovery document still publishes the same record. announced_atis no more than five minutes in the future.- A pushed notice (
POST /_telium/v1/relocation) comes fromold.exampleornew.example, never a third server. - The successor key’s signature verifies, and
new.example’s own key document publishes that key. Until it does, the record staysannouncedand nothing is rewritten.
Once applied, a second relocation for the same old name is refused with 409. A later owner of a lapsed old.example cannot take it back.
What gets rewritten
Section titled “What gets rewritten”Peers and the relocating server rewrite, in one transaction:
- columns whose value is the domain (
guild_server,sequencer,home_domain,originand similar), - ids ending in
:old.example, such as@alice:old.exampleand#alias:old.example, - JSON strings containing either, and
media://old.example/references, - attachment descriptors in message history (
origin,reference, and the fetchurl).
Requests to the old name are then sent to the new one, and ids under the old name resolve forward.
These are not rewritten:
- Signed data. Message signatures, co-signed tombstones and identity anchors keep the old id. They still verify with the old name’s historical key, which peers keep.
- Message text. What people typed stays as typed.
- Secrets and key material: hashes, tokens, ciphertexts,
server_keys,remote_keys, cold archives, the replication log, and migrations in flight. - Failover pairings. Pair your warm standby again under the new name.
A chain of relocations (a to b, then b to c) is followed up to eight hops.