Files
ihasmail/stalwart-servers.example.json
T
jcoffey-dev 171c11fc92 Choose the Stalwart by the domain somebody signs in with
One ihasmail in front of several Stalwarts, from #238. STALWART_URL stays
required and stays the default, so an installation that sets nothing behaves
exactly as it always has -- the mapping only adds domains that go elsewhere.

An unlisted domain goes to the default. So does a bare username, which
Stalwart accepts and which has no domain to map at all.

A listed domain never falls back. If its server is unreachable that sign-in
fails rather than retrying against the default, because falling back would
authenticate somebody against a server their domain was deliberately routed
away from -- and if the same account name existed there, they would land in
another tenant's mailbox. The fallback is a decision about unmapped domains,
taken before any network call, not a recovery path.

Smaller than it sounds because only four places read config.stalwartUrl, all
in upstream.ts. The upstream session now records which server issued it, since
the relative URLs inside it only mean anything against that server, and every
route already holding a session gets the right upstream without a second
lookup. The client is untouched: it talks to one proxy and never learns there
is more than one server behind it, which is exactly why this is small and
several-servers-at-once is not.

The upstream is derived from the username rather than stored on the session,
so a mapping change takes effect on restart instead of being frozen into
sessions that outlive it.

Validated at boot the way the settings policy is: malformed JSON, a duplicate
domain once normalised, a missing file or a value that is not an http(s) URL
all stop the server. Domains are lower-cased and stripped of a trailing dot,
because that is how one arrives off a username and comparing them any other
way means a mapping that silently never matches. The servers themselves are
not contacted -- a mapping is a routing table, not a health check, and one
customer's outage must not stop ihasmail starting for the other four.

Eight tests on the routing, two on the shipped example, and the four refusals
checked by hand against a real config load.
2026-09-02 14:18:50 -07:00

26 lines
1.1 KiB
JSON

{
"_comment": [
"Optional: which Stalwart a domain signs in to.",
"",
"STALWART_URL stays required and stays the default. This file only adds",
"domains that go somewhere else -- delete it and nothing changes.",
"",
"Point at it with STALWART_SERVERS_FILE=/etc/ihasmail/servers.json and mount",
"it read-only. Read once at startup, so editing it means restarting.",
"",
"A domain that is not listed here, and a bare username with no domain at",
"all, go to STALWART_URL. A domain that IS listed never falls back: if its",
"server is unreachable that sign-in fails, because falling back would",
"authenticate somebody against a server their domain was routed away from.",
"",
"Keys are lower-cased and stripped of a trailing dot when read. Malformed",
"JSON, a duplicate domain, or a value that is not an http(s) URL stops the",
"server at startup rather than failing quietly at somebody's sign-in.",
"",
"Docs: https://docs.ihasmail.org/configure/#several-stalwart-servers"
],
"example.com": "https://mail.example.com",
"customer-b.test": "https://jmap.customer-b.test"
}