Search Documentation
Search across all documentation pages
Encryption Model
ExoVault uses a zero-knowledge architecture where all sensitive content is encrypted client-side before reaching the server. The server never has access to plaintext content or encryption keys.
Algorithm#
ExoVault uses AES-256-GCM (Galois/Counter Mode) for all encryption:
- Key length: 256 bits
- IV length: 96 bits (12 bytes), randomly generated per encryption
- Authentication tag: 128 bits
- API: Web Crypto API (works in Node.js 20+ via
globalThis.crypto)
AES-GCM provides both confidentiality (encryption) and integrity (authentication). Any tampering with ciphertext is detected during decryption.
Key Architecture#
Master Encryption Key (MEK)#
Each user has a single Master Encryption Key (MEK) that encrypts all their data. The MEK is:
- Generated as a 256-bit AES-GCM key during account creation
- Never sent to the server in plaintext
- Used for all encrypt/decrypt operations
Key Wrapping#
The MEK is protected by PBKDF2 key wrapping:
- User's password is combined with a random salt
- PBKDF2 derives a wrapping key using SHA-256
- The wrapping key encrypts the MEK using AES-GCM
- Only the encrypted (wrapped) MEK and salt are stored on the server
Password + Salt → PBKDF2 → Wrapping Key → AES-GCM → Wrapped MEKTo decrypt data, the flow reverses:
Password + Salt → PBKDF2 → Wrapping Key → Unwrap MEK → Decrypt ContentAgent Key Authentication#
Agent keys carry an encrypted copy of the MEK. When an agent authenticates with its key, the MCP server receives the MEK in a secure context and uses it for all encrypt/decrypt operations during that session.
Client-Side Encryption Flow#
When writing data (e.g., write_memory, create_note):
- Agent provides plaintext content to the MCP tool
- MCP server generates a random 12-byte IV
- Content is encrypted with AES-256-GCM using the MEK
- Encrypted ciphertext + IV are sent to the Supabase database
- Server stores only encrypted data
When reading data:
- Encrypted ciphertext + IV are fetched from the database
- MCP server decrypts using the MEK
- Plaintext is returned to the agent
What Is Encrypted#
| Data | Encrypted | Notes |
|---|---|---|
| Memory content | Yes | AES-256-GCM |
| Memory summary | Yes | AES-256-GCM |
| Note title | Yes | AES-256-GCM |
| Note content | Yes | AES-256-GCM |
| Note tags | Yes | AES-256-GCM (JSON array) |
| Task title | Yes | AES-256-GCM |
| Task description | Yes | AES-256-GCM |
| Message content | Yes | AES-256-GCM |
| Knowledge link labels | Yes | AES-256-GCM |
| Vault name | Yes | AES-256-GCM |
What Is NOT Encrypted#
| Data | Why Plaintext |
|---|---|
| Memory type | Needed for server-side filtering |
| Importance/confidence | Needed for server-side sorting |
| Entities | Needed for entity search (JSONB containment) |
| Timestamps | Needed for ordering and cleanup |
| Embedding vectors | Needed for pgvector similarity search |
| Blind index tokens | Hashed (not reversible), needed for keyword search |
| Task status/priority | Needed for server-side filtering |
| Message status/category | Needed for server-side filtering |
| User ID, vault ID | Needed for access control |
Blind Index#
For keyword search on encrypted content, ExoVault uses a blind index approach:
- Content is tokenized into words
- Each token is hashed with HMAC-SHA256 using a key derived from the MEK
- Hashed tokens are stored alongside the encrypted content
- Searches hash the query terms the same way and match against stored hashes
This enables keyword search without exposing plaintext to the server. The hashes are one-way -- the server cannot reverse them to recover the original words.
Embedding Security#
Embedding vectors (used for semantic search) are stored in plaintext because pgvector requires them for similarity calculations. While embeddings can theoretically leak semantic information, they cannot be reversed to reconstruct the original text.
For maximum security, you can disable semantic search and rely on blind-index keyword search only. However, this significantly reduces search quality.
Zero-Knowledge Guarantees#
The server never has access to:
- User passwords
- The MEK in unwrapped form
- Plaintext content of any encrypted field
- Plaintext search queries (only hashed tokens or embedding vectors)
Even if the database is compromised, an attacker cannot read the content without the user's password.
Next Steps#
- Connecting Agents -- Agent key authentication
- Search Strategies -- How search works with encryption
- Memory Management -- Encrypted memory operations