Lumi stores everything locally on your Mac. Your resume, notes, API keys, and sessions never leave your machine. This report details every security measure in the app.
| Area | Protection | Status |
|---|---|---|
| API keys at rest | AES-256-GCM encryption, HKDF key derivation | Pass |
| Playbook documents | AES-256-GCM encrypted .enc files | Pass |
| File permissions | Owner-only (0600) on all encrypted files | Pass |
| License verification | URL-encoded POST, format-validated, HTTPS-only | Pass |
| Network transport | All API calls over TLS (HTTPS) | Pass |
| Update integrity | Ed25519 signed .lumi update files | Pass |
| Speech processing | 8-layer anti-hallucination filter | Pass |
| Screen sharing | sharingType = .none on all windows | Pass |
| Data residency | Everything local — no cloud, no telemetry | Pass |
| Account required | None — no email, no signup | Pass |
All sensitive data (API keys, playbook documents) is encrypted using AES-256-GCM — the same standard used by banks and governments.
.enc binary files — plaintext is never written to disk| Data | Location | Encrypted |
|---|---|---|
| OpenAI API key | ~/Library/Application Support/Lumi/.*.enc | Yes |
| Anthropic API key | ~/Library/Application Support/Lumi/.*.enc | Yes |
| License key | ~/Library/Application Support/Lumi/.*.enc | Yes |
| Playbook documents | ~/Library/Application Support/Lumi/playbooks/*.enc | Yes |
| Session data | ~/Library/Application Support/Lumi/sessions/*.json | No (JSON) |
| User preferences | UserDefaults | No (non-sensitive) |
Lumi only makes network requests to three services — all over HTTPS:
| Service | Purpose | Data sent |
|---|---|---|
| OpenAI API | Whisper transcription, GPT chat, GPT-4o vision | Audio chunks, text queries, screenshots |
| Anthropic API | Claude chat (optional) | Text queries only |
| Gumroad API | License key verification | Product ID + license key (URL-encoded) |
When you enter a license key, Lumi verifies it with Gumroad's API:
Lumi uses macOS sharingType = .none — an OS-level API that excludes windows from all screen capture APIs. This is not a CSS hack or opacity trick.
sharingType and window level propertiesWhisper (OpenAI's speech-to-text) can produce garbage output from silence, music, or cross-language audio. Lumi applies 8 layers of filtering:
| Layer | What it catches |
|---|---|
| 1. Energy gate | Silence — no API call if audio is below energy threshold |
| 2. Speech confidence | no_speech_prob > 0.95 — Whisper says it's not speech |
| 3. Language mismatch | Requested English, Whisper detected Welsh — reject |
| 4. Script detection | Vietnamese/CJK characters in English mode — reject |
| 5. Pattern filter | "subscribe", prompt echoes, ALL CAPS, repetitive text |
| 6. Cross-chunk dedup | Same phrase from different audio chunks — reject duplicate |
| 7. Music loop | 3+ consecutive identical outputs — suppress as music |
| 8. Gibberish flood | 4+ consecutive short disconnected phrases — suppress as noise |
.lumi) are cryptographically signedlumidesk.app/version.json on launch for newer versionsRemove the app and all stored data in one step:
rm -rf ~/Library/Application\ Support/Lumi/
rm -rf /Applications/Lumi.app
This removes all encrypted API keys, playbooks, sessions, and preferences. Nothing remains.
| Finding | Severity | Status |
|---|---|---|
| License key URL encoding | Critical | Fixed |
| Key derivation (SHA256 → HKDF) | High | Fixed |
| File permissions (644 → 600) | Medium | Fixed |
| License key format validation | Medium | Fixed |
| Prompt echo hallucination | Medium | Fixed |
| Gibberish flood detection | Medium | Fixed |
| Legacy encryption migration | Medium | Fixed |
| Update signer public key | Low | Pending (pre-release) |
| API keys in memory | Low | Accepted (desktop app risk model) |
| Certificate pinning | Low | Accepted (HTTPS sufficient) |