Files
keepassgo/docs/local-first-remote-sync-plan.md
T
2026-04-06 21:49:56 -07:00

5.3 KiB
Raw Blame History

Local-First Remote Sync Plan

Goal

Redesign remote-backed vault handling so every platform uses the same local-first model:

  • every vault is a local KDBX file first
  • remote sync is an optional binding on top of that local file
  • shared remote configuration lives in the vault
  • user-specific remote credentials live in the vault
  • app-local state stores only non-secret binding metadata

Android adds only one platform-specific capability on top of that model:

  • share/import the initial local KDBX file between devices

Product Rules

  1. A remote-backed vault must always have a local cache KDBX file.
  2. Opening a remote-backed vault should open the local KDBX first.
  3. Shared remote configuration must be stored in the vault, not only in app state.
  4. Remote credentials must not be stored in plaintext app-local state.
  5. Remote credentials should be stored in the vault and resolved by a stable reference.
  6. The app state file should keep only the metadata needed to reopen the local vault and find the remote binding.
  7. Sync must support both manual and automatic modes.
  8. Android-specific sharing should transfer the KDBX file, not a bespoke remote-secret bundle.

Target Data Model

In-Vault Shared Remote Profile

Store a reusable remote profile in the vault with fields such as:

  • profile ID
  • profile name
  • backend type, initially WebDAV
  • base URL
  • remote object path
  • optional notes or labels
  • default sync policy, if shared defaults are desirable

In-Vault User Credential Binding

Store user-specific credentials in the vault as normal vault data, referenced by:

  • remote profile ID
  • credential entry UUID, or another stable internal reference
  • optional username field override if needed

The credential entry should contain the actual username/password or token.

Local App State

Persist only non-secret binding state such as:

  • local vault path
  • selected remote profile ID
  • selected credential entry reference
  • sync policy override
  • last sync metadata
  • conflict or recovery markers

Core Flows

Create Or Configure Remote Sync

  1. Open or create a local vault.
  2. Create or edit a shared remote profile in that vault.
  3. Create or select a credential entry in that vault.
  4. Bind the local vault to the selected remote profile and credential reference.
  5. Choose manual or automatic sync behavior.

Reopen Existing Remote-Backed Vault

  1. Open the local vault file from app state.
  2. Resolve the selected remote profile from vault contents.
  3. Resolve the credential entry from vault contents.
  4. Offer or perform sync based on the binding policy.

Bootstrap A New Android Device

  1. Share the local KDBX file through Android Sharesheet.
  2. Import and open that KDBX locally on the new device.
  3. Select a remote profile stored in the vault.
  4. Select or create that users credential entry in the vault.
  5. Bind the local vault as the cache for the remote-backed setup.

Migration Requirements

  1. Migrate existing remote connections that save credentials in app state.
  2. On first open after upgrade, move any recoverable remote credentials into the vault.
  3. Replace saved plaintext credential state with a vault credential reference.
  4. If migration cannot write into the vault yet, hold the old state only long enough to prompt the user to complete migration.
  5. Remove legacy local plaintext credential persistence after migration is complete.

Implementation Phases

Phase 1: Domain Model

  • define remote profile structures independent of Gio UI
  • define credential reference structures independent of Gio UI
  • define sync binding state independent of Gio UI
  • add behavior tests for local-first remote-backed vaults

Phase 2: Vault Storage

  • persist remote profiles in the vault
  • persist credential references in the vault
  • resolve credentials from normal vault entries
  • add behavior tests for read/write and lookup semantics

Phase 3: State And Open Flow

  • shrink app state to non-secret metadata only
  • update open flows to always prefer the local cache vault
  • update reopen behavior on all platforms to use the same model
  • add migration coverage for old remote state

Phase 4: Sync Binding

  • bind a local vault to a selected remote profile
  • support manual sync
  • support automatic sync on open/save
  • define conflict and remote-failure handling for the local cache model

Phase 5: Android Bootstrap

  • add Android Sharesheet export of the current local KDBX
  • add Android import flow for a shared KDBX
  • keep the remote pivot flow consistent with desktop after local open

Open Questions

  1. Where in the vault should remote profiles live: custom metadata, dedicated entries, or another KDBX-compatible structure?
  2. Should credential references point to entry UUIDs directly, or should KeePassGO maintain an additional logical identifier?
  3. Should automatic sync run only on open/save initially, or also on app resume?
  4. How should multiple remote profiles per vault be presented in the UI?
  5. What should happen when the credential entry reference no longer resolves?

Implement the shared domain model and tests first:

  • model a local vault plus optional remote binding
  • define in-vault remote profile and credential reference semantics
  • add tests proving app state no longer needs plaintext remote credentials

That slice standardizes the architecture before any Android-specific sharing work begins.