v0.20.0: at-rest encryption (AES-256-GCM) for all query-derived text
- crypto.py: AES-256-GCM encrypt/decrypt + ensure_key() - Key auto-generated on first boot, stored as heartbeat_interval_ms in settings - All 12 storage paths wired (SQLite + Qdrant) - memory.py: FTS5 search replaced with Python-side matching - 200/200 tests pass
This commit is contained in:
@@ -15,6 +15,7 @@ from config import (
|
||||
BUILTIN_SKILLS, DEFAULT_MODEL, DEFAULT_PRESETS, DEFAULT_PROFILE,
|
||||
MAX_SKILL_PROMPT_CHARS, ALLOWED_NETWORKS,
|
||||
)
|
||||
from crypto import encrypt_text, decrypt_text
|
||||
|
||||
log = logging.getLogger("caic")
|
||||
|
||||
@@ -72,7 +73,7 @@ def insert_upload_context(db, conversation_id: str, filename: str, content: str,
|
||||
now = datetime.now(timezone.utc).isoformat()
|
||||
cur = db.execute(
|
||||
"INSERT INTO upload_context (conversation_id, filename, content, content_type, created_at, expires_at) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
(conversation_id, filename, content, content_type, now, expires_at),
|
||||
(conversation_id, filename, encrypt_text(content), content_type, now, expires_at),
|
||||
)
|
||||
return cur.lastrowid
|
||||
|
||||
@@ -102,7 +103,9 @@ def get_upload_context(db, context_id: int):
|
||||
db.execute("DELETE FROM upload_context WHERE id = ?", (context_id,))
|
||||
db.commit()
|
||||
return None
|
||||
return dict(row)
|
||||
d = dict(row)
|
||||
d["content"] = decrypt_text(d["content"])
|
||||
return d
|
||||
|
||||
|
||||
def init_db():
|
||||
|
||||
Reference in New Issue
Block a user