Skip to content

Encryption

All sensitive fields in the database are encrypted using Fernet (AES-128-CBC with HMAC-SHA256 authentication).

FieldDescription
signing_secret_currentActive webhook signing secret
signing_secret_previousPrevious signing secret (for rotation)
delivery_secretSecret for signing outbound deliveries
project_delivery_secretProject-level fallback delivery secret
  • Algorithm: Fernet (symmetric encryption)
  • Cipher: AES-128-CBC
  • Authentication: HMAC-SHA256
  • Key: 32-byte base64-encoded key from the ENCRYPTION_KEY environment variable

Fernet provides authenticated encryption, meaning any tampering with the ciphertext is detected and rejected on decryption.

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()

Generate a new encryption key:

Terminal window
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Set it as the ENCRYPTION_KEY environment variable.

  • All endpoints are served over TLS (HTTPS only)
  • Outbound delivery requests use HTTPS
  • Database connections use TLS where supported

The Admin API token (X-Admin-Token) is compared using hmac.compare_digest(), which provides constant-time comparison to prevent timing attacks.