Jun 26 MT-0 phase

This commit is contained in:
2026-06-26 16:19:48 -04:00
parent 5d95cdbbfc
commit fc39491891
13 changed files with 1094 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
"""
control/crypto.py
-----------------
Symmetric encryption for sensitive control-plane fields (tenant DB passwords).
Fernet (AES-128-CBC + HMAC) keyed by the CONTROL_FERNET_KEY env var.
Generate a key once:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
Store it in the server environment / .env (never in git). Key rotation requires
re-encrypting existing tenant rows.
"""
import os
from cryptography.fernet import Fernet
def _fernet() -> Fernet:
key = os.environ.get('CONTROL_FERNET_KEY')
if not key:
raise RuntimeError(
"CONTROL_FERNET_KEY is not set. Generate one with: "
"python -c \"from cryptography.fernet import Fernet; "
"print(Fernet.generate_key().decode())\""
)
return Fernet(key.encode() if isinstance(key, str) else key)
def encrypt(plaintext):
"""Encrypt a string to a Fernet token (str). Passes None through."""
if plaintext is None:
return None
return _fernet().encrypt(plaintext.encode()).decode()
def decrypt(token):
"""Decrypt a Fernet token back to the original string. Passes None through."""
if token is None:
return None
return _fernet().decrypt(token.encode()).decode()