docs(auth): the fourth reading, and the rules as they stand (ADR 0017)
ADR 0017 records what the fourth reading found and what was done, and states who changes what of an account with which proofs, as a table the full reading can check against; the module README and Learn's AGENTS.md follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
f154b7ea7c
commit
858fffdce3
1 changed files with 75 additions and 12 deletions
|
|
@ -389,6 +389,61 @@ The findings, and what was done:
|
|||
subject names it ("K7QX-M2PD: your Halkyon Learn code to delete your account"), and the
|
||||
sign-up mail says it also gives a password to an account with that address and none.
|
||||
|
||||
### Fourth reading (21 Oct 2026)
|
||||
|
||||
A fourth independent reading, of the third's fixes (`a45842f..263c171`), found its five
|
||||
findings closed, and two older gaps in Proton's rule: the first password and the first
|
||||
authenticator. What was done (`18ab2ee`, `f3c8706`, `403b88c`):
|
||||
|
||||
1. **A stolen session made a GitHub-only account, or an address account without a
|
||||
password, its own** (high): `password.set` took the session alone, so the thief set
|
||||
their address (or, with the owner's address, their password) and their authenticator;
|
||||
GitHub then refused the owner. A first password now takes a fresh proof of the
|
||||
account's existing way in: a code mailed to the account's own address for it
|
||||
(`EmailCodePurpose.firstPassword`), or, for an account that signs in with GitHub
|
||||
alone, a GitHub sign-in of the last 10 minutes (`gitHubSignInFreshFor`: the session's
|
||||
method and creation time, where the session lives, a member telling the register),
|
||||
refused `signInAgain` before any code is used. Anonymous people still become
|
||||
identified with a code to the address they add. The app offers a password right after
|
||||
a GitHub sign-in, before the person's app (D2's "at their next sign-in"), and asks
|
||||
for a GitHub sign-in anew when the instance refuses an older one.
|
||||
2. **A stolen session outlived a reset of the authenticators and claimed the first new
|
||||
one** (medium-high): carrying the reset out ended no session, and the first
|
||||
authenticator took its own code alone. Carrying it out now ends every session of the
|
||||
account in every service (the sign-in that carries it out gets its session after
|
||||
that moment), and the first authenticator takes the password's proof for a change's
|
||||
challenge, without a code (`proveOwnersPassword`), counted per session as the owner's
|
||||
proofs are.
|
||||
3. **Lows**: a proof whose call to the register failed (`RegisterUnavailableException`)
|
||||
stays counted, as the register may have checked it; the sign-up mail's subject says it
|
||||
also gives an account its password. A notice for the owner when ten wrong proofs end a
|
||||
session is still to come (NEXT.md).
|
||||
|
||||
### The rules as they stand (21 Oct 2026)
|
||||
|
||||
Who changes what of an account, with which proofs. "Password" is SRP's proof bound to
|
||||
the host the device addressed; "code" a TOTP code from a confirmed authenticator or a
|
||||
recovery code; "mailed code" one asked for that purpose, for the account's own address
|
||||
unless said otherwise. Signed-in proofs count per session (ten wrong in a row end it);
|
||||
sign-ins' codes per account (waits from ten wrong in a row, the owner mailed).
|
||||
|
||||
| What | Without a session | Signed in |
|
||||
|---|---|---|
|
||||
| Sign in | password + code; password alone once an authenticator reset took effect, until one is confirmed; password + mailed code (`finishSetup`) while no authenticator was ever confirmed | — |
|
||||
| Sign up / first password | mailed code (`signUp`) to an address nobody has, or whose account has no password | anonymous: mailed code (`signUp`) to the address added; with an address: mailed code (`firstPassword`); GitHub alone: GitHub sign-in of the last 10 minutes + mailed code (`signUp`) to the address added. Never once an authenticator was confirmed |
|
||||
| First authenticator | — | password (no code) + the new one's code |
|
||||
| Another authenticator | — | password + code + the new one's code |
|
||||
| Remove an authenticator | — | confirmed: password + code (never the last); unconfirmed: nothing |
|
||||
| New recovery codes | — | password + code |
|
||||
| New recovery phrase | — | password + code |
|
||||
| New password | phrase's proof + code (keys kept) | password + code |
|
||||
| Authenticator reset | password + (mailed code or phrase's proof); takes effect after 72 h, owner mailed, called off by a sign-in with a code | — |
|
||||
| Account reset (new keys) | mailed code (`accountReset`) asks, a new one carries it out after 72 h, owner mailed, called off by any sign-in with the password | — |
|
||||
| Delete the account | — | password + code; where no second factor works, password + mailed code (`deletion`) |
|
||||
|
||||
Every reset carried out, and every new password, ends the account's sessions in every
|
||||
service (a change keeps the session asking).
|
||||
|
||||
## Consequences
|
||||
|
||||
- People keep a password, an authenticator app and a recovery phrase: more to keep than a
|
||||
|
|
|
|||
Loading…
Reference in a new issue