← Back to Desktop application starters · project planning pack

Skill · Version 1.0.0

Desktop storage and credentials

Separates desktop application data, reliable local writes and OS-protected credentials into appropriate storage locations.

desktop-storage-credentials

Agents using this skill

See how it helps

When is it useful?

Use when local databases, configuration and tokens need consistent ownership.

What does it help you do?

  • Uses operating-system directories for persistent data, caches and logs.
  • Protects SQLite ownership and config-file replacement against interrupted writes.
  • Stores secrets through the system credential facility with explicit failure handling.

Try asking this

Move API tokens into the system keychain and preserve valid settings if a write is interrupted. Interrupt a settings-file replacement and deny keychain access. The previous valid settings should survive, with a clear credential error and no token in logs.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

Desktop Storage & Credentials

User data on a desktop machine must survive application updates, unexpected power loss, and multi-window access without corruption, while sensitive tokens stay encrypted by the OS credential store.

OS-Standard Directory Layout

Always store files in their designated OS directories—never inside the application installation folder (Program Files or /Applications/App.app), which is read-only for standard users and overwritten on every update:

Data Category macOS Windows Linux (XDG)
User Data & SQLite DB ~/Library/Application Support/<App> %APPDATA%\<App> ~/.config/<App> or ~/.local/share/<App>
Disposable Cache ~/Library/Caches/<App> %LOCALAPPDATA%\<App>\Cache ~/.cache/<App>
Diagnostic Logs ~/Library/Logs/<App> %APPDATA%\<App>\logs ~/.local/state/<App>/logs

SQLite & Config File Integrity on Desktop

  1. Single-Process SQLite Ownership & WAL Mode:
    • Never open and write to the same SQLite database file simultaneously from multiple renderer processes and background workers without coordination (SQLITE_BUSY / lock contention). Route all database writes through the single backend/main owner process.
    • Enable Write-Ahead Logging (PRAGMA journal_mode = WAL; PRAGMA synchronous = NORMAL; PRAGMA foreign_keys = ON; PRAGMA busy_timeout = 5000;) at connection startup, and run PRAGMA wal_checkpoint(TRUNCATE) on clean shutdown.
  2. Atomic JSON Config Writes:
    • Never overwrite settings.json in place with fs.writeFileSync(configPath, data)—if the OS crashes or battery dies mid-write, the file is truncated to 0 bytes and the app fails to boot on restart!
    • Write to settings.json.tmp.<pid>, flush (fsync), and fs.renameSync atomically over settings.json. Keep a .bak fallback or schema recovery when parsing fails.

Secret & Token Storage via OS Keychain

  • Never store API keys, OAuth tokens, or session secrets in plaintext localStorage or unencrypted JSON:
    • In Electron: use safeStorage.encryptStringAsync() / safeStorage.decryptStringAsync() (backed by macOS Keychain, Windows DPAPI, and Linux libsecret/kwallet) and store the encrypted base64 ciphertext on disk, or store local server auth tokens in owner-only (mode: 0o600) files.
    • In Tauri: use tauri-plugin-stronghold or the keyring crate to store secrets in the native OS credential manager.

Included files 1

  • SKILL.md