https://gitlab.synchro.net/main/sbbs/-/commit/9f1adb69902828d5b5ed8331
Modified Files:
docs/superpowers/specs/2026-07-31-hashed-password-storage-design.md
Log Message:
docs: scope the password design honestly and narrow its argument
Third pass, following review. Most of this is retraction.
The case against encryption rested on four claims that are now withdrawn:
that a sysop necessarily holds the key; that the key would sit on the
same disk, in the same backup, as the data; that two users with the same password would encrypt to the same ciphertext; and that encryption fails
the non-usability property by definition.
The first three each evaluated encryption at its worst instantiation and rejected the primitive for the result, which is an argument available
against anything -- an unsalted single-round SHA-256 is "hashing" too,
and it would fail every property this document sets out. The fourth was circular: it read the property as "is a one-way function" and then
observed that encryption is not one. A ciphertext record is not a
credential; it cannot be presented to a login prompt and without the key
it authenticates nothing.
The property survives and keeps its job -- ruling out cleartext, and
ruling out the CRAM-MD5 midstate, which is directly presentable as a
credential with no key at all -- but encryption is not in that class and
is now recorded as satisfying it. Which leaves encryption, competently
built, meeting every property this document asks for and beating hashing
on one: against a file-only adversary there is no offline attack at all
without the key, where a hash only makes one expensive. A weak password survives a stolen ciphertext and does not survive a stolen hash.
So the rejection is now narrow, and rests on two things. Encryption fails totally and retroactively when it fails, where hashing has no single
secret whose loss exposes everyone and charges the attacker per account instead. And the BBS never needs to recover a password, only to answer
yes or no about one, so reversibility is a capability that will never be
used and is paid for in key management that hashing does not incur.
The key-management cost is also stated at its true size. Every operating
system Synchronet runs on has secret storage, and distributing a key to a multi-host installation means provisioning the same secret into each
host, not federating their key stores -- an ordinary setup step of the
same kind as installing a TLS private key. What remains is a manual step
per host, repeated on rotation, with the secret outside any key store in transit. That is some cost, not much, and the failure mode is what
actually decides the question.
The document also now states its own scope, and the criticism of it. An analysis that answers every existing use of passwords with "passwords,
but stored more carefully" is a narrow answer to a broad problem, and
pairing it with the removal of working features makes the narrowness
harder to excuse. Most of that is correct. A large share of the sites catalogued here should not use a password at all: the MQTT broker wants
an issued API key, qtmonitor wants the key it was issued rather than a
human's login, door dropfiles want a per-session token or nothing, and
the human-facing surfaces want FIDO2 on the web, public keys at the
terminal, and client certificates for mail. Each of those is a larger improvement than this design is.
What defends proceeding is that storage is the floor rather than the
ceiling. No post-password mechanism retires an existing password -- a BBS
with a thousand records still has a thousand passwords the day FIDO2
ships, and most of those users will never enrol anything. Storage is the
only measure that requires no user action, which matters when the threat
is a file that leaks rather than a user who chooses badly. And it is a precondition rather than a competitor, since SCRAM stores the salted
iterated verifier this design already builds.
Accordingly the removed mechanisms are recorded as a cost rather than as cleanup, in "What this delivers" alongside the limitations, and the rule
that nothing is removed without a replacement path is stated generally
rather than only for IMAP.
FIDO2 and API keys are named for the first time, in place of gesturing at
the families they belong to. FIDO2 is the strongest of the post-password options and the one users would plausibly adopt: the private key is not extractable even by the user, the server stores a public key, and a
leaked credential file is inert rather than merely expensive. Being origin-bound, it addresses the reused-credential asset by construction
instead of by cost. Its limit is transport rather than merit -- WebAuthn
is a browser API -- which is why the post-password map is three protocols
and not one.
For MQTT the standard answer has a name, API key generation, and the
lifecycle is the point rather than the value: issued to a client rather
than to a person, revocable and rotatable independently, high-entropy so
no KDF is needed, never typed. Concretely, revoking a sysop's broker
access today means changing the password they log into the BBS with, and
since authenticate_psk() compares against cfg->sys_pass it revokes broker access for every other sysop at the same time. The residue is stated too: TLS-PSK is symmetric, so API keys fix reuse and revocation completely and
the at-rest problem only partly, where client certificates need no shared secret at all.
Co-Authored-By: Claude Opus 5 (1M context) <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net