feat(base): a reset of the keys without the phrase, and the keys' proof key for a password that signs in (ADR 0020, D31–D34)

An account that signs in with SimpleLogin alone, its password and its
recovery phrase both lost, asks for new keys with a SimpleLogin sign-in
(`keys.startReset`); another sign-in carries it out 72 hours later
(`keys.completeReset`, `notDue` with when before), with the same keys
rewrapped where the device still holds them (D33). No mail: every
signed-in device shows it, and any right proof of the password's or the
phrase's key, or a mend, calls it off; `keys.callOffResets` takes the
password's proof alone (D32). The row is ADR 0017's account reset of kind
`account`, so no migration; ADR 0017's reset by mail now takes only an
account whose password signs in.

An account with ADR 0017's password that added SimpleLogin had keys but
no proof key, so no new device signed in with SimpleLogin could open
them: `password.setProofKey` sets the one that same password makes, with
the owner's proof binding it (D34), and ADR 0017's new password takes it
away. Only an account that signs in with SimpleLogin alone changes
through `keys`. `simpleLogin.complete` says whether the password signs
in, whether the keys have the proof key, and when a reset takes effect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-24 21:51:00 +02:00
commit fe2ef02c92
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -1,6 +1,6 @@
# ADR 0020: Signing in with SimpleLogin only
- **Status:** decided 23 Oct 2026, by the developer (D1–D20 below; D21–D30 on 24
- **Status:** decided 23 Oct 2026, by the developer (D1–D20 below; D21–D34 on 24
Oct), the *Proposal* with it (D15), as D18 to D20 change it and D24 drops the
cut-off's machinery (D8's code, D10, D22, 10's `ANONYMOUS_SESSIONS_END`, 11, step 5).
- **Built (23 Oct 2026), step 1:** the forwarding page (3),
@ -113,6 +113,18 @@
device opens the keys with the phrase, wraps them under the new password and signs the
phrase's proof bound to it (`keys.beginPhrase`, `keys.resetPassword`); the keys stay,
every other session ends.
Then the reset of the keys without the phrase, the server's half (D31–D33):
`keys.startReset` with a SimpleLogin sign-in, taken, `keys.completeReset` once due
with another (`notDue` with when, before), and `keys.callOffResets` with the
password's proof (the new purpose `call off resets`), each through the register; every
right proof of the password's or the phrase's key, and a mend's, calls the reset off.
ADR 0017's reset by mail takes only an account whose password signs in. And D34's
`password.setProofKey`, the owner's proof binding the key (the new purpose `keys proof
key`); ADR 0017's new password takes the key away. Only an account that signs in with
SimpleLogin alone changes through `keys` (`opensKeysAlone`). `simpleLogin.complete`
says whether the password signs in too (`passwordSignsIn`), whether the keys have the
proof key (`hasProofKey`) and when a reset takes effect (`accountResetAt`). No
migration: the reset is ADR 0017's `account_reset` row of kind `account`.
- **Builds on:** ADR 0010 (email sign-in), ADR 0011 (profile pages), ADR 0016 (the
register), ADR 0017 (a password, TOTP and the keys).
- **Changes:** ADR 0017's way in on an instance that offers SimpleLogin (its keys, their
@ -302,6 +314,38 @@ against app.simplelogin.io on 23 Oct:
own): the same field, checking as it is typed, for password sign-up, setting a
password, SimpleLogin's sign-up and its keys step; the handle the instance suggested
counts as free without asking.
- **D31 A reset of the keys after 72 hours, with a banner** (24 Oct, evening,
recommended, over 7 and 14 days): the password and the recovery phrase both lost, a
SimpleLogin sign-in asks for new keys (`keys.startReset`), which a SimpleLogin sign-in
carries out 72 hours later (`keys.completeReset`). No mail tells the owner, as
SimpleLogin is their way in and its mailbox may be what was taken over: every
signed-in device of theirs shows a banner meanwhile, and the next SimpleLogin sign-in
says when it takes effect. Any proof of the password or the phrase calls it off: the
keys opened on any device, a lost password set with the phrase, a link mended. The row
is ADR 0017's account reset (kind `account`, with its lapses, no hold-outs); only an
account that signs in with SimpleLogin alone has one this way, and ADR 0017's reset by
mail is for passwords that sign in alone, so a mailbox never resets a SimpleLogin
account. The handle, the profile, the link and what was published stay; what was
encrypted under keys no device holds any more is lost (Learn shows it as Locked).
- **D32 Called off with the password's proof** (24 Oct, recommended, over the password
and a fresh SimpleLogin sign-in, which guards little, as a SimpleLogin account taken
over is what starts a reset, and over the session alone, which would let a thief who
holds one block the owner): `keys.callOffResets` from a signed-in device, under the
banner.
- **D33 A device that holds the keys keeps them** (24 Oct, recommended, over new keys
always): finishing the reset there wraps the same keys under the new password and
phrase, so nothing is lost.
- **D34 A password that signs in gets the keys' proof key** (24 Oct, recommended, over
leaving the gap for later, and over unlocking with SRP): found while planning D31, an
account with ADR 0017's password that added SimpleLogin had keys but no proof key, so
no new device signed in with SimpleLogin could open them. Its password and a code (ADR
0017's owner proof) set the proof key that same password makes
(`password.setProofKey`): on adding SimpleLogin, and again after a new password of ADR
0017's, which takes it away, as it was made of the old one (over carrying it in ADR
0017's new password, which would change those proofs' digests). Such an account opens
its keys through `keys.unlock` but changes nothing through `keys`: its changes and
resets stay ADR 0017's, which keep SRP's verifier in step. `simpleLogin.complete` says
whether the password signs in and has the proof key.
- **Also (23 Oct):** the developer's own account moves by adding SimpleLogin to it while
signed in with GitHub; the instance's SimpleLogin app goes up for approval once
halkyon.app/learn exists, before learn.halkyon.eu switches.