This repository is the complete, verbatim source of the Vault feature in Lemonade: the local-only encrypted store that holds a user's API keys and injects them into agent terminal sessions.
It exists so that anyone can audit the code that touches their secrets, rather than take our word for it.
| File | Role |
|---|---|
src/vault.rs |
The entire Vault backend: encryption, storage, PIN gate, all 12 IPC commands, and the two egress routes. 927 lines including tests. |
src/redact.rs |
The terminal-output redactor that masks vault values in the PTY stream before they reach the UI. 355 lines including tests. |
WHITEPAPER.md |
The security design document: architecture, threat model, and an honest account of what the Vault does not protect against. |
- Extracted verbatim, unmodified from the Lemonade application source as shipped in v2.5.1 (Vault first shipped in v2.5.0).
- Source commit:
53a6ea951e808be0f58a7573de08cd19f5b6b6be(private repolemonade-app; pathssrc-tauri/src/commands/vault.rsandsrc-tauri/src/pty/redact.rs). - These files will be re-published on any release that changes them, with the new commit hash noted here.
Secret values enter the app once, are sealed with AES-256-GCM under a key held in the OS credential store, and leave by exactly two Rust-side routes (child-process environment variables and the OS clipboard). No IPC command ever returns a secret value to the frontend.
Read WHITEPAPER.md for the full design, then verify the claim against the code: every #[tauri::command] in vault.rs is the complete IPC surface of the feature, and none of their return types carries a value field.
This is an audit copy, not a standalone crate. The files compile inside the Lemonade Tauri application, and two things are external to what is published here:
use super::license::require_license;refers to Lemonade's licensing module. Its signature ispub fn require_license() -> Result<(), String>; it gates every command to licensed installs and touches no vault data. Stub it asOk(())if you want to type-check the file in isolation.redaction_secrets()andinjectable_env()are consumed by the PTY manager (pty/manager.rs), which is out of scope for this audit but is described in the whitepaper's egress section.
Relevant dependency versions (from the application's Cargo.toml):
tauri = "2"
aes-gcm = "0.10"
keyring = { version = "3", features = ["windows-native", "apple-native"] }
argon2 = "0.5"
zeroize = { version = "1", features = ["derive"] }
base64 = "0.22"
uuid = { version = "1", features = ["v4"] }
serde = { version = "1", features = ["derive"] }You can check the main claims against the installed app directly:
- Ciphertext at rest. Open
%APPDATA%\dev.getlemonade.lemonade\vault.enc(Windows) or~/Library/Application Support/dev.getlemonade.lemonade/vault.enc(macOS). It is a small JSON envelope{v, nonce, data}whose payload is base64 AES-256-GCM ciphertext. Your keys do not appear in it. - The key lives in your OS credential store. Windows: Credential Manager, entry
Lemonade Vault/ userdek. macOS: Keychain Access, itemLemonade Vault. - Nothing phones home. Run Wireshark, Little Snitch, or
netstatwhile adding, listing, and injecting vault keys. Vault operations perform no network I/O; the only network activity in the app is license validation, the updater, usage meters, and any providers you configure yourself. - The frontend never sees a value. Open the WebView devtools and observe the IPC responses:
vault_listreturns metadata with a masked preview (…3456), andvault_copy_secretreturns only an integer (the clipboard clear delay).
If you find a flaw in this code, email drew.devteam@gmail.com with the details. Please do not open a public issue for an unpatched vulnerability.
The contents of this repository are published under the MIT License (see LICENSE). This covers the published module for audit and reuse; the Lemonade application as a whole remains proprietary.