EncryptedSessionStore wraps any session store so message content and metadata are encrypted before they reach disk — keys stay in PRAISONAI_SESSION_KEY, plaintext never lands on the filesystem.
Quick Start
1
Enable in three lines
2
Generate a key
Encrypting sessions needs the
cryptography package (not a hard dependency of PraisonAI). Install it with pip install cryptography. If it is missing when the wrapper is instantiated, a SessionEncryptionError is raised with the exact install command.How It Works
The wrapper encrypts content on the way in and decrypts it on the way out — the inner store only ever sees ciphertext.What is encrypted / not encrypted
Configuration Options
The wrapper takes the inner store and a Fernet key. Everything else is inherited from whatever store you wrap.Errors and Honest Limits
These conditions are designed in, not accidental — each fails loudly rather than silently.search() raises instead of returning []. Stored content is ciphertext, so substring matching cannot work. An empty list would be indistinguishable from a genuine miss — the more dangerous answer. Callers should get_chat_history() and filter in memory, or use an unencrypted store when search matters more than confidentiality.
Wrong key raises SessionEncryptionError rather than yielding gibberish:
“the key does not match the one it was written with. Session transcripts are unrecoverable without their original key.”Empty or malformed key is refused at construction time — fails fast rather than at first use. Losing the key loses the transcripts. By design — no recovery path.
Enabling encryption on an existing store does not break history
Switching encryption on leaves earlier plaintext rows readable — they are recognised and returned untouched.- Rows written before encryption was switched on lack the
praisonai:enc:v1:prefix and are returned as-is — not fed to the decrypter, not reported as corrupt. - Legacy metadata containing an
__enc__key as regular data (not our envelope) is preserved intact — the wrapper recognises only the exact one-key envelope shape with the crypto prefix. - Unwrapped methods are forwarded via
__getattr__, so wrapping cannot silently drop capabilities the inner store has.
Common Patterns
Opt-in via environment
LeavingPRAISONAI_SESSION_KEY unset yields the plain store, so existing deployments are unaffected until they set the env var.
Filter in memory instead of search()
Best Practices
Keep the key out of source and out of the container image
Keep the key out of source and out of the container image
Load from
PRAISONAI_SESSION_KEY or a secrets manager — never commit a Fernet key.Rotate carefully
Rotate carefully
There is no automatic re-encryption path. Rotating requires re-writing existing sessions with the new key (out of scope for this wrapper).
Filter in memory instead of using search()
Filter in memory instead of using search()
When you need to find something in an encrypted session,
get_chat_history() + Python filtering is the supported path.Choose a different design if session ids must also be confidential
Choose a different design if session ids must also be confidential
Ids, roles, and timestamps stay readable — the store indexes on them.
Related
Session Store
Default JSON, SQLite, hierarchical backends
Session Persistence
Automatic persistence via session_id
SQLite Transcript Store
Gateway-default transcript backend that can also be wrapped
Security Environment Variables
Where PRAISONAI_SESSION_KEY fits

