End-to-End Encryption: How We Keep Your Memories Private
Learn how ContextFS implements AES-256-GCM encryption to ensure your memories remain private—even when syncing to the cloud. We can't read your data, and neither can anyone else.
End-to-End Encryption: How We Keep Your Memories Private
When we built ContextFS, privacy was non-negotiable. Your memories contain sensitive information—project secrets, architectural decisions, code patterns. This data should be yours and yours alone.
That's why ContextFS uses end-to-end encryption (E2EE) for cloud sync. Here's how it works.
The Zero-Knowledge Principle
ContextFS follows a zero-knowledge architecture. This means:
- Your encryption keys are generated on your device
- Keys never leave your device
- Data is encrypted before transmission
- We store only encrypted data we cannot read
Even if our servers were compromised, attackers would get meaningless encrypted blobs.
The Encryption Process
Key Derivation
When you enable cloud sync, ContextFS generates a master key using PBKDF2:
import hashlib
master_key = hashlib.pbkdf2_hmac(
'sha256',
device_secret.encode(),
user_salt,
iterations=100000,
dklen=32 # 256 bits
)
The device_secret is generated locally and stored in your system keychain. It never leaves your device.
AES-256-GCM Encryption
Each memory is encrypted using AES-256-GCM, which provides both confidentiality and integrity:
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Generate a unique nonce for each encryption
nonce = os.urandom(12)
# Encrypt the memory content
aesgcm = AESGCM(master_key)
ciphertext = aesgcm.encrypt(nonce, plaintext, associated_data)
Why AES-256-GCM?
- AES-256: Military-grade encryption, approved by NSA for TOP SECRET
- GCM mode: Provides authentication, detecting any tampering
- Unique nonce: Ensures identical plaintexts produce different ciphertexts
What Gets Encrypted
| Data | Encrypted? | Notes |
|---|---|---|
| Memory content | Yes | Full content encrypted |
| Memory summary | Yes | Summaries are sensitive too |
| Tags | Yes | Tags can reveal context |
| Timestamps | No | Needed for sync ordering |
| Memory IDs | No | UUIDs, not sensitive |
Key Management
Device Keys
Each device has its own encryption key derived from:
- A device-specific secret (stored in keychain)
- Your user ID (from authentication)
- A salt (stored server-side)
This means:
- Each device can decrypt your memories
- Losing a device doesn't compromise others
- You can revoke device access independently
Key Rotation
ContextFS supports key rotation for enhanced security:
contextfs cloud rotate-keys
This re-encrypts all memories with a new key, invalidating the old one.
What We Store
On our servers, we store:
{
"id": "mem_abc123",
"user_id": "user_xyz",
"device_id": "dev_456",
"ciphertext": "base64-encoded-encrypted-blob",
"nonce": "base64-encoded-nonce",
"created_at": "2025-01-13T10:00:00Z",
"vector_clock": {"dev_456": 1}
}
The ciphertext is meaningless without your device key. We literally cannot read your memories.
Verification
Don't trust us? Verify the encryption yourself:
- Inspect network traffic: Use Wireshark to see that only encrypted data is transmitted
- Check the source: Our encryption code is open source
- Audit the database: Export your data and verify it's encrypted
Trade-offs
E2EE comes with trade-offs:
Pros:
- Complete privacy
- Protection from server breaches
- Compliance with strict data regulations
Cons:
- No server-side search (we can't index encrypted data)
- Lost keys = lost data (no recovery possible)
- Slightly more complex sync logic
We believe the privacy benefits far outweigh these costs.
Best Practices
To maximize security:
- Enable cloud sync only if needed—local-only is most secure
- Use strong device authentication—your device security is your encryption security
- Keep backups—export your data regularly with
contextfs export - Review connected devices—remove old devices from your dashboard
Your memories are yours. Get started with ContextFS and take control of your AI's context.