Summary
Store the share token and third-party service credentials in the operating system's secure storage on desktop, instead of localStorage.
Why
apps/geolibre-desktop/src/hooks/useDesktopSettings.ts persists the whole settings object — including the share.geolibre.app token, the Cesium ion token, and other credential values — to localStorage under one key. Its own doc comments flag the trade-off and note that moving to OS secure storage on desktop is a possible future.
The consequences are worth stating plainly:
- Any script that runs in the app's origin can read every credential at once. On the web build that is the browser's normal exposure surface, but on desktop we are choosing it, not inheriting it.
- The values sit in plaintext in the webview's profile directory, readable by any process running as the user and picked up by any backup that copies it.
- There is no per-credential lifetime; a token stays until someone thinks to clear it.
- Tokens for genuinely paid services (Cesium ion, Google Maps, commercial map services) are the ones a user is least willing to store loosely, which makes this a real adoption blocker for those integrations.
Proposal
- Add a small credential-store abstraction in the desktop app with two backends: OS secure storage on Tauri (Keychain on macOS, Credential Manager on Windows, Secret Service / libsecret on Linux — via
keyring from the Rust side, exposed as Tauri commands), and localStorage on the web build, unchanged.
- Move credential-shaped settings out of the single settings blob and behind that abstraction, keyed individually so one credential can be read, replaced, or deleted without touching the others: the share token, Cesium ion token, Google Maps API key, geocoding
apiKeys, custom request headers for authenticated 3D Tiles, and PostGIS DSNs.
- Keep non-secret preferences exactly where they are — this should not turn theme or locale into keychain entries.
- Migrate on first launch: read any existing values from
localStorage, write them to the secure store, then remove them from the settings blob.
- Be explicit in the UI about which build the user is on. A short line in Settings ("credentials are stored in your system keychain" / "credentials are stored in this browser") is more honest than silence, and it is the same sentence that makes the web build's limits understandable.
Scope notes
- Linux desktops without a running Secret Service daemon need a defined fallback. Prefer failing loudly to silently writing plaintext.
- The Mac App Store build is sandboxed; confirm keychain access works there under the entitlements template before assuming it does.
- The Jupyter (
python/) embed runs the web build inside a notebook — it stays on the browser-storage path.
- This issue is storage only. It does not change what any credential is used for.
Effort
Medium.
Part of #1665 (access control umbrella).
Summary
Store the share token and third-party service credentials in the operating system's secure storage on desktop, instead of
localStorage.Why
apps/geolibre-desktop/src/hooks/useDesktopSettings.tspersists the whole settings object — including theshare.geolibre.apptoken, the Cesium ion token, and other credential values — tolocalStorageunder one key. Its own doc comments flag the trade-off and note that moving to OS secure storage on desktop is a possible future.The consequences are worth stating plainly:
Proposal
keyringfrom the Rust side, exposed as Tauri commands), andlocalStorageon the web build, unchanged.apiKeys, custom request headers for authenticated 3D Tiles, and PostGIS DSNs.localStorage, write them to the secure store, then remove them from the settings blob.Scope notes
python/) embed runs the web build inside a notebook — it stays on the browser-storage path.Effort
Medium.
Part of #1665 (access control umbrella).