Rotación de secrets (API keys, tokens y credenciales)

Este documento describe cuándo y cómo rotar los secrets del proyecto UnoSportClub (API keys, tokens y credenciales) para mantener la seguridad del sistema.

Cuándo rotar

Rotar secrets en los siguientes casos:

  • Rotación periódica: Según política de seguridad (por ejemplo cada 90 días para API keys y cada 12 meses para credenciales de base de datos, o según normativa aplicable).

  • Sospecha o confirmación de compromiso: Si un secret pudo haber sido expuesto (log, repositorio, captura de pantalla, dispositivo perdido).

  • Salida de personal o sistemas: Cuando un empleado, integrador o sistema externo deja de tener acceso; rotar cualquier secret que haya podido conocer o usar.

  • Cambio de proveedor o entorno: Al migrar SMTP, base de datos, Firebase u otro servicio; generar nuevos valores y dejar de usar los antiguos.

  • Cumplimiento o auditoría: Cuando una política interna o un estándar (p. ej. PCI-DSS, ISO 27001) exija rotación en un plazo determinado.

Secrets del proyecto

El backend (API en functions) utiliza los siguientes tipos de secrets. Las variables se configuran en el entorno (por ejemplo functions/.env o variables de entorno del host/Cloud Functions).

Variable / Origen

Uso

Dónde se usa

BOT_API_KEYS

Autenticación de bots e integraciones (header X-Auth)

server.js, rutas /admin, /account, /trainer, /sudo

XSRF_SECRET

Secret HMAC para tokens CSRF/XSRF

middleware/xsrf.js

FIREBASE_ADMIN_SDK_JSON o GOOGLE_APPLICATION_CREDENTIALS

Credenciales Firebase Admin (verificación de tokens, Auth)

server.js, seeders, user-sync

DATABASE_URL o DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD

Conexión a PostgreSQL

db/index.js, reset_and_migrate.js, rutas

SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_FROM_*

Envío de correo (reportes, notificaciones)

routes/admin/reports.js

SENDGRID_API_KEY, SENDGRID_FROM_EMAIL

Alternativa para envío de correo (SendGrid)

routes/admin/clients.js

PUSHER_APP_ID, PUSHER_KEY, PUSHER_SECRET, PUSHER_CLUSTER

Notificaciones en tiempo real (Pusher)

Si está integrado en el backend

Cómo rotar cada secret

BOT_API_KEYS (API key para bots)

  • Dónde se define: Variable de entorno BOT_API_KEYS. Puede contener varias claves separadas por coma.

  • Pasos:

    1. Generar una nueva clave (por ejemplo 64 caracteres hex: openssl rand -hex 32).

    2. Añadir la nueva clave a BOT_API_KEYS manteniendo la antigua: BOT_API_KEYS=clave_vieja,clave_nueva.

    3. Desplegar o reiniciar el backend para que cargue el nuevo valor.

    4. Actualizar todos los clientes que usan X-Auth (n8n, scripts, integraciones) para que usen clave_nueva.

    5. Verificar que las integraciones responden correctamente con la nueva clave.

    6. Eliminar clave_vieja de BOT_API_KEYS, desplegar de nuevo.

  • Impacto: Los clientes que sigan usando la clave antigua recibirán 401 hasta que actualicen.

XSRF_SECRET

  • Dónde se define: Variable de entorno XSRF_SECRET. Si no existe, el código usa un valor por defecto (no recomendado en producción).

  • Pasos:

    1. Generar un nuevo secret (por ejemplo openssl rand -hex 32).

    2. Actualizar XSRF_SECRET en el entorno del servidor.

    3. Reiniciar/desplegar el backend.

  • Impacto: Las sesiones activas (cookies XSRF-TOKEN) quedarán invalidadas; los usuarios tendrán que recargar la aplicación o volver a iniciar sesión para obtener un nuevo token.

Credenciales de Firebase Admin

  • Dónde se definen: FIREBASE_ADMIN_SDK_JSON (JSON completo de la cuenta de servicio) o archivo apuntado por GOOGLE_APPLICATION_CREDENTIALS.

  • Pasos:

    1. En Firebase Console: Proyecto → Configuración del proyecto → Cuentas de servicio.

    2. Generar una nueva clave privada para la cuenta de servicio existente, o crear una nueva cuenta de servicio y descargar su clave.

    3. Sustituir el contenido de FIREBASE_ADMIN_SDK_JSON o el archivo de credenciales por el nuevo JSON.

    4. Desplegar/reiniciar el backend.

    5. (Opcional) Revocar o eliminar la clave antigua en Firebase para que deje de ser válida.

  • Impacto: Hasta que el backend use el nuevo JSON, la verificación de tokens de Firebase podría fallar si se revocó la clave anterior.

