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
|
|
@ -15,16 +15,15 @@ Endpoints, under the nickname `base` in a host's client (`client.modules.base.em
|
|||
| Endpoint | Methods | Who may call |
|
||||
|---|---|---|
|
||||
| `anonymousIdp` | `login` (Serverpod's anonymous sign-in, at most 30 new accounts per network and hour) | anyone |
|
||||
| `password` | `set`: the caller's password, with the address a mailed code proves unless they have one | signed in |
|
||||
| `passwordSignIn` | `begin`, `complete`: SRP-6a's two steps with a code from an authenticator (or a recovery code); a session | without a session |
|
||||
| `password` | `set`: the caller's password, with the address a mailed code proves unless they have one; `beginChange`, `change`: a new password with the old one's proof and a code, every other session ending; `setRecoveryKeys`: a new recovery phrase's wrapping, for a code | signed in |
|
||||
| `passwordSignIn` | `begin`, `complete`: SRP-6a's two steps with a code from an authenticator (or a recovery code; a setup never finished, a code by mail); a session. `signUp`: an account at the address a mailed code proves, with a password; a session | without a session |
|
||||
| `authenticator` | `enrol`, `confirm` (the first brings ten recovery codes; another takes a code from one confirmed before), `list`, `remove`, `newRecoveryCodes` | signed in |
|
||||
| `accountRecovery` | `sendCode`, `resetAuthenticator`, `beginKeyProof`, `resetPassword` (with the recovery phrase), `startAccountReset`, `completeAccountReset` | without a session |
|
||||
| `accountRecovery` | `resetAuthenticator`, `beginKeyProof`, `resetPassword` (with the recovery phrase), `startAccountReset`, `completeAccountReset` | without a session |
|
||||
| `gitHubUpgrade` | `upgrade`: links a GitHub account to the caller, who becomes `identified`; refused where passwords are offered (deprecated) | signed in |
|
||||
| `gitHubSignIn` | `signIn`: a session for whoever has that GitHub account, unless they sign in with a password; none once `GITHUB_SIGN_IN_ENDS` has come | without a session |
|
||||
| `emailCode` | `sendCode`, `verifyCode`: a code by mail; a new address becomes the caller's, another person's gives a switch token | signed in |
|
||||
| `emailSignIn` | `signIn`: a session for the person a switch token names | without a session |
|
||||
| `emailCode` | `sendCode`: a code by mail, which proves the address and signs nobody in | anyone |
|
||||
| `account` | `delete`, `signInWays` | signed in |
|
||||
| `instance` | `basics`: the app it serves, GitHub's client ID if any, whether email and password sign-in are on, the source link, the oldest app build, where data and backups are | anyone |
|
||||
| `instance` | `basics`: the app it serves, GitHub's client ID if any and when GitHub sign-in ends, whether codes by mail and password sign-in are on, the source link, the oldest app build, where data and backups are | anyone |
|
||||
| `profile` | `mine`, `save`, `checkHandle`, `checkLinks` (at most 10 an hour), `setAvatar`, `removeAvatar`, `remove`: the caller's own public profile | `identified` |
|
||||
| `profiles` | `byHandle`: anyone's public profile, whatever the handle's case | signed in |
|
||||
|
||||
|
|
@ -182,9 +181,20 @@ Built on the three parts above, on the register (members forward every step thro
|
|||
confirmed; until then a new setup replaces it, never once one was, even while a reset
|
||||
leaves the account without one (a new password comes through the recovery phrase or
|
||||
the account's reset alone).
|
||||
- **Codes by mail** (`emailCode.sendCode`, without a session) only prove an address: for
|
||||
a password's setup, a sign-up, a setup never finished and the resets. Since step 3
|
||||
nothing turns a code into a session (`emailCode.verifyCode`, `emailSignIn.signIn` and
|
||||
the switch token went with build 22, `minimumAppBuild` 22 in Learn).
|
||||
- **Signing up** (`passwordSignIn.signUp(request, code, setup)`, without a session): an
|
||||
address nobody has becomes a new identified account, an account with the address and
|
||||
no password takes it (keeping its ID); refused (`passwordExists`) for an address whose
|
||||
account has a password. The session it gives sets up the authenticator.
|
||||
- **Signing in:** `begin(address)` answers salt, costs and B; `complete(challenge, A, M1,
|
||||
totpCode | recoveryCode)` answers M2, the public keys, the password's wrapping and a
|
||||
session. SRP's identity I is the challenge's ID. An address nobody has (or whose
|
||||
session. A setup never finished (never a confirmed authenticator) signs in with a code
|
||||
mailed to the address it began with in its place (`request`, `code`), which calls off
|
||||
a reset of the account waiting; any other account takes no code by mail there and
|
||||
leaves it unused. SRP's identity I is the challenge's ID. An address nobody has (or whose
|
||||
account has no password) gets a salt and verifier from `signInDecoyKey` and the
|
||||
address's hash, the same queries and arithmetic, and the same refusal: a wrong
|
||||
password, an unknown address and a wrong, used or missing code are all
|
||||
|
|
@ -203,13 +213,26 @@ Built on the three parts above, on the register (members forward every step thro
|
|||
account's Ed25519 signature over a nonce (`keyProofMessage`) and a code set a new
|
||||
password, the keys staying. A lost password without it: a mailed code asks, 72 hours
|
||||
pass (a mail at the start, a sign-in calls it off), a new code carries it out: new
|
||||
password, new keys, no authenticators. Either change of password ends the account's
|
||||
sessions on the register's server.
|
||||
password, new keys, no authenticators.
|
||||
- **Changing while signed in:** `password.beginChange` and `password.change` take the old
|
||||
password's SRP proof, a TOTP or recovery code and the same keys wrapped under the new
|
||||
password; `password.setRecoveryKeys` replaces the phrase's wrapping for a code. A
|
||||
session alone changes neither.
|
||||
- **Sessions end everywhere:** a change of password ends every other session of the
|
||||
account; a reset of the password or the account ends all. The register ends its own
|
||||
and keeps a `sessions_ended_notice` per member (told at once and hourly until it
|
||||
confirms, `deliverSessionNotices`, as deletions are told): it names a moment, so a
|
||||
session made since stays, and the session that asked for a change. A member answering
|
||||
one (`/halkyon-base/member/sessions-ended`) ends its sessions made before the moment;
|
||||
a member signing someone in after a reset ends its own first and makes the new session
|
||||
only once its clock is past the moment (`issueSessionAfter`). A refusal for a reset not
|
||||
due says when it takes effect (`takesEffectAt`).
|
||||
- **Older ways:** an account that signs in with a password (it had a confirmed
|
||||
authenticator, which a reset may have taken since: `passwordOnly` in its ways in) no
|
||||
longer signs in by a mailed code (`usePassword`) or GitHub (`usePassword`); where passwords are offered, no new GitHub account is linked
|
||||
(`deprecated`); from `GITHUB_SIGN_IN_ENDS` on GitHub signs nobody in (`ended`) and
|
||||
`forgetGitHubAccounts` deletes every GitHub ID.
|
||||
longer signs in with GitHub (`usePassword`); where passwords are offered, no new GitHub
|
||||
account is linked (`deprecated`); from `GITHUB_SIGN_IN_ENDS` on GitHub signs nobody in
|
||||
(`ended`), the basics stop naming the day (`gitHubSignInEnds`, which apps show until
|
||||
then) and `forgetGitHubAccounts` deletes every GitHub ID.
|
||||
|
||||
## Taking it into a host
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue