Security
Last updated: 2026-05-26
Infrastructure
Application servers run on Hetzner Cloud in Nürnberg, Germany. Database (Postgres 17 with pgvector) and cache (Redis 7) run as Docker containers on the same VPS, behind a firewall that exposes only the public application port (443). Email send and inbound receive go through AWS SES in eu-central-1; persistent storage (logos, backups) uses S3 in the same region.
Data at rest
Postgres data is stored on encrypted block storage at the Hetzner volume level. S3 buckets are encrypted with AES-256 server-side encryption. Passwords are stored as bcrypt hashes (cost factor 12). Database backups are encrypted with the same SSE-S3 scheme and gated by IAM.
Data in transit
All public traffic terminates HTTPS at nginx with TLS 1.2+ (1.3 preferred), certificates auto-renewed via Let's Encrypt. Internal service-to-service traffic (backend ↔ database ↔ Redis) runs over the Docker bridge network and is not exposed publicly. Outbound API calls to subprocessors (OpenAI, Vapi, Twilio, SES) use TLS-pinned HTTP clients.
Access control
Application access requires a JWT issued via password authentication. JWT secrets and database passwords are stored in a server-side .env file readable only by the application user. AWS access uses long-lived IAM keys scoped to the minimum required permissions per service (separate keys for SES vs S3 vs backups). Admin actions are logged in an immutable audit table. Impersonation tokens are short-lived (15 min) and audit-logged.
Backups
Postgres is backed up to S3 every 4 hours via `pg_dump --format=custom --compress=9`. Backups are versioned, encrypted, and lifecycle-managed (Hot → IA → Glacier → 400-day expire). The bucket policy blocks bucket-level deletion. Restore is documented and rehearsed monthly. See BACKUP.md in the repo for the full runbook. Redis runs with AOF persistence (everysec fsync).
Incident response
Sentry captures errors with PII scrubbing applied client-side. On a security incident affecting personal data, we notify affected Controllers without undue delay (target: within 72 hours, per GDPR Art. 33), with a summary of scope, impact, and remediation. Coordination email: security@prezio.app.
Compliance
We operate under GDPR (Germany / EU). We are not currently SOC 2 / ISO 27001 certified — formal certifications are on the roadmap once team size and revenue justify the audit cost. We commit to applying SOC-2-aligned controls (access management, change management, encryption, logging, backup, vendor management) even without the formal certification.
Responsible disclosure
Found a vulnerability? Email security@prezio.app with reproduction steps. We commit to acknowledging within 48 hours and patching critical issues within 7 days. We do not currently run a paid bug-bounty programme but we publicly acknowledge contributors in our changelog with their consent.