File size: 1,412 Bytes
45dc2a1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
"""
Prototype-only stand-in for ADR-0002's GCP KMS envelope encryption. No GCP project is
provisioned yet (see docs/blueprint/blueprint.md), so mailbox credentials and contact PII
are encrypted at rest here using a single symmetric Fernet key from CREDENTIAL_ENCRYPTION_KEY
(.env) instead of KMS-wrapped per-record data keys.

This is a real, working encryption layer — not a no-op — but it is NOT the security posture
ADR-0002 commits to for production: one key, no envelope, no separate audit-logged access
control. Every function here is the seam that gets replaced (same call signatures) once a
GCP project with KMS exists.
"""

from __future__ import annotations

import os

from cryptography.fernet import Fernet

_key = os.getenv("CREDENTIAL_ENCRYPTION_KEY")
if not _key:
    # Auto-generated per-process when unset, matching the prior build's local-dev fallback.
    # Encrypted values won't survive a process restart with a fresh key — fine for tests
    # and throwaway local runs, NOT fine for anything meant to persist. Set
    # CREDENTIAL_ENCRYPTION_KEY in .env for a stable local key across restarts.
    _key = Fernet.generate_key().decode()

_fernet = Fernet(_key.encode() if isinstance(_key, str) else _key)


def encrypt(plaintext: str) -> str:
    return _fernet.encrypt(plaintext.encode()).decode()


def decrypt(token: str) -> str:
    return _fernet.decrypt(token.encode()).decode()