End-to-end by design
Learn how OneLine keeps your words private
Everything you write encrypts in your browser using a key derived from your passphrase. We never store or see that passphrase. If a passphrase is wrong, we only discover it because the ciphertext fails to decrypt. Servers merely hold encrypted blobs in Supabase until your vault is unlocked again.
The path of your data
- On-device first: Your browser derives an AES-256 key from your passphrase using PBKDF2. That key never leaves your device.
- Encrypted transit & storage: Entries are encrypted with AES-GCM before they leave your device, then stored as ciphertext in Supabase. We do not keep a copy of your passphrase.
- Vault locked by default: Without the correct passphrase, decryption fails and the vault stays shut. The only signal we see is a decryption error.
- Backed by Supabase: All encrypted rows live in Supabase’s managed Postgres. You can export or delete them anytime to meet EU data rights.
What servers see
{
"content_cipher": "b64...",
"iv": "b64...",
"created_at": "2024-10-14T21:10:00Z"
}No plaintext is stored or logged. Your passphrase is never transmitted.
Decryption flow
When you return to read
- Unlock locally: Enter your passphrase; the key is derived again in your browser.
- Decrypt client-side: We pull ciphertext from Supabase and decrypt it locally. If the passphrase is wrong, AES-GCM fails and no text is shown.
- Stay offline-friendly: If the data is cached, you can read locally until you sign out or clear storage.
Zero-knowledge stance
No passphrase retention
We cannot reset or recover your passphrase. Use a password manager if you need backup. Failed decryptions simply tell us the key is incorrect—nothing more.
Where data lives
Supabase hosting
Encrypted entries, IVs, and metadata are stored in Supabase (managed Postgres) within your configured region. Export and delete tools help you comply with EU and Spanish privacy requirements.
Science-backed storytelling
How your story is generated
When you request a story or reflection, your entries decrypt locally first. Only then does your browser send the freshly decrypted text to Gemini over TLS, along with the parameters needed for the narrative. The request originates from your device and Gemini sends the summary straight back to it—plaintext never touches OneLine servers.
- Decrypt only on your device: Your vault unlocks locally; plaintext exists only in browser memory while composing the prompt.
- Send directly to Gemini: The decrypted snippet goes from your browser straight to Gemini over TLS—no OneLine proxy, no intermediate storage.
- Receive and re-encrypt: Gemini replies to your device; if you save the story, it re-encrypts immediately before syncing back to Supabase. No other system ever holds the decrypted output.
Transparency snapshot
Where plaintext exists
- Only in your browser memory while the vault is open.
- Temporarily inside Gemini's secure runtime to produce the response.
- Never on OneLine servers or logs—saved stories are re-encrypted instantly before syncing to Supabase.
What about Supabase?
Encrypted vault storage
Supabase only stores ciphertext rows plus metadata like IVs and timestamps. Gemini never writes to Supabase, and Supabase never receives plaintext. Export or delete the encrypted rows anytime to stay compliant with EU and Spanish privacy rules.
Why this matters
OneLine is built for skeptics: private by architecture, transparent about storage, and upfront about trade-offs. Nothing meaningful can leak because plaintext never touches our servers.
When you sign out or lock the vault, entries revert to ciphertext. When you sign back in, your device does the heavy lifting to decrypt them. If you ever want to double-check, use the encrypted view in History to see exactly what servers receive.
Questions? Reach out and we'll walk you through how encryption, Supabase storage, and consent-first summaries work together.