docs(auth): what building the apps' side settled (ADR 0017)
ADR 0017's step-3 section: codes by mail sign nobody in, the ways in for accounts without a working password, changes while signed in, sessions ended in every service, the apps' screens (the QR package and the alternatives considered), the keys in the keyring, anonymous people's keys waiting for step 4, and libsodium on devices (results copied before they leave an isolate; a C compiler and make for every build). The module's and halkyon_app's READMEs and the AGENTS files say the same; the snap's build installs make for sodium's build hook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
ae57cbe864
commit
4f7b123ad4
1 changed files with 136 additions and 32 deletions
|
|
@ -156,12 +156,65 @@ through `AccountRegister`, the session being theirs.
|
|||
- **Email codes** still sign in (until step 3), but not into an account with a password
|
||||
that had a confirmed authenticator (`usePassword`), which a code alone would bypass.
|
||||
|
||||
Step 3 (email codes go): sign-up keeps `password.set` with its code; `emailCode.verifyCode`
|
||||
and `emailSignIn.signIn` go, and with them the switch token; accounts with an address but
|
||||
no password, and accounts whose setup never finished, need a way in (a mailed code and a
|
||||
new password, as the account reset, or a password plus a mailed code until an
|
||||
authenticator is confirmed); a member's sessions should end too when the register resets
|
||||
an account; and a signed-in change of password (with the keys at hand) is still missing.
|
||||
## Settled in building the apps' side (20 Oct 2026, step 3)
|
||||
|
||||
On branch `password-sign-in`, for build 22 (`minimumAppBuild` 22 in Learn; Todo, never
|
||||
released, stays at 1), after the second reading.
|
||||
|
||||
- **Codes by mail sign nobody in** (D4): `emailCode.verifyCode`, `emailSignIn.signIn`
|
||||
and the switch token went, with the register's operations for them. `emailCode.sendCode`
|
||||
stays, without a session, as what proves an address: for `password.set`, a sign-up,
|
||||
a setup never finished and the resets (`accountRecovery.sendCode` went).
|
||||
- **Ways in for accounts without a working password:** `passwordSignIn.signUp` (a code
|
||||
and a setup, no session) makes a new account at an address nobody has, or gives the
|
||||
account with that address and no password (codes by mail before; no keys exist, so
|
||||
nothing waits) its password, keeping its ID. A setup never finished signs in with its
|
||||
password and a code mailed to the address the sign-in began with, until an
|
||||
authenticator is confirmed, and that calls off an account reset waiting (a reset of
|
||||
the account waiting no longer counts as having had an authenticator, so its owner
|
||||
isn't locked out). Never for an account that had a confirmed authenticator.
|
||||
- **Changing while signed in:** the password (`password.beginChange`, `password.change`:
|
||||
the old password's SRP proof, a TOTP or recovery code, the same keys rewrapped on the
|
||||
device; every other session ends) and the recovery phrase (`password.setRecoveryKeys`:
|
||||
the keys wrapped under a new phrase, for a code). A session alone changes neither.
|
||||
- **Sessions end in every service:** a change of password ends every other session of
|
||||
the account, a reset of the password or the account all of them, on the register and
|
||||
on every member, by a notice kept until each confirms (`sessions_ended_notice`, a new
|
||||
table; hourly with the deletions' notices). A notice names a moment, so sessions made
|
||||
since stay: a member signing someone in after a reset makes the session once its clock
|
||||
is past it.
|
||||
- **A reset not due says when** it takes effect (`takesEffectAt` on the refusal), and the
|
||||
basics say when GitHub sign-in ends (`gitHubSignInEnds`), which apps show.
|
||||
- **The apps** (halkyon_app, Learn and Todo): signed out, Sign in and Create an account
|
||||
(and GitHub, its end date beneath); signing in asks the address and password (Argon2id
|
||||
on the device, about a second), then a code from the authenticator or a recovery code;
|
||||
M2 is checked and the keys opened before the session is put in place. An account
|
||||
never finished is mailed a code; one whose authenticators' reset took effect signs in
|
||||
without a code; both then set up an authenticator with the session held back, and put
|
||||
it in place only after. Creating an account: address, password twice, the recovery
|
||||
phrase shown once (copy, save as a file) and three random words typed back, then the
|
||||
mailed code (nothing reaches the instance before), the authenticator (a QR code of the
|
||||
`otpauth://` URI, drawn by the app with pub.dev's `qr`, BSD-3-Clause, pinned; its key
|
||||
as text; on phones Open in authenticator app; considered: `qr_flutter` and
|
||||
`pretty_qr_code`, Flutter widgets on the same encoder) and the ten recovery codes
|
||||
(copy, save). Getting back in: with the phrase (a new password, the keys staying), a
|
||||
reset of the account asked for by a code (72 hours), and finishing it (a new code; new
|
||||
keys and a new phrase, or with the phrase the old keys rewrapped, as the account's
|
||||
reset keeps them for someone who lost both password and authenticator). The account
|
||||
part (`AccountSecuritySection`): setting up a password (anonymous people, GitHub's, an
|
||||
account with only an address), finishing the setup, the authenticators (adding one
|
||||
takes a code from one before), new recovery codes, changing the password, a new
|
||||
phrase; GitHub's end date.
|
||||
- **The keys on the device:** unlocked after signing in, kept in the system's keyring
|
||||
per instance and person (flutter_secure_storage), gone once another person signs in or
|
||||
nobody, and with the instance's removal from the device. Anonymous people's device keys
|
||||
wait for step 4: nothing is encrypted before it.
|
||||
- **libsodium on devices:** sodium's results (salts, public keys, cipher texts,
|
||||
signatures) are views of native memory its finalizers free once the isolate that made
|
||||
them ends; each step runs on an isolate of its own, so whatever crosses back is copied
|
||||
first (a view read freed memory and crashed the process). Every build of an app needs a
|
||||
C compiler and make for sodium's build hook (Linux, Android's NDK, Xcode, Visual
|
||||
Studio; the snap's build and CI's runner too).
|
||||
|
||||
## Consequences
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue