Security & Privacy Model

June 14, 2026 · View on GitHub

Last updated: June 2026 · Mnemosyne v3.7.0

You are solely responsible for the content stored in Mnemosyne. Mnemosyne Sync supports optional client-side encryption. When disabled, memory content travels over TLS and is stored according to your infrastructure's security settings.


Philosophy

Mnemosyne is built on three security principles:

  1. User sovereignty — You own your data. Mnemosyne has no telemetry, no tracking, no cloud dependency. The database file is yours.
  2. Privacy by design — The default configuration stores everything locally. No data ever leaves your machine unless you explicitly enable sync.
  3. Minimal trust in remote infrastructure — When sync is enabled, optional client-side encryption ensures that even the remote server cannot read your memory contents. The remote side sees only routing metadata (timestamps, event IDs, device IDs).

Data at Rest

Mnemosyne stores all data in a single SQLite file (default: ~/.hermes/mnemosyne/data/mnemosyne.db).

LayerDataSecurity
Working memoryRecent agent context, preferences, factsPlaintext in SQLite. File permissions control OS-level access.
Episodic memoryConsolidated long-term memories, vector embeddingsSame as working memory. Embeddings are mathematical vectors, not reversible to original text.
TripleStoreTemporal knowledge graph (subject-predicate-object triples)Same as working memory.
ConfigAPI keys, endpoints, encryption settingsStored in environment variables or config.yaml. Never logged or transmitted.

Recommendations for data at rest:

  • Set restrictive file permissions: chmod 600 ~/.hermes/mnemosyne/data/mnemosyne.db
  • Use full-disk encryption (LUKS, FileVault, BitLocker)
  • On shared machines, use memory banks for isolation: mnemosyne --bank <name>

Data in Transit (Sync)

When mnemosyne sync is enabled, memory content travels between instances over HTTP/HTTPS.

Without Client-Side Encryption

What the remote server seesExample
Memory content (plaintext)"User prefers dark mode"
Importance scores0.9
Memory type / source"preference", "cli"
Event metadataevent_id, timestamp, device_id, operation (CREATE/UPDATE/DELETE)
Vector embeddingsOpaque binary data (not reversible to text, but could be used for similarity analysis)

Protection: TLS encryption between instances (recommended). Behind a reverse proxy (Caddy, Nginx, Traefik) with automatic HTTPS.

With Client-Side Encryption (--encrypt)

What the remote server seesExample
Memory contentEncrypted::<base64 ciphertext> (unreadable without the key)
Importance scoresEncrypted alongside content
Memory type / sourceEncrypted alongside content
Unencrypted metadata (required for routing)event_id, timestamp, device_id, operation
Vector embeddingsEncrypted as part of payload

Protection: Authenticated encryption via cryptography.fernet.Fernet (AES-128-CBC) or nacl.secret.SecretBox (XSalsa20-Poly1305). The remote server cannot decrypt any payload content. See Encryption in Mnemosyne Sync below.


Encryption in Mnemosyne Sync

Overview

Client-side encryption is optional but first-class. When enabled, memory payloads are encrypted on the sending side before transmission and decrypted on the receiving side after receipt. The remote server (including the Mnemosyne sync endpoint) never has access to the encryption key.

How It Works

┌─────────────────────┐           ┌─────────────────────┐
│   Local Instance    │           │   Remote Instance   │
│                     │           │                     │
│  1. Encrypt payload │  ──────►  │  3. Store encrypted │
│     with local key  │  (TLS)   │     payload as-is   │
│                     │           │                     │
│  4. Request changes │  ◄────── │  2. Return encrypted │
│  5. Decrypt payload │  (TLS)   │     payloads         │
│     with local key  │           │                     │
└─────────────────────┘           └─────────────────────┘

The encryption key never leaves the local instance. The remote instance stores and serves encrypted payloads without ever decrypting them.

Key Sources

SourceConfigurationSecurity LevelWhere Supported
Environment variableMNEMOSYNE_SYNC_KEY=<base64-key>Medium (env may be logged)Core, Hermes adapter
File path--encrypt /path/to/keyfileMedium (file perms)CLI, Hermes adapter
Raw key string--encrypt <base64-key>Low (visible in ps)CLI, Hermes adapter
OS keyringMNEMOSYNE_SYNC_KEY_SOURCE=keyringHigh (OS keychain)Hermes adapter only
Derived from passphraseMNEMOSYNE_SYNC_PASSPHRASE=<phrase>Medium (Argon2id derived)Hermes adapter only

Core SyncEncryption.from_config() reads from $MNEMOSYNE_SYNC_KEY, a file path, or a raw key string. The Hermes sync adapter adds keyring and passphrase support.

