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, claves JWT del IdP 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 |
OAUTH2_CLIENT_SECRET, SIGNER_KEY, SALT_SEPARATOR |
IdP local: client secret y material de hash de contraseñas |
server.js, routes/public/auth.js |
Par de claves RSA ( |
Firma JWT RS256 y JWKS |
server.js, oauth-local-auth |
DATABASE_URL o DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD |
PostgreSQL principal |
db/index.js, rutas |
DB_NAME_ACCOUNTING |
Base contable NIIF |
install-accounting.js, rutas /accounting |
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:
-
Generar una nueva clave (por ejemplo 64 caracteres hex:
openssl rand -hex 32). -
Añadir la nueva clave a
BOT_API_KEYSmanteniendo la antigua:BOT_API_KEYS=clave_vieja,clave_nueva. -
Desplegar o reiniciar el backend para que cargue el nuevo valor.
-
Actualizar todos los clientes que usan X-Auth (n8n, scripts, integraciones) para que usen
clave_nueva. -
Verificar que las integraciones responden correctamente con la nueva clave.
-
Eliminar
clave_viejadeBOT_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:
-
Generar un nuevo secret (por ejemplo
openssl rand -hex 32). -
Actualizar
XSRF_SECRETen el entorno del servidor. -
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.
Claves JWT del IdP local (RSA)
-
Dónde se definen: par
functions/ssl/id_rsa(privada) eid_rsa.pub(pública/JWKS);OAUTH2_JWKS_KIDopcional. -
Pasos:
-
Generar nuevo par RSA (
openssl genrsa -out id_rsa 2048y extraer pública). -
Desplegar ambos archivos en el servidor (permisos restrictivos en la privada).
-
Reiniciar el backend; publicar JWKS en
/.well-known/jwks.json. -
Tras validar logins, retirar el par anterior.
-
-
Impacto: tokens firmados con la clave antigua dejan de ser válidos tras el cambio.
OAuth2 client secret
-
Dónde se define:
OAUTH2_CLIENT_SECRETenfunctions/.env. -
Rotar generando nuevo secret, actualizar
.envy clientes máquina que usen client credentials.
Base de datos (DATABASE_URL o DB_*)
-
Dónde se definen:
DATABASE_URLoDB_HOST,DB_PORT,DB_NAME,DB_USER,DB_PASSWORD(yDB_SSLsi aplica). -
Pasos (cambio de contraseña en PostgreSQL):
-
En el servidor de base de datos, cambiar la contraseña del usuario (por ejemplo con
ALTER USER unosport_admin PASSWORD 'nueva_contrasena';). -
Actualizar
DB_PASSWORDo la parte de contraseña enDATABASE_URLen el entorno del backend. -
Reiniciar/desplegar el backend y cualquier proceso que use esa conexión (workers, cron, etc.).
-
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 opcionalmenteSMTP_SECURE). -
Pasos:
-
En el panel del proveedor SMTP (Mailtrap, SendGrid, etc.), generar nuevas credenciales o cambiar la contraseña.
-
Actualizar
SMTP_USERySMTP_PASSWORD(y el resto si cambió) en el entorno del backend. -
Reiniciar/desplegar el backend.
-
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:
-
En SendGrid: Settings → API Keys → crear nueva API key con los permisos necesarios.
-
Actualizar
SENDGRID_API_KEYen el entorno del backend. -
Desplegar/reiniciar.
-
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(yPUSHER_TLSsi se usa). -
Pasos:
-
En el dashboard de Pusher, regenerar el secret o crear un nuevo canal/app si aplica.
-
Actualizar las variables en el entorno del backend y, si el frontend usa clave pública, actualizar también allí.
-
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
.envlocal 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-productionpara XSRF_SECRET; siempre definirXSRF_SECRETexplí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 |
OAuth2 JWT / client secret |
Compromiso, rotación periódica |
Nuevo par RSA o secret; reiniciar API |
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 |