This document defines the security architecture, privacy guarantees, and operational security rules for RL Stats.
The user's data belongs to the user. Period.
This app is designed with a "local-first, privacy-by-default" architecture. No match data, player names, statistics, or usage patterns are transmitted to any server without explicit, informed user consent.
- Match history and results
- Player names encountered in matches
- Personal performance statistics
- Game behavior patterns
- Any data derived from the RL Stats API stream
- Crash reports and diagnostics
- Anonymous usage analytics
- Cloud sync data (only after explicit login + active cloud sync plan)
- App version (for update checks)
- OS version and architecture (for update checks)
- App settings (stored locally)
Scenario: Malicious code or third-party library sends user data to external servers. Mitigation:
- No analytics libraries (Google Analytics, Mixpanel, etc.)
- No crash reporting without explicit opt-in
- No network requests except for updater checks
- CSP
default-src 'self'prevents inline scripts and external resources - Code review required for any new dependency with network capability
Scenario: Attacker intercepts update download and serves malicious binary. Mitigation:
- All updates cryptographically signed with Ed25519
- Public key embedded in binary
- Signature verification before installation
- HTTPS-only for update endpoints
- No downgrade attacks (version check enforced)
Scenario: App vulnerability allows attacker to execute arbitrary code. Mitigation:
- Tauri's minimal permissions model
- No shell plugin access
- No arbitrary file system access outside app directory
- Input sanitization on all external data
- Regular dependency updates
Scenario: Malformed data from game stream corrupts database. Mitigation:
- Parameterized queries exclusively
- Input validation on all parsed fields
- JSON schema validation for event data
- Database WAL mode for crash recovery
Scenario: Sensitive data remains in memory after app closes. Mitigation:
- No password/credential storage (none needed)
- SQLite connection pool properly closed on exit
- Rust's ownership model prevents use-after-free
- No secrets in source code (checked by CI)
- All dependencies pinned and audited
cargo auditruns in CI pipelinenpm auditruns in CI pipeline- No
println!orconsole.logof sensitive data
- Code signing certificate for Windows binaries
- Signed update manifests
- SHA256 checksums published with releases
- Reproducible builds where possible
- Release artifacts built in GitHub Actions (transparent)
- Security issues reported privately (not in public issues)
- Security advisory published for confirmed vulnerabilities
- Patch released within 72 hours for critical issues
- Users notified via update mechanism
By default: Nothing.
The app operates entirely on your local machine. Your match data, statistics, and settings are stored in a local SQLite database on your computer.
- No account creation required
- No personal information collected
- No match data sent to our servers
- No analytics or tracking by default
- No advertising
- No third-party cookies
Crash Reports: If you opt-in, anonymous crash data may be sent to help us fix bugs. This includes stack traces and app version, but NO match data or personal information.
Cloud Sync: If you create an account and activate a cloud sync plan, the app may upload profile metadata, settings, match history, player rows, match events, sessions, caches, friends, and presets needed to reproduce the same local experience on another device. Cloud sync remains off unless the user explicitly enables it.
Update Checks: The app checks our GitHub releases page for updates. This sends your app version and OS platform so we can serve the correct update file.
- Access: All your data is visible in the app
- Export: You can export your data to JSON at any time
- Deletion: You can clear all data from the settings
- Portability: Export format is documented and open
Windows: %APPDATA%\rl-stats\data.db
Settings: %APPDATA%\rl-stats\settings.json
Logs: %APPDATA%\rl-stats\logs\
- GitHub: Used for hosting releases and update manifests
- Supabase: Planned optional cloud sync backend for authenticated users only
- Stripe: Planned optional subscription billing provider
{
"permissions": [
"core:app:default",
"core:event:default",
"core:window:default",
"core:path:default",
"core:fs:allow-appdata-read",
"core:fs:allow-appdata-write",
"core:process:allow-restart",
"updater:default"
]
}default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
connect-src 'self' https://api.github.com;
- No
shellplugin - No
clipboardplugin (unless explicitly needed) - No
global-shortcutplugin - No HTTP requests from frontend (only Rust backend)
- GDPR: Local-first design minimizes compliance burden
- CCPA: No personal information sold or shared
- COPPA: No data collection from minors (app doesn't know user age)
Security concerns: Please open a private security advisory on GitHub or email the maintainers.
Privacy questions: Open a GitHub Discussion or Issue.