Jun 26 MT-0 phase
This commit is contained in:
@@ -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()
|
||||
Reference in New Issue
Block a user