Implement local-first remote sync flow
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
# 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 user’s 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?
|
||||
|
||||
## Recommended First Slice
|
||||
|
||||
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.
|
||||
Reference in New Issue
Block a user