Base de datos (DATABASE_URL o DB_*)

  • Dónde se definen: DATABASE_URL o DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD (y DB_SSL si aplica).

  • Pasos (cambio de contraseña en PostgreSQL):

    1. En el servidor de base de datos, cambiar la contraseña del usuario (por ejemplo con ALTER USER unosport_admin PASSWORD 'nueva_contrasena';).

    2. Actualizar DB_PASSWORD o la parte de contraseña en DATABASE_URL en el entorno del backend.

    3. Reiniciar/desplegar el backend y cualquier proceso que use esa conexión (workers, cron, etc.).

    4. Verificar que la API y los jobs se conectan correctamente.

  • Impacto: Si el backend sigue con la contraseña antigua, dejará de conectar a la BD hasta actualizar.

SMTP (correo)

  • Dónde se definen: SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_FROM_NAME, SMTP_FROM_EMAIL (y opcionalmente SMTP_SECURE).

  • Pasos:

    1. En el panel del proveedor SMTP (Mailtrap, SendGrid, etc.), generar nuevas credenciales o cambiar la contraseña.

    2. Actualizar SMTP_USER y SMTP_PASSWORD (y el resto si cambió) en el entorno del backend.

    3. Reiniciar/desplegar el backend.

    4. Enviar un correo de prueba (por ejemplo desde el panel de reportes) para verificar.

  • Impacto: El envío de reportes o notificaciones por correo fallará hasta que las credenciales sean correctas.

SendGrid (alternativa de correo)

  • Dónde se definen: SENDGRID_API_KEY, SENDGRID_FROM_EMAIL.

  • Pasos:

    1. En SendGrid: Settings → API Keys → crear nueva API key con los permisos necesarios.

    2. Actualizar SENDGRID_API_KEY en el entorno del backend.

    3. Desplegar/reiniciar.

    4. Revocar o eliminar la API key antigua en SendGrid.

  • Impacto: Cualquier flujo que envíe correo vía SendGrid fallará hasta actualizar la clave.

Pusher

  • Dónde se definen: PUSHER_APP_ID, PUSHER_KEY, PUSHER_SECRET, PUSHER_CLUSTER (y PUSHER_TLS si se usa).

  • Pasos:

    1. En el dashboard de Pusher, regenerar el secret o crear un nuevo canal/app si aplica.

    2. Actualizar las variables en el entorno del backend y, si el frontend usa clave pública, actualizar también allí.

    3. Reiniciar backend y probar notificaciones en tiempo real.

  • Impacto: Las notificaciones en tiempo real pueden dejar de funcionar hasta sincronizar las nuevas credenciales.

Buenas prácticas

  • Nunca versionar secrets en el repositorio; usar .env local y variables de entorno en CI/CD y producción.

  • Usar un gestor de secrets (por ejemplo Google Secret Manager, AWS Secrets Manager, HashiCorp Vault) en producción cuando sea posible.

  • Documentar en un lugar seguro (acceso restringido) qué sistemas o personas usan cada clave (p. ej. “n8n QA usa la segunda clave de BOT_API_KEYS”).

  • Tras una rotación, revisar logs y accesos para detectar intentos de uso con la clave antigua (posible compromiso).

  • En producción, no usar valores por defecto como change-this-secret-in-production para XSRF_SECRET; siempre definir XSRF_SECRET explícitamente.

Resumen rápido

Secret

Rotar si…

Acción principal

BOT_API_KEYS

Compromiso, salida de integración, periódico

Añadir nueva clave → actualizar clientes → quitar vieja

XSRF_SECRET

Compromiso, periódico

Cambiar variable y reiniciar backend

Firebase Admin

Compromiso, rotación de cuentas de servicio

Nuevo JSON en env o archivo; opcional revocar clave antigua

DB (password/URL)

Compromiso, rotación de contraseñas

Cambiar en BD y en env del backend; reiniciar

SMTP / SendGrid / Pusher

Compromiso, cambio de proveedor o clave

Nuevas credenciales en env; reiniciar y probar