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.
Seguridad
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
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.
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.
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
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.
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.
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.
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.
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.
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
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.
Detalles más profundos
Lista completa de servicios de terceros que procesan tus datos: Hetzner (hosting), Stripe (facturación), Resend (email), Anthropic (AI, DRAFT), GoCardless (PSD2), Monobank API, FCM.
Abrir listaMatriz per-feature: qué se almacena, cuánto tiempo, cómo se elimina. Flujo GDPR Art. 15/17/20 y ventanas de retención por entidad.
Abrir matrizPreguntas frecuentes sobre seguridad
Los servidores están en el centro de datos de Hetzner en Frankfurt, Alemania (UE). El controlador de datos es el propietario de MyFina — sin intermediarios agregadores, sin proveedores de nube de EE.UU. La lista completa de subprocesadores está en /security/subprocessors.
Al menos 30 días antes te enviaremos un correo con notificación y un botón "Descargar todo" en formatos CSV / XLSX / PDF. Después del período de gracia la base de datos se destruye. Es un compromiso operativo en nuestros Términos, no una promesa de marketing.
Sí. Configuración → Datos → Eliminar cuenta es un hard-delete en una sola transacción de DB: transacciones, cuentas, categorías, tokens y leads de marketing vinculados al mismo correo se borran en cascada. Sin soft-delete, sin archivos "por si acaso". Totalmente conforme con RGPD art. 17.
Nadie del "personal" tiene acceso rutinario a tus datos financieros. El propietario solo puede acceder a la base de datos durante un incidente de seguridad o con tu solicitud explícita a través de soporte. Todas las acciones de administración se registran en audit_log con IP y user-agent.
Las sesiones del navegador son JWTs con TTL, no "conectado para siempre". Si tu navegador actual está desconectado, nadie puede iniciar sesión sin la contraseña. Con sesión activa — usa lock-screen del SO y/o cambia la contraseña desde otro dispositivo (esto invalida instantáneamente todas las sesiones activas).
No. No ejecutamos ni un solo script de analítica en las páginas de usuario. El banner de cookies muestra solo dos categorías — essential (sesión NextAuth) y functional (enlaces de referidos). Sin categoría analytics, porque no hay nada que analizar.
Lo que puedes verificar tú mismo
Cada afirmación de arriba es auditable vía código y API.
src/lib/crypto.ts (AES-256-GCM, randomBytes IV, auth tag).src/auth.ts, src/lib/auth/rate-limit.ts.src/lib/auth/ownership.ts (assertCanAccessAccount).https://app.my-fina.com/api/openapi (OpenAPI 3.1).https://app.my-fina.com/api/health (liveness público).Suscríbete para enterarte de CVEs, parches de seguridad y cambios en el modelo de amenazas. Sin marketing.