Seguridad

Seguridad, sin rodeos

MyFina es una contabilidad doméstica. Los datos financieros son especiales — aquí te contamos cómo los protegemos, sin paja de marketing.

Tres respuestas breves a las grandes preguntas

Cómo se cifra

TLS 1.3 en tránsito (Let's Encrypt). Claves de API externas, tokens bancarios y secretos de brokers — AES-256-GCM con un IV único por registro. Contraseñas — bcrypt (12 rondas). La clave de cifrado vive en env, no en la base de datos.

Dónde se almacena

PostgreSQL 16 en una instancia gestionada en Hetzner (Alemania, UE). Red Docker aislada, sin conexiones externas a la BD. Copias de seguridad — diarias, cifradas antes de subirlas, retención de 30 días.

Cómo se elimina

Hard-delete de la cuenta en un solo paso: se eliminan en cascada transacciones, cuentas, categorías, divisas, tokens. Sin tablas soft-delete, sin archivo «por si acaso». Leads de marketing bajo el mismo email — erase-hook independiente (GDPR Art. 17).

Seis pilares de defensa

Autenticación

NextAuth.js v5 sobre JWT, contraseñas con hash bcrypt. Throttling de login — 5 intentos / 15 min por identificador y 20 / 15 min por IP. OAuth de Google opcional. Reset de contraseña con un token de 32 bytes; solo se guarda su SHA-256.

Cifrado «at rest»

Las claves de API externas (bancos, Resend, Anthropic) y los secretos de brokers se cifran con AES-256-GCM. La clave nunca abandona el servidor. Cada conexión bancaria lleva su propio secreto de webhook hex de 32 bytes.

Aislamiento de datos del usuario

Cada operación UPDATE/DELETE filtra por `userId`. La protección IDOR está centralizada en `assertCanAccessAccount/Category` — el acceso a la cuenta de otro devuelve 403, no 404. Las cuentas familiares compartidas usan roles explícitos OWNER/MEMBER/VIEWER.

Sesiones y revocation

JWT con un `session_version` que se incrementa. Cambio de contraseña, bloqueo de cuenta o cambio de rol invalidan todas las sesiones activas. Los refresh tokens de la API móvil rotan en cada refresh.

GDPR y privacidad

El hard-delete de la cuenta elimina todas las transacciones, cuentas y categorías en cascada en una sola transacción. Exportación de datos — CSV/XLSX/PDF con un clic. Cookie consent con dos categorías (essential / functional), sin analítica ni trackers.

Auditoría y observabilidad

Todas las acciones de admin y operaciones sensibles del usuario se escriben en `audit_log` con IP, user-agent y source. Los logs de intentos de login se guardan 30 días. Los eventos de webhook de Stripe se sientan en un journal de idempotency dedicado para replay seguro en caso de fallo.

Lo que NO hacemos

  • No vendemos ni compartimos tus datos con terceros. Nuestra fuente de ingresos es la suscripción Pro, no la publicidad.
  • No ejecutamos analítica web ni trackers en las páginas de usuario — sin Google Analytics, Mixpanel, Hotjar.
  • No guardamos contraseñas en texto plano — bcrypt con 12 rondas, sin backdoor-recovery.
  • No incrustamos tu saldo ni transacciones en webs de partners — sin widget, nada que filtrar.

Sincronización bancaria — qué se comparte exactamente

Si conectas Monobank o un banco PSD2 a través de GoCardless, solo recibimos lo necesario para sincronizar transacciones: pagos salientes, transferencias entrantes, saldos de cuentas. Ningún dato personal del lado del banco (pasaporte, foto, biometría). El token de API del banco se guarda cifrado con AES-256-GCM; puedes revocar el acceso con un clic desde Ajustes → Bancos. El consentimiento de GoCardless caduca cada 90 días según PSD2 — te recordamos con 7 días de antelación.

Lo que puedes verificar tú mismo

Cada afirmación de arriba es auditable vía código y API.

  • Cifrado: src/lib/crypto.ts (AES-256-GCM, randomBytes IV, auth tag).
  • Autenticación: src/auth.ts, src/lib/auth/rate-limit.ts.
  • Autorización: src/lib/auth/ownership.ts (assertCanAccessAccount).
  • API abierta: https://app.my-fina.com/api/openapi (OpenAPI 3.1).
  • Health endpoint: https://app.my-fina.com/api/health (liveness público).

Recibir avisos de seguridad

Suscríbete para enterarte de CVEs, parches de seguridad y cambios en el modelo de amenazas. Sin marketing.

Avisarme cuando Pro esté disponible

Un email. Sin spam. Cancelación en un clic.

Conforme con GDPR · datos procesados en la UEÚltima actualización: 3 de junio de 2026