- Device key (DeviceSigner): Windows TPM via CNG with a DPAPI-sealed software fallback, Linux Secret Service with a 0600 file fallback (warned in Settings), macOS keychain for dev runs. The store used is recorded; no silent switching. - SyncService (Tauri-free): server URL and pins, create account with the server's setup code, sync after unlock/save/browser save, every 15 min while unlocked and on demand, status events, integrity alarm, device list with fingerprint approval and revoke. - Onboarding: "Use my phone" (join_start/poll, QR rendered locally, 6-digit code), Emergency Kit from PDF/PNG/JPEG (hayro + rqrr), paste setup code, new account. Then only the master password. - From a signed-in desktop: "Add a phone or tablet" QR with countdown (cancel, lock and quit revoke the ticket) and "Approve a computer" via pasted join code. - KESTROVE_DATA_DIR / KESTROVE_DEVICE_NAME for a second instance; ignored live test drives three instances against a real server. - deny: ignore three unmaintained notices for zbus 5 sub-crates (Linux keyring). Co-Authored-By: Claude Opus 5.5 <[email protected]>
82 lines
5.2 KiB
Markdown
82 lines
5.2 KiB
Markdown
# kestrove-desktop
|
|
|
|
**Windows and Linux** app built on Tauri 2. The Rust side links `kestrove-core`'s `kv-ffi`
|
|
directly. The web UI only renders and never touches keys. macOS uses the native `kestrove-apple` app.
|
|
|
|
Also ships `kestrove-nmh`, the **native-messaging host** that bridges `kestrove-browser` to the app.
|
|
|
|
```bash
|
|
# prerequisites: rustup, Node 20+, and Tauri's OS deps (https://tauri.app/start/prerequisites/)
|
|
npm install
|
|
npm run tauri dev
|
|
npm run tauri build # MSI/NSIS on Windows, AppImage/deb on Linux
|
|
npm run tauri build -- --debug --bundles app # macOS dev build (Kestrove.app)
|
|
npm run tauri icon assets/logo.png # regenerate src-tauri/icons (placeholder logo)
|
|
(cd src-tauri && cargo clippy --all-targets -- -D warnings && cargo test)
|
|
```
|
|
|
|
The vault lives in the OS app-data dir (`vault.sqlite`, plus `pairings.json`, `settings.json` and
|
|
`secret-key`, all owner-only). Closing the window keeps Kestrove in the tray so the browser extension
|
|
keeps working; Quit is in the tray menu.
|
|
|
|
## Browser integration (docs/05)
|
|
|
|
```
|
|
extension ─ native messaging (stdio) ─▶ kestrove-nmh ─ local IPC ─▶ app (src-tauri/src/broker.rs)
|
|
└──────────── pairing channel: X25519 → 6 words → AES-256-GCM, end to end ───────────┘
|
|
```
|
|
|
|
* **IPC** (`ipc.rs`): Unix socket `$XDG_RUNTIME_DIR/kestrove/nmh.sock` (macOS: the per-user temp
|
|
dir), dir 0700, socket 0600, peer uid checked on both ends. Windows: `\\.\pipe\kestrove-nmh-<user>`,
|
|
first instance only, local clients only, DACL for the current user, client token SID checked
|
|
(compile-checked only). `KESTROVE_IPC_DIR` isolates an instance for tests.
|
|
* **Pairing** (`channel.rs`, mirrored by kestrove-browser `src/channel.ts`, shared test vectors):
|
|
both UIs show 6 words; the user confirms in the app (needs an unlocked vault) and in the extension.
|
|
Each connection derives a fresh session key from both sides' nonces; messages carry strict
|
|
counters, so replay and reordering fail. `kestrove-nmh` only relays ciphertext.
|
|
* **Protocol** (`broker.rs`): `query` → identities for the origin (`items_for_url`); `fill`/`totp`
|
|
re-check that the item matches the origin and need an unlocked vault; `save` shows a prompt in
|
|
the app (new login or password update).
|
|
* **Native host manifests**: `native-messaging/install.sh` (Linux, macOS) and `install.ps1`
|
|
(Windows, HKCU registry) fill in the host path and extension ids.
|
|
* **Tests**: `cargo test` (unit tests + `tests/nmh_stdio.rs`, which drives the real `kestrove-nmh`
|
|
over stdio through the paired channel). `examples/test-host.rs` is a headless, auto-approving
|
|
stand-in for the app used by kestrove-browser's interop and Chrome end-to-end tests.
|
|
|
|
## Auto-lock
|
|
|
|
10 minutes idle by default (Settings), plus screen lock and sleep (`autolock.rs`). Idle time is the
|
|
system's on Windows (`GetLastInputInfo`) and macOS; on Linux it is activity inside Kestrove (UI input
|
|
and fills). Screen lock: Windows input-desktop check, Linux logind `LockedHint`, macOS session dictionary.
|
|
Sleep: a jump in the wall clock between polls.
|
|
|
|
## Sync and onboarding (docs/03, docs/10)
|
|
|
|
* **First start** offers four ways in: **Use my phone** (default: type the server URL, scan the QR on screen
|
|
with a signed-in phone, compare the 6-digit code, then type only the master password), **Emergency Kit**
|
|
(PDF, or a PNG/JPEG photo of its QR), **Paste setup code**, and **New account** (server URL + the server's
|
|
`KV_SETUP_CODE`).
|
|
* **Device key** (`device_key.rs`): Windows TPM via CNG, else a DPAPI-sealed software key; Linux Secret Service,
|
|
else a 0600 file (with a warning in Settings); macOS dev runs use the keychain. `KESTROVE_DEVICE_KEY=file`
|
|
forces the file store.
|
|
* **Sync** (`sync.rs`) runs after unlock, after a save, every 15 minutes while unlocked, and on "Sync now".
|
|
Lock drops all keys (core), cancels a scan-to-join and revokes an "Add a device" ticket still on screen.
|
|
An integrity alarm shows a hard alert and a banner; syncing that vault stops.
|
|
* **Settings → Devices**: approve pending devices (compare fingerprints), remove devices, **Add a phone or
|
|
tablet** (10-minute single-use QR; Done/Cancel revokes it) and **Approve a computer** (paste the join code a
|
|
new computer shows under "No phone?").
|
|
* **Two instances on one machine**: `KESTROVE_DATA_DIR=/tmp/kv-b Kestrove.app/Contents/MacOS/kestrove-desktop`
|
|
(the second one has no browser integration). `KESTROVE_DEVICE_NAME` overrides the device name.
|
|
* **Live test**: `tests/live_sync.rs` (ignored) drives three instances against a running server; see its header.
|
|
|
|
## Roadmap (M3, kestrove-spec/docs/07)
|
|
- [ ] Unlock with Windows Hello (KeyCredentialManager, TPM) and libsecret on Linux
|
|
- [x] Persistent vault (`VaultCore::open` in app data)
|
|
- [x] Sync, device approval and scan-to-join onboarding
|
|
- [x] Auto-lock on idle, screen lock and suspend
|
|
- [x] Local IPC between `kestrove-nmh` and the app, plus the pairing AEAD channel
|
|
- [x] Native-messaging manifest installers (`native-messaging/install.sh`, `install.ps1`)
|
|
- [ ] **Quick Access** global hotkey (Ctrl+Shift+Space): search, then copy or auto-type (Windows `SendInput`, X11 XTest; Wayland gets copy only)
|
|
- [ ] MSI/deb installers run the manifest installers
|
|
- [ ] Windows 11 passkey plugin provider
|