docs(auth): proofs bound to the base URL and to what they approve (ADR 0017)
The full reading's part in ADR 0017 records the device's medium 1 as done (the identity's purpose and digest, the base URL in place of the host, an instance under a path taking no password sign-in), and "The rules as they stand" says what "password" binds; the module's and halkyon_app's READMEs say the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
0a7679396b
commit
7bef70948d
1 changed files with 48 additions and 18 deletions
|
|
@ -210,13 +210,17 @@ Built on the three parts above, on the register (members forward every step thro
|
|||
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 `passwordIdentity`: the challenge's ID and the
|
||||
host the device addressed (`host` on every proving call: in production it must be the
|
||||
server's `apiServer.publicHost`, else `otherInstance`; in development any, as an
|
||||
emulator reaches the machine as 10.0.2.2), so a hostile instance relaying a sign-in or
|
||||
a phrase's proof here gets nothing taken; a member forwards its own host, and the
|
||||
phrase's proof for a new password signs that password's digest
|
||||
(`newPasswordDigest`). An address nobody has (or whose
|
||||
leaves it unused. SRP's identity I is `passwordIdentity`: the challenge's ID, the
|
||||
instance's base URL the device addressed (`instanceUrl` on every proving call, written
|
||||
alike on both sides by `canonicalInstanceUrl`: in production it must be the server's
|
||||
own public scheme, host and port at the root, `publicInstanceUrlOf`, else
|
||||
`otherInstance`, so an instance served under a path takes no password sign-in; in
|
||||
development any, as an emulator reaches the machine as 10.0.2.2), what the proof is for
|
||||
and the digest of what it sets (`PasswordProofPurpose`; signing in and an
|
||||
authenticator's reset each its own, with none), so a hostile instance relaying a
|
||||
sign-in or a phrase's proof here gets nothing taken, nor one beside it on the same host;
|
||||
a member forwards its own base URL, and the phrase's proof for a new password signs
|
||||
that URL and that password's digest (`newPasswordDigest`). 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
|
||||
|
|
@ -238,7 +242,13 @@ Built on the three parts above, on the register (members forward every step thro
|
|||
recovery codes, a new phrase, a new password, deleting) takes the password's SRP proof
|
||||
for a challenge `password.beginChange` gave (30 begun an hour per session, holding
|
||||
back no other) and then a TOTP or recovery code (`proveOwner`, `ownersCode`). A proof
|
||||
given where none is taken is refused, so none passes unchecked. Each proof counts for
|
||||
given where none is taken is refused, so none passes unchecked. The proof is bound to
|
||||
what it approves: SRP's identity carries the purpose and the digest of what is set
|
||||
(`newPasswordDigest` of the new password, `newPhraseDigest` of the phrase's wrapping
|
||||
and proof key, `authenticatorDigest` of the authenticator confirmed or removed; none
|
||||
for new recovery codes, calling resets off and deleting), which the register works out
|
||||
from the call itself, so whoever stands between swaps nothing in and a proof made for
|
||||
one change makes no other. Each proof counts for
|
||||
its session alone (`owner_proof_tries.dart`, `asOwnerProofTry`, table
|
||||
`session_code_failures`, kept where the session is, on a member too), before it is
|
||||
checked; the tenth wrong in a row ends the session (`sessionEnded`), only a proof
|
||||
|
|
@ -295,7 +305,7 @@ Built on the three parts above, on the register (members forward every step thro
|
|||
neither, nor a session and a code.
|
||||
- **Deleting an account with a password** (`account.delete(proof:)`, a `DeletionProof`)
|
||||
takes the same: the password's proof for a `beginChange` challenge and a code, bound
|
||||
to the host the device addressed (`requireOwnerToDelete`; a member passes the proof on
|
||||
to the base URL the device addressed and made for deleting (`requireOwnerToDelete`; a member passes the proof on
|
||||
and the register checks it), counted for the session as every owner's proof is. The
|
||||
code is a TOTP or recovery code wherever an authenticator is confirmed; where no second
|
||||
factor works (a setup never finished, or the authenticators' reset taken effect;
|
||||
|
|
|
|||
Loading…
Reference in a new issue