Skip to content

Accounts sync through a server (phase 2, 1.0.0-alpha.3) - #19

Merged
usermaneGermane merged 2 commits into
mainfrom
v3-account-sync
Nov 10, 2026
Merged

usermaneGermane merged 2 commits into
mainfrom
v3-account-sync

Conversation

@usermaneGermane

Copy link
Copy Markdown
Owner

What

Phase 2 of SecretSpace 3, client side: accounts sync through your own server. This is a test version. It needs SecretSpace Server 2.0.0-alpha.1 (server PRs #10).

  • Settings → Sync → Set up… puts the account on the server: you log in if it's already there, otherwise it's created with the server's token as the sign-up code. The server is remembered only if this worked.
  • The Sync button syncs the personal vault with the same three-way merge, conflict dialog and base rules as 2.x. It saves locally, then pushes, and writes the base last.
  • "Sign in from a server" on the login screen covers two cases:
    • A new device: you give the address, username, master password and Secret Key. The keyset is opened before anything is written.
    • This device, after a password change on another one: it keeps its own vault files and merges them at the next sync.
  • Changing the master password of a server account tells the server first. If the server can't be reached, nothing changes anywhere.
  • Network calls all run off the window's thread, including the logout. On the main thread it froze the window for 20 s in the Lab flow, which is how I found it.

Never sent to the server: the master password, the Secret Key or the vault key. The server gets the Login Key and blobs it can't open.

Checks

  • tests/test_account_sync.py: 20 end-to-end tests on two "devices" against a real copy of the server. They cover:
    • connecting and signing up, a wrong or missing token, a name already taken, a 1.x server;
    • the first upload, sign-in on a second device, merging both ways, conflicts, a vault changed during a sync;
    • a wrong password or Secret Key, the Emergency Kit being required, case of the username;
    • a password change on one device reaching the other (DPAPI and password scheme), no server → no change;
    • nothing readable on the server.
  • Mutation check: I broke 8 guards on purpose, and all were caught.
  • All tests: pytest passes.
  • Lab, in the real windows:
    • new phase 2 flow flows_sync_accounts.py: 22/22 on Windows and Linux code;
    • phase 1 flow: 42/42 on both (updated for the rename and the new Sync row).

Not yet: several vaults per account (phase 3), sharing (phase 4), recovery with the phrase (phase 5), and Sync when I unlock for accounts.

🤖 Generated with Claude Code

https://claude.ai/code/session_011ojnyVg7ccsR3pZ64s7aRH

usermaneGermane and others added 2 commits November 10, 2026 08:59
Phase 2 of the 3.0 design, client side, against SecretSpace Server 2.0's
API v2 (server PRs #10):

- account_sync.py: AccountServer (the /v2/ calls on sync_client's
  transport); connect() puts an account on a server (log in, or sign up
  with the server's token as the code) and remembers it only if that
  worked, and refuses a server account with another personal vault;
  AccountSync syncs the personal vault with the 2.x three-way merge,
  conflict choices and base rules (saved locally first, then pushed, base
  written last with its server and revision); sign_in() brings an account
  onto a new device (pre-login salt, Login Key, keyset opened before
  anything is written) or onto this one after a password changed
  elsewhere, keeping its vault files to merge; change_password() tells the
  server first, so device and server never disagree.
- accounts.py: the Login Key stays in memory after unlock; set_server,
  base load/save, encrypt/decrypt helpers, sealed_files, stored_secret,
  adopt_from_server; change_password(before_write=...).
- account_sync_ui.py: Settings -> Sync -> Set up..., the Sync button,
  "Sign in from a server" on the login screen. Network on worker threads
  only, including the logout (on the main thread it froze the window for
  20 s in the Lab flow).
- gui.py / dialogs.py: Sync button back, the Sync section (Synced with /
  Sync now / Disconnect, or Set up...), password change off the main thread
  through account_sync.
- Test copy of the server = server 2.0.0-alpha.1.

Not yet: several vaults per account (phase 3), sharing (4), recovery (5),
"Sync when I unlock" for accounts.

tests/test_account_sync.py: 20 end-to-end tests on two "devices" and a real
server copy. Mutation check: 8 broken guards, all caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ojnyVg7ccsR3pZ64s7aRH
On Linux the device's own scheme is the password one (no DPAPI), so after a
password change on another device it rightly needs the Emergency Kit to sign
in again. The test assumed DPAPI for "native" and failed in Linux CI; it
now asks secret_store which scheme is in force.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ojnyVg7ccsR3pZ64s7aRH
@usermaneGermane
usermaneGermane merged commit 2057bd6 into main Nov 10, 2026
6 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