gg
Overview
The devices are Google Pixels wiped and flashed with GrapheneOS - no Google services, no telemetry, full verified boot. Stock Android wasn't an option.
The app encrypts everything at rest with SQLCipher, locks behind a PIN with brute-force protection, and syncs only over local WiFi. Inventory fields (GPS coordinates, photos) are gated behind a separate password that doubles as user tiering - only users with the password can access inventory on both mobile and dashboard. These fields get their own encryption layer, so even a database extraction yields nothing without the second key.
The web dashboard decrypts and visualizes synced backup data - period-aware summaries, category breakdowns, debt tracking - all with client-side decryption via the Web Crypto API. Sync is WiFi-only with silent failures by design - if the server is unreachable, the app continues without interruption.
Tech Stack
Mobile Client
- Kotlin + Jetpack Compose
- Room + SQLCipher
Web Dashboard
- Flask
- React + TypeScript
Security
- PBKDF2-HMAC-SHA256 (100k iterations)
- AES-256-GCM encryption
- Android Keystore master key
- Web Crypto API (client-side)
Platform
- Google Pixel + GrapheneOS
- No Google Play Services dependency
- WiFi-only sync (no cellular)
- Self-hosted sync server
Encryption Architecture
Three independent encryption layers, each with its own key material:
Layer 1: Database (SQLCipher) - Full database encryption at rest - Key derived from PIN via Android Keystore - Transparent to application code Layer 2: Backup Files - Format: [salt:16][iv:12][ciphertext + GCM tag] - PBKDF2-HMAC-SHA256, 100k iterations, 256-bit key - Used for export/import and WiFi sync Layer 3: Inventory Secure Fields - Separate password doubles as access control (user tiering) - Format: Base64([salt:16][iv:12][ciphertext + GCM tag]) - GPS coords + photos encrypted per-field - Decrypted client-side on dashboard via Web Crypto API