Encryption
Encryption at Rest
Section titled “Encryption at Rest”All sensitive fields in the database are encrypted using Fernet (AES-128-CBC with HMAC-SHA256 authentication).
Encrypted Fields
Section titled “Encrypted Fields”| Field | Description |
|---|---|
signing_secret_current | Active webhook signing secret |
signing_secret_previous | Previous signing secret (for rotation) |
delivery_secret | Secret for signing outbound deliveries |
project_delivery_secret | Project-level fallback delivery secret |
Encryption Scheme
Section titled “Encryption Scheme”- Algorithm: Fernet (symmetric encryption)
- Cipher: AES-128-CBC
- Authentication: HMAC-SHA256
- Key: 32-byte base64-encoded key from the
ENCRYPTION_KEYenvironment variable
Fernet provides authenticated encryption, meaning any tampering with the ciphertext is detected and rejected on decryption.
Implementation
Section titled “Implementation”Transyt uses a custom SQLAlchemy EncryptedText column type that transparently encrypts on write and decrypts on read:
class EncryptedText(TypeDecorator): def process_bind_param(self, value, dialect): # Encrypt before storing return fernet.encrypt(value.encode()).decode()
def process_result_value(self, value, dialect): # Decrypt when loading return fernet.decrypt(value.encode()).decode()Key Generation
Section titled “Key Generation”Generate a new encryption key:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"Set it as the ENCRYPTION_KEY environment variable.
Encryption in Transit
Section titled “Encryption in Transit”- All endpoints are served over TLS (HTTPS only)
- Outbound delivery requests use HTTPS
- Database connections use TLS where supported
Token Security
Section titled “Token Security”The Admin API token (X-Admin-Token) is compared using hmac.compare_digest(), which provides constant-time comparison to prevent timing attacks.