Skip to content

fix(sync): recover from a locked keyring without restarting the app - #215

Merged
gnacho merged 1 commit into
mainfrom
fix/keyring-locked-recovery
Sep 17, 2026
Merged

gnacho merged 1 commit into
mainfrom
fix/keyring-locked-recovery

Conversation

@gnacho

@gnacho gnacho commented Sep 17, 2026

Copy link
Copy Markdown
Owner

Problem

When the system Secret Service restarts (e.g. gnome-keyring-daemon crashing outside the PAM phase), its collections come back Locked. The app reports "the password keyring is locked", #170's capped retry (5 attempts over ~1 min) exhausts long before the keyring is unlocked, and afterwards nothing re-checks the credentials: in push-ready configs the remote interval is dropped (#185), other triggers just queue up, and the parked folder never retries on its own. Only relaunching the app recovered.

Verified today on a live session: with a persistent D-Bus connection, Secret.Service.unlock(collections) unlocks both the login and the default collection without prompting (they share the login password), so an in-app unlock attempt is viable.

Fix

Two complementary changes, both minimal:

  1. Unlock attempt in the lookup path: when a credential lookup reports Locked, the engine asks the source to unlock the locked collections and retries the lookup once. CredentialsStore::unlock_locked_collections() iterates all collections and unlocks the locked ones; the crate's blocking client keeps its connection alive through the prompt, which is exactly what gnome-keyring needs to auto-complete it. The common case (session-keyring collections) heals with no user interaction.
  2. Slow keyring watch: once Keyring-locked state persists until the app restarts #170's fast backoff budget is exhausted, the scheduler falls back to a slow periodic re-check (60 s, uncapped) mirroring the server probe of Mark folder offline after N consecutive failed syncs regardless of error class #179. Each tick re-enters the engine without touching the visible state, and re-arms itself after every still-locked outcome, so the folder recovers on its own whenever the keyring is unlocked later - by the user, the session, or the unlock attempt above.

No new UI states, no new translated strings.

Tests

  • keyring_retry_budget_is_capped_and_falls_back_to_a_watch (updated) and keyring_watch_recovers_without_restart_once_unlocked: after the fast budget is exhausted the watch keeps re-entering the engine and a later successful run recovers to IdleOk with no restart.
  • locked_lookup_retries_once_after_a_successful_unlock and locked_lookup_without_unlock_is_not_retried: engine-level, with injectable credential sources (no real keyring).

Closes #214

…loses #214)

When the Secret Service restarts (e.g. gnome-keyring-daemon crashing
outside the PAM phase), its collections come back locked and the app
parks in the keyring-locked state. Issue #170's capped retry exhausts
long before the user unlocks the keyring, and afterwards nothing
re-checks the credentials: new triggers either never arrive (push-ready
configs drop the remote interval) or bounce off the parked state, so
only relaunching the app recovered.

Two complementary changes:

- The engine now attempts to unlock the locked collections via the
  Secret Service when a lookup reports Locked, then retries the lookup
  once. GNOME collections created by the desktop session share the
  login password, so the service completes the unlock prompt on its own
  while the client connection stays alive: the common case heals with
  no user interaction.
- Once #170's fast backoff budget is exhausted, the scheduler falls
  back to a slow periodic keyring watch (60 s, uncapped, like the
  server probe of #179) that re-enters the engine until a run resolves
  credentials, so the folder also recovers when the keyring is unlocked
  by any other means. No new visible states or strings.
@gnacho
gnacho merged commit 7c49f51 into main Sep 17, 2026
2 checks passed
@gnacho
gnacho deleted the fix/keyring-locked-recovery branch September 17, 2026 19:36
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.

Recover from a locked keyring without restarting the app

1 participant