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
|
|
@ -271,6 +271,7 @@ deletion):
|
|||
production the host must be the server's `apiServer.publicHost` (`otherInstance`
|
||||
otherwise), any in development; members forward their own. A hostile instance relaying
|
||||
a sign-in or a phrase's proof to the real one, or swapping in a password, gets nothing.
|
||||
(Since the full reading, the instance's whole base URL in place of the host.)
|
||||
- **M7: data keys weren't authenticated.** A sealed data key is now signed by its sealer
|
||||
and checked against the expected one on opening, so the register can't plant a key of
|
||||
its own (before step 4 encrypts anything).
|
||||
|
|
@ -471,18 +472,34 @@ refused but on this machine; the phrase is saved, never copied. Server side:
|
|||
matters only once someone holding it made codes wait; L8, decoys answer today's costs
|
||||
(`newPasswordCosts`), revisit when `PasswordKdf.current` rises; L9, a key proof's first
|
||||
step gives out an address's public keys (step 4 shares keys: revisit then).
|
||||
- **Not done yet, the device's M1:** the owner's proof is bound to the challenge and the
|
||||
host, not to the operation it approves nor the instance's whole base URL; binding a
|
||||
purpose label and the digest of what is set into SRP's identity on both sides, and
|
||||
scheme, host, port and path in place of the host, is the next change. Until then a
|
||||
`change` challenge's proof can be replayed for another signed-in change by whoever
|
||||
reads and changes the traffic (plain `http://`, TLS intercepted), which the refusal of
|
||||
`http://` instances (the device's part 2) narrows.
|
||||
- **The device's medium 1, the owner's proof bound to the challenge and the host
|
||||
alone.** Whoever read and changed the traffic (plain `http://`, TLS intercepted or
|
||||
broken: what SRP is for) could keep the owner's proof and code and swap in a password,
|
||||
a phrase or an authenticator of their own, or turn a proof made for new recovery codes
|
||||
into a deletion; and instances on one host under another port, path or scheme could
|
||||
relay each other's proofs (the device's low 4). SRP's identity is now a label, the
|
||||
challenge's ID, the instance's base URL, what the proof is for and the digest of what
|
||||
it sets (`passwordIdentity`, identity v2), and the phrase's proof signs the base URL
|
||||
too (key proof v3). The base URL is written alike on both sides
|
||||
(`canonicalInstanceUrl`: scheme and host in lower case, the port only where it isn't
|
||||
the scheme's own, the path ending in `/`); the register takes only its own public
|
||||
scheme, host and port at the root (`publicInstanceUrlOf`; Serverpod serves at the root,
|
||||
so an instance under a path takes no password sign-in), any in development, a member's
|
||||
as the member names it. The purposes are signing in, an authenticator's reset (each of
|
||||
its own, so one never stands for the other), a new password (the digest of the
|
||||
`NewPassword` sent), a new phrase (of its wrapping and proof key), the first or another
|
||||
authenticator and removing one (of its ID), new recovery codes, calling resets off and
|
||||
deleting (none); the register works out purpose and digest from the call that brings
|
||||
the proof, never from the device. `OwnerProof`'s and `DeletionProof`'s `host`, and
|
||||
every endpoint's, are `instanceUrl`. Each refusal has a test, which fails with the
|
||||
binding taken out on both sides.
|
||||
|
||||
### 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
|
||||
the instance's base URL the device addressed, and to what it approves (the purpose and
|
||||
the digest of what it sets: a proof made for one change counts for no other); "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 and way, after the password or the phrase (waits from ten
|
||||
|
|
|
|||
Loading…
Reference in a new issue