Security

Essential security practices for self-hosted Memori deployments.

API Keys

import os
from openai import OpenAI

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

For production, use AWS Secrets Manager, Google Cloud Secret Manager, Azure Key Vault, or HashiCorp Vault.

Database Credentials

Same rule — store connection strings in environment variables, not code:

import os
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine(os.getenv("DATABASE_URL"), pool_pre_ping=True)
SessionLocal = sessionmaker(bind=engine)

Entity Isolation

Memori uses entity_id to isolate memories between users. Facts stored for user_123 are never returned when recalling for user_456.

def handle_request(authenticated_user_id: str, message: str):
    mem.attribution(entity_id=authenticated_user_id, process_id="my_app")
    # memories are now scoped to this user

Encryption in Transit

Always use SSL for production database connections:

# PostgreSQL
engine = create_engine("postgresql+psycopg://user:pass@host/db?sslmode=verify-full&sslrootcert=/path/to/ca.pem")

# MySQL
engine = create_engine("mysql+pymysql://user:pass@host/db?ssl_ca=/path/to/ca.pem")

For encryption at rest, use your database's built-in encryption (PostgreSQL TDE, InnoDB encryption, SQLCipher for SQLite) or encrypted volumes.

.gitignore Essentials

.env
*.db
*.sqlite3
*.pem
*.key
__pycache__/
.venv/

Common Mistakes

MistakeFix
Hardcoded API keysUse os.getenv()
.env committed to gitAdd to .gitignore
Admin database userCreate a dedicated Memori user
Unvalidated entity_idValidate against authenticated user
No SSL on databaseEnable sslmode=verify-full
SQLite in productionUse PostgreSQL