Key Derivation

SyncEncryption.derive_key() converts a passphrase to a 32-byte key:

  • Default: PBKDF2-HMAC-SHA256 with 600,000 iterations
  • If argon2-cffi is installed: Argon2id (memory-hard, recommended)

Note: from_config() does not currently call derive_key() — passphrases require the Hermes sync adapter or manual key derivation.

# Generate a random key
mnemosyne sync generate-key
# Output: 7A8B3C... (base64, 32 bytes)

# Use with CLI
mnemosyne sync --encrypt MNEMOSYNE_SYNC_KEY=7A8B3C...
mnemosyne sync --encrypt /path/to/keyfile

# Enable in Hermes (config.yaml)
mnemosyne:
  sync:
    key: "7A8B3C..."
    encrypt: true

What Gets Encrypted

The payload field of each sync event is encrypted. Payload includes:

  • Memory content text
  • importance score
  • source field
  • metadata_json (if present)
  • memory_type / veracity fields
  • Vector embeddings (binary_vector)

What Stays Unencrypted (Metadata)

These fields are always sent in plaintext for routing and conflict resolution:

  • event_id — Unique event identifier (UUID)
  • memory_id — References the memory row
  • operation — CREATE / UPDATE / DELETE / CONSOLIDATE
  • timestamp — ISO 8601 timestamp
  • device_id — Which device originated the event
  • parent_event_ids — Causality chain for conflict detection

This means an adversary with access to the remote sync server can learn:

  • How many memory events are being synced
  • When they occurred
  • Which events are related to each other
  • Which devices are syncing

They cannot learn the content or meaning of those memories when encryption is enabled.


Liability & Disclaimer

Mnemosyne is provided "as is", without warranty of any kind.

You are solely responsible for:

  • The content you store in Mnemosyne
  • Securing your database file (file permissions, disk encryption)
  • Securing your sync channel (TLS certificates, network configuration)
  • Managing your encryption keys (key rotation, backup, loss prevention)
  • Compliance with applicable laws regarding data storage and transfer

Mnemosyne Sync supports optional client-side encryption. When disabled, memory content travels over TLS and is stored according to your infrastructure's security settings. Even with encryption enabled, metadata (event counts, timestamps, device IDs) is visible to the remote server for routing purposes.

See the LICENSE file for the full terms.


Comparison with Alternatives

SystemData at RestData in TransitClient-Side EncryptionSelf-Hostable
MnemosyneLocal SQLite (file permissions)TLS + optional client-side encryptionYes (sync, Fernet/XSalsa20-Poly1305)Yes
Mem0Qdrant/PostgreSQLTLSNoOptional
ZepBYOK (data at rest)TLSBYOK only (server-managed)Yes
LettaPostgreSQLTLSNoYes
HonchoPostgreSQLTLSNoYes
SupermemoryCloud (SaaS)TLSNoEnterprise only
HindsightLocal SQLiteTLSNoYes

Mnemosyne is the only memory system with client-side encryption of sync payloads as a core feature, not an afterthought. Zep offers BYOK for data-at-rest but manages the key server-side — Mnemosyne keeps the key entirely client-side.


Threat Model

In Scope

ThreatMitigation
Remote server compromise → memory content exposureClient-side encryption renders payloads unreadable
TLS interception (MITM)TLS with certificate validation
Unauthorized sync accessAPI key / JWT authentication on sync endpoints
Replay attacksUnique event IDs + timestamp validation
Sync of malicious contentDestination-side content filtering via ignore_patterns

Out of Scope (v1)

ThreatRationale
Side-channel attacks on encryption timingPerformance-sensitive sync makes constant-time hard. Use TLS for transit security.
Quantum cryptanalysis of Fernet/SecretBoxNot a practical threat for memory content. Key rotation mitigates long-term risk.
Physical access to the database fileOS-level controls (file permissions, disk encryption) are the user's responsibility
Denial of service on sync endpointSelf-hosted deployments manage their own rate limiting and firewall rules

Best Practices

  1. Always use HTTPS/TLS for sync connections. Never sync over plain HTTP outside a local network.
  2. Enable client-side encryption if syncing over the internet or to a shared/VPS instance.
  3. Rotate sync keys periodically (e.g., every 90 days).
  4. Back up your encryption keys separately from your Mnemosyne database. Losing the key means losing access to encrypted memories.
  5. Use environment-specific keys — separate keys for development, staging, and production.
  6. Monitor sync events with mnemosyne sync status --remote <url> to verify no unexpected sync activity.