← Back home

Security

Last updated: 2026-05-24

How we protect your account, your data, and your customers' email addresses.

TL;DR

  • Passwords hashed with bcrypt. API keys stored as SHA-256 hashes — we never see plaintext after the moment of issue.
  • Optional TOTP-based 2FA on every account. Session revocation across all devices in one click.
  • Email addresses you verify are stored as SHA-256 hashes only — plaintext lives in memory for the duration of the request, then is gone.
  • Webhook URLs are validated against SSRF (loopback / private / metadata IPs blocked).
  • Webhook payloads signed with HMAC-SHA256. Paddle webhooks signature-verified.
  • Login brute-force gated atomically per IP. Per-key rate limits.
  • Full audit trail for every admin action.

Authentication

  • Passwords: bcrypt with cost factor 10. We enforce 8+ character minimum.
  • API keys: 256-bit random, prefix tm_. Stored as SHA-256 hash — we cannot recover them, only revoke and reissue.
  • 2FA: TOTP via any RFC-6238 authenticator (Authy, 1Password, Google Authenticator). Required code on every sign-in once enabled.
  • Sessions: JWT with embedded token-version. "Sign out everywhere" bumps the version and invalidates every outstanding session instantly.
  • Constant-time login: bcrypt runs even for unknown email addresses so attackers can't enumerate accounts by timing.
  • Brute-force gate: 5 failed attempts per IP per 15 min returns 429 with Retry-After.

Data at rest & in transit

  • In transit: TLS 1.2+ on every public endpoint with HSTS (2-year max-age, preload).
  • At rest: Postgres database encrypted by the hosting provider.
  • Verifications: SHA-256 hash + domain + verdict. The plaintext email is not written to the database, log files, or cache.
  • Password reset tokens: stored as SHA-256 hash; a DB-snapshot leak can't be used to reset accounts.
  • Backups: daily encrypted snapshots, 30-day retention.

Infrastructure

  • Stateless Go API behind a reverse proxy with TLS termination.
  • NATS for async job queueing; not exposed to the public internet.
  • Redis for caches and rate-limit counters; private network only.
  • Postgres for durable state; private network only, no public port.
  • Webhook delivery refuses HTTP redirects and re-validates the target host before each delivery (defends against DNS rebinding).
  • Content-Security-Policy, X-Frame-Options DENY, X-Content-Type-Options nosniff, Referrer-Policy strict-origin, Permissions-Policy locked down.

Operational security

  • All admin actions are logged to an immutable audit trail (actor, action, target, timestamp).
  • Production access uses unique per-engineer credentials, MFA required.
  • SSH keys, not passwords. No shared accounts.
  • Dependency updates via Dependabot, security advisories reviewed weekly.
  • Worker logs scrub email addresses to f***@domain form — no full PII at INFO level.

Incident response

We'll notify affected customers within 72 hours of becoming aware of a personal data breach, with the facts available and our mitigation. See the DPA for the contractual commitment.

Responsible disclosure

Found a vulnerability? Please don't post it publicly. Email security@trumailo.com with a description and reproduction steps. We'll acknowledge within 48 hours and credit you (if you want) once a fix is shipped. We don't prosecute good-faith security research that follows this process.

Compliance roadmap

  • GDPR & UK GDPR: covered by our DPA and privacy policy.
  • CCPA: covered by our privacy policy.
  • SOC 2 Type II: on the roadmap, targeted for the post-beta milestone.
  • ISO 27001: on the roadmap, after SOC 2.

Questions about this policy? Email legal@trumailo.com or use the contact form.