Skip to content

feat: github sync - #58

Merged
cyenite merged 3 commits into
mainfrom
feat/github-sync
Nov 4, 2026
Merged

cyenite merged 3 commits into
mainfrom
feat/github-sync

Conversation

@cyenite

@cyenite cyenite commented Nov 4, 2026 •

Copy link
Copy Markdown
Owner

Summary

Syncs saved accounts (and, behind an opt-in, their passwords, API keys and the CID), layouts, drawings, templates, watchlists, Pine scripts and preferences between a user's computers through a private GitHub repository, end-to-end encrypted so GitHub only ever holds ciphertext.

How was this tested?

  • Tests: 6 new, including two attack tests that plant a key for a waiting computer. In one, the planted key can’t open the synced data and is refused at once. In the other, the manifest is deleted too, and the key is refused after three wrong tries with nothing kept. Both pass.
  • Whole project: all 810 tests pass, and the typecheck and production build are clean. The 104 sync tests also pass under Electron’s own crypto library.

Checklist

  • npm run check passes (typecheck, tests and build).
  • New behaviour is covered by tests.
  • Documentation in docs/ is updated where needed.
  • User-visible changes have an entry under Unreleased in CHANGELOG.md.
  • No credentials, account numbers or captured broker traffic are included.

@gitguardian

gitguardian Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

The engine for syncing accounts, layouts, drawings and other user data
between computers through a remote such as a private GitHub repository.
Not wired into the app yet: no GitHub client, store adapters or UI.

- Everything is encrypted on the device (AES-256-GCM, per-record keys
  from HKDF), padded, and stored under content-hash paths, so the
  remote sees no names, symbols or sizes worth reading. Each object is
  bound to its repository, key epoch, record and generation.
- The root key unlocks with a recovery code (with check digits), an
  optional scrypt passphrase, or a per-computer X25519 key.
- Records merge three ways by shape (fields, map, set, list, text,
  value) with hybrid logical clock stamps; edits are stamped when they
  happen, so an offline edit does not beat a newer one. Text edited on
  both sides keeps both versions.
- A signed manifest with a rising sequence refuses tampered, missing,
  foreign or rolled-back data before anything is applied.
- Applying is journalled and rolls back if a store refuses; a sync that
  would delete most of a store waits for the user; pushes are
  compare-and-swap and retry after a lost race.
- Copier leases fence their holder before anyone else may take over,
  and presence records which accounts each computer has open.
File > Sync Across Computers (beta) connects computers to the encrypted
sync core. No app data syncs yet; this registers each computer and
checks the repository.

- GitHub App sign-in by the device flow with only the public client id;
  refresh tokens are single use, so refreshes run one at a time and the
  new pair is saved before use. Requests go only to api.github.com,
  refuse redirects and run on their own in-memory session.
- A GitHub remote over the Git Data API: conditional head reads that
  cost no rate limit, Contents API seeding of an empty repository, and
  fast-forward-only ref updates as the compare-and-swap. Public
  repositories and ones with other files are refused, and an hourly
  check stops sync if the repository goes missing or public.
- Without GitHub, the same engine runs over one .ot5sync file on a
  drive or share; a missing file reads as offline, never as empty.
- Setup creates the sync key and a recovery code that must be typed
  back before sync starts; other computers unlock with the code, a
  passphrase, or approval from a linked computer after both show the
  same six words.
- The sync key, device key and tokens live only in the OS keychain; the
  engine state on disk is encrypted.
- A scheduler stamps edits a second after they settle, pushes within a
  budget, polls faster while focused, syncs on focus, lock and wake,
  and backs off when offline. Quitting waits up to 5 s for unsynced
  edits.
- Readers refuse data written by, or restoring, a computer that was
  removed from sync.
Security review fixes for sync pairing and the sync file.

- A computer waiting to pair no longer trusts a key wrapped to it. The
  key must open the existing synced data, and the user must type three
  words the approving computer shows, derived from the real sync key;
  three misses discard the key. Someone holding the GitHub token could
  otherwise wrap a key of their own to it and later read its data.
- Approval names the public key whose words were shown, so a request
  swapped in afterwards is refused instead of approved.
- Sync file writes use a random temporary name created exclusively, so
  a link planted in a shared folder cannot redirect the write.
- The removed-computer check is documented as best effort: the writer
  field is self-reported, and removal must replace the key.
@cyenite
cyenite merged commit d7a9752 into main Nov 4, 2026
4 checks passed
@cyenite cyenite mentioned this pull request Nov 4, 2026
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