Skip to content

SecretSpace 4.0.0: nothing carries the old name any more - #34

Merged
usermaneGermane merged 5 commits into
mainfrom
rename-everything
Nov 14, 2026
Merged

usermaneGermane merged 5 commits into
mainfrom
rename-everything

Conversation

@usermaneGermane

Copy link
Copy Markdown
Owner

Part of the task "rename everything: PassMan → SecretSpace" (your decision of 13 Nov: everything, the cryptography's labels too, with a new account format and a one-time re-key).

SecretSpace 3 still carried the old name where nobody looks: in the labels its keys are made with, in the markers at the start of its files, in the name of its data folder. This version uses its own name everywhere. The cryptography is unchanged; the format is new (format 2), and an account from SecretSpace 3 is converted the first time it is unlocked.

What the user sees

  • At unlock: "This account will be converted", with Save a copy first…, Convert, Cancel. Cancel changes nothing.
  • After it: a window asking for the 12 recovery words once, to convert the recovery copy too (it opens only with the words). Later is fine; Settings → Security has it afterwards.
  • At the next sync: the server is told, and vaults are stored in the new format. A shared vault moves by itself once every member has updated; until then it stays readable for a member still on SecretSpace 3.
  • The Emergency Kit stays valid: a Secret Key printed as A3-… is accepted; it is shown as A4-… now.
  • The data folder %APPDATA%\PassMan is renamed to %APPDATA%\SecretSpace at start (renamed, not copied).

What must be known before installing

  • SecretSpace 3.0 / 3.1 cannot open a converted account. Every device has to be updated.
  • The server must be 2.1.0 (PRs open in both server repos). Until then the app works locally and says the server is too old.

How it is built

  • account_crypto.Format: what differs between the formats. NOW is written; OLD is read, to convert — and written only for a vault that someone with an older app still opens.
  • The signing key and the recovery proof were derived with the old labels. They are now stored in the keyset — for a converted account the values it always had, so its identity, every signature it made and the server's recovery check stay valid. Nobody has to compare fingerprints again.
  • accounts.convert: keyset sealed again with the same salt (every device arrives at the same new login key on its own), then the vault files; account.json is the commit point.
  • legacy_names.py is the one module with the old names; a test fails if the old name appears anywhere else in the program.

Proof

  • 849 tests pass (88 new).
  • The conversion is tested on accounts that the real 3.1.0 wrote, with its server 2.0.0 (tests/fixtures/format1, made by make_format1.py): a synced account with a shared vault, its other member, and an account that was never on a server.
  • Covered: interruption at every write; two devices converting separately; a member who has not updated still reading and writing; sign-in and recovery of an unconverted account; an old Emergency Kit.
  • Mutation check: 56 deliberate breaks, 55 caught, 1 equivalent (a guard that only saves a server call).
  • Lab flows on the real app (source run): accounts 42/42, sync 22/22, vaults 56/56, sharing 101/101, recovery 83/83.

Not done

  • A security review of the new format by fresh eyes (planned before the release).
  • The conversion windows were not looked at on screen by me: the flows drive the logic, not these two new dialogs.
  • Merging this before the two server PRs is harmless, but releasing it is not useful until the server 2.1.0 is out.

After the merge

Tag v4.0.0, build and release the installer. The local folders E:\CLAUDE\PassMan-* are renamed last, after all four merges.

🤖 Generated with Claude Code

https://claude.ai/code/session_011ojnyXb6JY4UPVU4waZe1w

usermaneGermane and others added 3 commits November 14, 2026 20:34
The project was renamed from PassMan to SecretSpace in November 2026, but
SecretSpace 3 still carried the old name where nobody looks: in the labels
its keys are made with, in the markers at the start of its files, in the
name of its data folder. This version uses its own name everywhere. That
means a new file format (format 2) and a one-time conversion of an account
made by SecretSpace 3; the cryptography itself is unchanged.

- account_crypto: `Format` holds what differs between the two formats
  (label prefix, file markers, Secret Key spelling). NOW is written; OLD is
  read, to convert. The signing key and the recovery proof, which were
  derived with the old labels, are stored in the keyset from now on - for a
  converted account the values it always had, so its identity, everything
  it signed and the server's recovery check all stay valid.
- accounts.convert: opens an account the old way and writes it again -
  keyset (same salt, so every device arrives at the same new login key),
  the stored Secret Key, every vault file and sync base. account.json is
  the commit point; stopped before it the old account is whole, stopped
  after it the next unlock tidies up. Asked for at unlock, with "Save a
  copy first".
- The recovery copy opens only with the 12 words, so it is converted when
  the user types them once (asked after the conversion; Settings later).
- account_sync: the server is told at the next sync (old login key, then
  the new keyset). The personal vault is uploaded in the new format. A
  further vault moves by a key change, once every member's account is
  converted; until then it stays in the old format and is read and written
  that way, so a member who has not updated is never locked out. Needs
  SecretSpace Server 2.1.0.
- An Emergency Kit from SecretSpace 3 (A3-...) stays valid; the key is
  shown as A4-... now.
- The data folder %APPDATA%\PassMan is renamed to %APPDATA%\SecretSpace at
  start (renamed, not copied; used where it is if it cannot be).
- legacy_names.py is the one module with the old names. A test fails if
  the old name appears anywhere else in the program.
- Headers X-SecretSpace-*, SECRETSPACE_DATA_DIR, the wording of Import.

Tests: 849 (88 new). The conversion is tested on accounts made by the real
3.1.0 with its server 2.0.0 (tests/fixtures/format1). 56 mutants: 55
caught, 1 equivalent. Lab flows on the app: accounts 42/42, sync 22/22,
vaults 56/56, sharing 101/101, recovery 83/83.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ojnyXb6JY4UPVU4waZe1w
…f its own

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ojnyXb6JY4UPVU4waZe1w
usermaneGermane and others added 2 commits November 14, 2026 20:48
Review finding: a sign-in from a server converted an account that no
device had converted yet, on the server, without asking - which locks out
every device of that account still running SecretSpace 3. Now sign_in
raises NeedsConversion (nothing changed, anywhere) unless convert=True, and
the window asks with the same "will be converted" question as an unlock,
saying that it happens on the server.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ojnyXb6JY4UPVU4waZe1w
…us one

Found in the security review of the new format: compare only once both
people have updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ojnyXb6JY4UPVU4waZe1w
@usermaneGermane
usermaneGermane merged commit 66f3cfc into main Nov 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant