0028: Switch sign-in methods and registration at run time; communities join by invite code
- Status: Accepted — one more switch, the proof-of-work before a code by email, since ADR 0037; the switch of the password does not cover the console’s own sign-in, which signs in with the password whatever the switch says, since ADR 0042
- Date: 2026-10-18
- Amends: ADR 0026 — a provider with secrets can still be off; ADR 0024 — signing up may need an invite code, or be closed
Context
ADR 0026 lets a deployment offer Google, GitHub and an OpenID Connect issuer by giving them secrets — a redeploy for every change. Opening Tò He to a few communities needs more, and sooner: let one community in this week and not everyone; stop sign-ups for a while after a wave of abuse; turn a provider off when it misbehaves, without touching the cluster. Leaderboards per community (D-09) need to know which community an account came with. And a switch that only some ways of creating an account obey is a back door.
Decision
- Two layers. The deployment decides what can exist — a provider needs its secrets, signing up by email needs
email (ADR 0022). The admin console decides what is on, kept in the database (
admin.settings), read through one service the Identity module asks: email and password, each configured provider, and the registration mode. The one API process (ADR 0027) caches them and forgets the cache whenever the console saves, so a change holds at once. - Turning a method off stops both signing in and signing up with it — for email and password also a forgotten password, since a new one signs in; nothing else changes — a linked provider stays linked, a password stays set, step-up still uses either. Two guards: one method at least stays on, and the admin who switches keeps a way in. The console says how many accounts depend on a method before it goes off.
- Registration modes:
open— anyone signs up;invite— signing up needs an invite code;closed— nobody new, everyone else signs in. Every way an account is made obeys it: signing up by email, when it starts and when its code comes back, and the first sign-in with a provider. - Communities and invite codes. A community is a name. Its codes may expire, may be used a set number of times,
and can be revoked; a code is counted in the same transaction that creates the account, so its limit holds when two
people use it at once. The account remembers the community it came with — one, for now — and in
openmode a code is welcome but not needed. Codes travel as links:/register?invite=CODE. - Every change — a method, the mode, a community, a code — needs step-up level 2 and lands in the audit log
(ADR 0027);
admin.settings.write(owners and admins) allows them.
Consequences
GET /api/configtells the hub which methods are on and the registration mode; the hub shows only what works, and an invite field when a code is needed — or welcome when one is not.- A deployment can run on providers alone: with email and password off, accounts that only have a password cannot sign in until it is on again or they get a provider linked — which is why the console counts them first.
- Leaderboards per community (D-09) and statistics per community in the console can rely on
community_id. - An account in several communities waits for a need; it would change the remembering, not the codes.
Alternatives considered
- Configuration only (ADR 0026’s layer): every switch a deploy, and an incident waits for one.
- A registration toggle per method (Google sign-ups closed, password sign-ups open…): a matrix nobody asked for; the mode and the methods already cover the needs above.
- Invite codes per person (one code, one account): heavier to hand out to a community at once; a code with a limit of uses and a revoke covers the same when needed.
- Allow-lists of email domains: communities here are groups of friends and families, not organisations with a domain.