"""Encrypt/decrypt platform API credentials at rest (R-174).""" from __future__ import annotations import base64 import hashlib from cryptography.fernet import Fernet from app.config import get_settings def _fernet() -> Fernet: """Derive a stable Fernet key from application SECRET_KEY.""" digest = hashlib.sha256(get_settings().SECRET_KEY.encode("utf-8")).digest() return Fernet(base64.urlsafe_b64encode(digest)) def encrypt_secret(value: str) -> str: """Encrypt a secret for database storage.""" return _fernet().encrypt(value.encode("utf-8")).decode("utf-8") def decrypt_secret(token: str) -> str: """Decrypt a stored secret.""" return _fernet().decrypt(token.encode("utf-8")).decode("utf-8") def mask_secret(value: str) -> str: """Return a display-safe hint (R-175).""" if len(value) <= 4: return "••••" return f"••••{value[-4:]}"