Skip to content

chore(client): Phase 9 — bump keyring 2 → 4 (rusqlite blocked)#568

Draft
Detair wants to merge 1 commit into
mainfrom
chore/rusqlite-keyring-bump
Draft

chore(client): Phase 9 — bump keyring 2 → 4 (rusqlite blocked)#568
Detair wants to merge 1 commit into
mainfrom
chore/rusqlite-keyring-bump

Conversation

@Detair

@Detair Detair commented May 13, 2026

Copy link
Copy Markdown
Owner

DRAFT — needs platform-by-platform keyring smoke test before mark-ready

Phase 9 of the dep-update sweep, scoped down: only the keyring bump ships here. rusqlite was attempted but is hard-blocked by a cargo links = "sqlite3" namespace conflict.

What's in this PR

Crate From To
keyring 2 4
keyring-core 1.0.x (new direct dep)
rusqlite 0.32 unchanged (blocked)

Why rusqlite is blocked

cargo's links = "sqlite3" constraint prevents two crates linking to the same native library from coexisting in the dep graph — even when one is an optional, unactivated dep. sqlx 0.8.x pulls sqlx-sqlite (optional, behind a feature we don't enable) which pins libsqlite3-sys 0.30. Any rusqlite ≥ 0.33 wants libsqlite3-sys ≥ 0.31, which collides. The unblock requires sqlx 0.9 (currently only 0.9.0-alpha.1 exists; no stable 0.9 release yet).

Inline comment added in client/src-tauri/Cargo.toml so future contributors don't re-attempt the bump and hit the same wall.

keyring 4 migration

keyring 4.0 split the crate:

  • keyring — credential-store selection (use_*_store functions)
  • keyring-coreEntry, Error, password operations

Six call sites in commands/auth.rs migrated from keyring::Entry/Errorkeyring_core::Entry/Error. entry.delete_password()entry.delete_credential() (renamed in 4.0).

Tauri setup callback now calls keyring::use_native_store(true) — keyring 4 requires explicit store selection at startup. Passing not_keyutils = true picks Secret Service over the kernel keyutils store on Linux (keyutils evicts on session end, which would break refresh-token persistence across reboot). macOS/Windows/Android auto-select platform-native stores.

Required smoke test before mark-ready

Keyring backends are platform-specific and brittle. Each must be validated separately:

  • Linux: log in → quit client → relaunch → session restores from Secret Service
  • Linux: log out → confirm Secret Service entry removed (use secret-tool to verify)
  • macOS: log in → quit → relaunch → session restores from Keychain
  • Windows: log in → quit → relaunch → session restores from Credential Manager
  • Android: log in → app foreground/background cycle → session restores from Keystore

Verification (local)

  • cargo deny check — advisories/bans/licenses/sources all ok
  • cargo check -p vc-client cannot complete locally due to a pre-existing libspa-0.8.0 FFI mismatch with installed PipeWire (reproduces on main). CI's macOS/Windows/Android Tauri builds will validate vc-client compilation.

Tracking

This PR documents the rusqlite block inline; consider opening a tracking issue to revisit when sqlx 0.9 stable ships.

🤖 Generated with Claude Code

## Summary

Phase 9 of the dep-update sweep, scoped down: only the keyring bump
ships in this PR. rusqlite 0.32 → 0.39 was attempted but is hard-
blocked by a cargo `links = "sqlite3"` namespace conflict — see
inline comment in client/src-tauri/Cargo.toml.

  keyring         2 → 4
  keyring-core    (new direct dep, 1.0.x)
  rusqlite        0.32 (unchanged, blocked)

## Why rusqlite is blocked

cargo's `links = "sqlite3"` constraint prevents two crates linking
to the same native library from coexisting in the dep graph — even
when one of them is an optional, unactivated dep. sqlx 0.8.x pulls
sqlx-sqlite (optional) which pins libsqlite3-sys 0.30. Any rusqlite
>= 0.33 wants libsqlite3-sys >= 0.31, which conflicts. The unblock
requires sqlx 0.9 (currently only 0.9.0-alpha.1; no stable 0.9).

Documented inline in Cargo.toml so future contributors don't
re-attempt the bump and hit the same wall.

## keyring 4 migration

keyring split into two crates in 4.0:
- `keyring` — credential-store selection (`use_*_store` functions)
- `keyring-core` — `Entry`, `Error`, password operations

Migration applied:

1. Added `keyring-core` as a direct dep alongside `keyring`.
2. Six call sites in `commands/auth.rs` switched from
   `keyring::Entry/Error` → `keyring_core::Entry/Error`.
3. `entry.delete_password()` → `entry.delete_credential()` (renamed
   in 4.0; `_password` was misleading since the underlying call
   removes the credential entry, not just the password field).
4. Tauri setup callback now calls `keyring::use_native_store(true)`
   at startup. keyring 4 requires explicit store selection before
   any `Entry::new`; keyring 2 had an implicit default. Passing
   `not_keyutils = true` picks Secret Service over the kernel
   keyutils store on Linux — keyutils evicts on session end, which
   breaks refresh-token persistence across reboot. macOS/Windows/
   Android pick the native platform store automatically.

## Verification

- [x] `cargo deny check` — advisories/bans/licenses/sources all ok
- ⚠ `cargo check -p vc-client` blocked locally by pre-existing
  libspa 0.8.0 FFI mismatch with installed PipeWire (reproduces on
  main; unrelated to this change). CI's macOS/Windows/Android Tauri
  builds will validate vc-client compilation.

## Required smoke test (before mark-ready)

DRAFT until you run these manually — keyring backends are platform-
specific and brittle, so platform-by-platform validation is
essential:

- [ ] Linux: log in → quit → relaunch → session restores
- [ ] Linux: log out → confirm Secret Service entry removed
- [ ] macOS: log in → quit → relaunch → session restores (Keychain)
- [ ] Windows: log in → quit → relaunch → session restores (Credential Manager)
- [ ] Android: log in → app foreground/background cycle → session restores

Phase 9 → Phase 10 soak: 24h per the plan.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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