Skip to content

Security: gambletan/cortex

Security

SECURITY.md

Security

Threat Model

What Cortex Protects Against

ThreatProtection
Cloud storage breachOplog files are AES-256-GCM encrypted (opt-in). An attacker with access to your iCloud/Google Drive/OneDrive/Dropbox cannot read synced memories.
Memory forensicsSensitive data (text, facts, preferences) is zeroized on drop via the zeroize crate. Encryption keys are securely cleared from memory.
Accidental sync of private dataPrivate memories (the default) never leave the local SQLite database. Only memories explicitly marked as Shared or Public are written to the sync oplog.
Man-in-the-middleNo network calls. Sync happens through local filesystem only. Cloud providers handle transport encryption.
Telemetry/trackingZero telemetry. Zero analytics. Zero phone-home. Verify: grep -r "reqwest|hyper|TcpStream|UdpSocket" cortex-core/src/ returns nothing.

What Cortex Does NOT Protect Against

ThreatWhy
Root access on your deviceIf an attacker has root, they can read the SQLite database directly. Use full-disk encryption (FileVault, BitLocker, LUKS).
Weak passphraseEncryption is only as strong as your passphrase. Use a strong, unique passphrase.
Side-channel attacksNo protection against timing, cache, or power analysis on cryptographic operations.
Compromised buildIf you run a tampered binary, all bets are off. Build from source or verify release checksums.

Data Storage Locations

DataLocationEncrypted?
All memories (SQLite)User-specified path (default: local)No (use OS full-disk encryption)
Sync oplog filesUser's cloud storage folderYes, if passphrase configured (AES-256-GCM)
Sync manifestcortex-sync/manifest.json in sync folderNo (contains only salt + schema version, no sensitive data)
Device metadatacortex-sync/devices/{id}/device.jsonNo (device name + OS only)

Encryption Details

  • Algorithm: AES-256-GCM (authenticated encryption with associated data)
  • Key derivation: Argon2id (memory-hard, resistant to GPU/ASIC attacks)
    • Parameters: time_cost=3, mem_cost=64MB, parallelism=1
    • 16-byte random salt (stored in manifest.json)
  • Per-line nonce: 12-byte random nonce per oplog line (never reused)
  • Format: ENC1:<base64(nonce[12] || ciphertext || tag[16])>
  • Key storage: Derived at runtime from passphrase, never persisted. Zeroized on drop.

Privacy Levels

LevelSync BehaviorDefault?
PrivateNever leaves local deviceYes
SharedSyncs to devices in specified scopeNo
PublicSyncs to all connected devicesNo

Zero Telemetry Verification

Cortex makes zero network calls. You can verify this yourself:

# Search for any networking code in the core library
grep -r "reqwest\|hyper\|TcpStream\|UdpSocket\|connect\|dns" cortex-core/src/
# Result: no matches# The HTTP server (cortex-http) and MCP server are local-only listeners# They do not make outbound connections

Responsible Disclosure

If you discover a security vulnerability, please report it via GitHub Issues with the security label, or contact the maintainers directly.

There aren't any published security advisories