Vault is built with privacy and security as core principles. Your financial data is sensitive, and we take protecting it seriously. This document outlines our security practices, data handling policies, and how to report security vulnerabilities.
All transaction data stays on your device. We guarantee:
- No cloud storage or synchronization
- No remote databases or third-party services
- No user accounts or authentication servers
- No analytics or telemetry collection
- No tracking or usage monitoring
Your financial data is stored exclusively in a local SQLite database on your machine.
The only external network communication occurs when:
-
Gemini API Categorization - Merchant names are sent to Google's Gemini API for categorization
- Only merchant names are transmitted (e.g., "STARBUCKS #12345")
- Transaction amounts, dates, and other details are NOT sent
- See Gemini API Data Usage below
-
Software Updates (if enabled) - Checking for new versions of the application
- Transaction amounts
- Transaction dates
- Account numbers or identifiers
- Personal identifying information
- Full transaction history
- Database contents
Transaction data is stored in a local SQLite database:
Location:
- macOS:
~/Library/Application Support/Vault/transactions.db - Windows:
%APPDATA%\Vault\transactions.db - Linux:
~/.config/Vault/transactions.db
Security Measures:
- File permissions set to user-only read/write (0600)
- No remote access capabilities
- Can be encrypted at rest using OS-level encryption (FileVault, BitLocker, etc.)
For additional security, you can enable SQLite encryption:
Using SQLCipher (Advanced Users):
# Install SQLCipher variant
npm install better-sqlite3-sqlcipher
# Set encryption key in .env.local
SQLITE_ENCRYPTION_KEY=your-secure-key-hereNote: Database encryption is optional and must be configured manually. Encrypted databases cannot be opened without the encryption key.
When categorizing transactions, only the merchant name is sent to the Gemini API:
{
"prompt": "Categorize this merchant: STARBUCKS #12345",
"categories": ["Dining", "Groceries", "Gas", "Travel", "Other"]
}- Transaction amounts
- Transaction dates
- Full transaction records
- Account information
- User information
According to Google's Gemini API Terms of Service:
- Prompts and responses may be temporarily stored for abuse prevention
- Data is not used to train models (when using the paid API)
- Review Google's Gemini API Privacy Policy for full details
To minimize data transmission:
- Merchant names are cached locally after first categorization
- Subsequent transactions from the same merchant use cached categories
- No repeat API calls for known merchants
Never commit API keys to version control. Store your Gemini API key in:
.env.local (git-ignored)
Example:
GEMINI_API_KEY=your_api_key_here- Use Environment Variables - Never hardcode API keys
- Restrict API Key Permissions - Limit to Gemini API only
- Rotate Keys Periodically - Generate new keys every 90 days
- Monitor Usage - Check Google Cloud Console for unexpected usage
- Use API Key Restrictions - Limit by IP address or application (if applicable)
If your API key is accidentally exposed:
- Immediately revoke the key in Google Cloud Console
- Generate a new key and update
.env.local - Monitor billing for unauthorized usage
- Review logs for suspicious activity
When importing CSV files:
- Files are read directly from disk (no upload to servers)
- Parsed in-memory using PapaParse
- Data written directly to local SQLite database
- Original CSV files are NOT stored by the application
Recommendations:
- Store CSV exports from your bank in encrypted folders
- Delete CSV files after importing if no longer needed
- Use OS-level file encryption for sensitive directories
- Avoid storing CSVs in cloud-synced folders (Dropbox, iCloud, etc.)
Electron security features enabled:
{
contextIsolation: true,
nodeIntegration: false,
sandbox: true
}Strict CSP headers prevent XSS attacks:
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
Inter-process communication between main and renderer processes uses validated channels:
- No dynamic IPC channel registration
- Input validation on all IPC messages
- Type-safe communication via TypeScript
Dependencies are scanned for vulnerabilities:
# Check for vulnerabilities
npm audit
# Auto-fix vulnerabilities
npm audit fix- Regularly update dependencies (monthly security patches)
- Review dependency licenses for compatibility
- Minimize third-party dependencies
- Use well-maintained, reputable packages
All dependencies use exact versions (no ^ or ~) to prevent unexpected updates:
{
"dependencies": {
"better-sqlite3": "9.2.0",
"electron": "28.0.0"
}
}Before building:
- Verify Git commits are signed (GPG signatures)
- Check package checksums match published versions
- Review dependency tree for unexpected packages
# Verify npm package integrity
npm ls
npm audit signatures# Clean install (removes existing node_modules)
rm -rf node_modules
npm ci
# Build with integrity checks
npm run buildAnyone with access to your computer can:
- Copy the SQLite database file
- Read transaction data (if database is not encrypted)
- Modify or delete data
Mitigations:
- Use OS-level user accounts with strong passwords
- Enable full disk encryption (FileVault, BitLocker)
- Lock your computer when away from desk
- Consider SQLite encryption for high-security needs
Merchant names are transmitted to Gemini API for categorization. While minimal, this does expose:
- Names of businesses you transact with
- Frequency of categorization requests (new merchants)
Mitigations:
- Review cached merchants before syncing (manual mode - future feature)
- Option to disable auto-categorization and use manual categories only (future feature)
If you discover a security vulnerability:
DO NOT open a public GitHub issue.
Instead:
-
Email: security@example.com (replace with actual email)
-
Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
-
Response Time:
- Acknowledgment within 48 hours
- Status update within 7 days
- Fix deployed within 30 days (for critical vulnerabilities)
- We follow responsible disclosure practices
- Security researchers will be credited (with permission)
- Critical vulnerabilities fixed immediately
- Users notified of security updates
- Watch this repository for security announcements
- Enable automatic updates in the app (when available)
- Check Releases regularly
# Check current version
npm run version
# Update to latest
git pull origin main
npm install
npm run build- Use Strong OS Passwords - Protect access to your computer
- Enable Disk Encryption - FileVault (macOS), BitLocker (Windows), LUKS (Linux)
- Lock Your Computer - When stepping away
- Regular Backups - Backup database file (with encryption)
- Keep Software Updated - OS, Electron app, dependencies
- Secure API Keys - Treat like passwords
- Review Permissions - Check file permissions on database
- Use SQLite encryption (SQLCipher)
- Store database in encrypted volume (VeraCrypt)
- Use hardware security keys for system login
- Monitor file access logs for database file
- Run application in sandboxed environment
Our architecture is built around privacy principles:
- Data Minimization - Collect only what's necessary
- Local-First - No cloud storage requirements
- User Control - You own and control all data
- Transparency - Open source code for audit
- No Tracking - Zero analytics or telemetry
Since data never leaves your device (except merchant names to Gemini):
- No data controller/processor relationship
- No cross-border data transfers
- No right to access requests (you already have all data)
- No data retention policies needed
All data is stored in standard formats:
- SQLite database (portable, standard format)
- CSV export capability (planned)
- No proprietary or encrypted formats (unless user-enabled)
For security-related questions:
- General: Open a GitHub issue (non-sensitive topics)
- Vulnerabilities: Email security@example.com (replace with actual email)
- Privacy Concerns: Review this document and
docs/ARCHITECTURE.md
Last Updated: 2026-01-02
This security policy may be updated as the application evolves. Check back regularly for changes.