Encryption
AES-256-GCM file encryption at rest, TLS 1.3 for all traffic, HMAC-signed session cookies, and field-level encryption for sensitive PII.
invoice.pdf
plaintext
AES-256
GCM mode
a3f9c2...
ciphertext
AES-256-GCM file encryption at rest.
Every file uploaded to Cronos — images, documents, invoices, exports — is encrypted with AES-256-GCM before being written to S3/MinIO storage. The encryption key lives in the application layer, never in the storage backend. Even with direct access to the storage bucket, files are ciphertext on disk.
Browser
Cronos
TLS 1.3 for all traffic, no exceptions.
Every API call, web request, and webhook delivery uses TLS 1.3. HSTS is enforced with a one-year max-age directive. Plaintext fallback is disabled — no HTTP port listens, no downgrade is possible. Stripe, MercadoPago, and all third-party webhooks are verified against their TLS certificates.
Valid sig
→ load session
Bad sig
→ reject, no DB
Timing-safe comparison · no side-channel
HMAC-signed session cookies.
Session cookies are signed with HMAC-SHA256 using a server-side secret. Verification uses timing-safe comparison to prevent side-channel attacks. If a cookie is tampered with, it is rejected before any database query runs — forged sessions never reach the application layer.
Database row preview
Field-level encryption for PII.
Sensitive fields — tax identification numbers, IBANs, customer addresses — are encrypted at the column level, not just at the file system level. Even with direct database access, PII is unreadable without the application encryption key. Non-sensitive fields like business names remain in plaintext for query performance.
Frequently asked questions
What encryption algorithm is used for files at rest?
AES-256-GCM (Galois/Counter Mode). GCM provides both confidentiality and authenticity — it detects tampering, not just encryption. Every file is encrypted with a unique IV before being written to S3/MinIO. The encryption key is held in the application layer and never sent to the storage backend.
Why TLS 1.3 and not TLS 1.2?
TLS 1.3 removes legacy cryptographic algorithms, requires fewer round-trips for the handshake (1-RTT vs 2-RTT), and mandates forward secrecy. It is the current standard for transport encryption. Cronos disables TLS 1.2 and all earlier protocols. HSTS ensures browsers never attempt an unencrypted connection.
How do signed session cookies work?
The session cookie contains the user ID and session metadata, signed with HMAC-SHA256 using a server secret. On every request, the signature is verified using timing-safe comparison before any database query. If the signature does not match — meaning the cookie was modified — the request is rejected immediately as unauthenticated.
What is field-level encryption and why does it matter?
Field-level encryption encrypts specific sensitive columns (tax IDs, IBANs, addresses) within the database, independent of disk-level encryption. This means that even someone with direct SQL access to the database cannot read PII without the application-layer encryption key. It provides defense in depth beyond transport and storage encryption.
Which fields are encrypted at the column level?
Tax identification numbers (VAT IDs, TINs), IBANs and bank account numbers, and customer addresses. These are the fields most likely to be targeted in a breach. Non-sensitive fields like business names and product titles remain in plaintext to allow efficient database queries and full-text search.
Is the encryption key stored on the same server as the data?
The encryption key is held in the application layer via environment variables and is never written to the database or storage backend. In production on Railway, the key is injected at runtime from Railway secrets and is not accessible to the storage or database services. This separation means a storage breach alone does not expose decrypted data.