Por que rotar secrets
Los secrets (API keys, tokens, passwords) deben rotarse periódicamente para:
- Limitar el impacto si un secret fue comprometido sin saberlo
- Cumplir con mejores practicas de seguridad (OWASP, SOC 2)
- Evitar que secrets antiguos se acumulen en logs, backups o memorias de equipo
Frecuencia de rotación
| Secret | Frecuencia | Razon |
|---|---|---|
| JWT_SECRET | Trimestral | Tokens de sesion — limitar ventana de compromiso |
| MOBILE_JWT_SECRET | Trimestral | Tokens de app movil |
| ENCRYPTION_PASSWORD | Anual | Requiere re-encriptar datos existentes |
| ENCRYPTION_SALT | Anual | Mismo que ENCRYPTION_PASSWORD |
| CLERK_SECRET_KEY | Trimestral | Autenticación principal |
| CLERK_WEBHOOK_SECRET | Trimestral | Webhooks de Clerk |
| STRIPE_SECRET_KEY | Trimestral | Pagos — alto impacto si comprometido |
| STRIPE_WEBHOOK_SECRET | Trimestral | Webhooks de Stripe |
| TWILIO_AUTH_TOKEN | Trimestral | Mensajeria WhatsApp/SMS |
| OPENAI_API_KEY | Trimestral | Costo directo si comprometido |
| ANTHROPIC_API_KEY | Trimestral | Costo directo si comprometido |
| INVITATIONS_WEBHOOK_SECRET | Trimestral | Revalidación ISR |
| REDIS_PASSWORD | Semestral | Infraestructura interna |
| Certificados SSL | Antes de expiración | Ver guia de Certificate Pinning |
Checklist de rotación trimestral
Ejecutar cada inicio de trimestre (enero, abril, julio, octubre):
1. Generar nuevos valores
# JWT secrets
openssl rand -base64 32 # → JWT_SECRET
openssl rand -base64 32 # → MOBILE_JWT_SECRET
# Webhook secrets
openssl rand -base64 32 # → INVITATIONS_WEBHOOK_SECRET
openssl rand -base64 32 # → CLERK_WEBHOOK_SECRET
2. Actualizar en Bitwarden
- Abrir Bitwarden Secrets Manager
- Actualizar cada secret con el nuevo valor
- Registrar fecha de rotación en notas del secret
3. Actualizar en ambientes
| Ambiente | Donde actualizar |
|---|---|
| DEV | Coolify → nvito-api → Environment Variables |
| TEST | Coolify → nvito-api → Environment Variables |
| PROD | Railway → nvito-api → Environment Variables |
4. Rotar API keys externas
| Servicio | Donde rotar |
|---|---|
| Stripe | dashboard.stripe.com → Developers → API Keys → Roll key |
| Twilio | console.twilio.com → Account → API keys |
| OpenAI | platform.openai.com → API keys → Create new, delete old |
| Anthropic | console.anthropic.com → API keys |
| Clerk | dashboard.clerk.com → API keys → Rotate |
5. Desplegar cambios
- Restart nvito-api en cada ambiente (Coolify/Railway)
- Verificar que la app arranca correctamente (
/healthretorna OK) - Verificar que webhooks siguen funcionando (enviar test desde Clerk/Stripe)
6. Verificar
- Login en nvito-admin funciona (Clerk)
- RSVP en invitación pública funciona
- Webhook de revalidación ISR funciona
- Login movil en nvito-client funciona (JWT)
7. Documentar
- Registrar fecha de rotación en Bitwarden
- Notificar al equipo via canal de comunicación interno
Consideraciones especiales
ENCRYPTION_PASSWORD y ENCRYPTION_SALT
Estos secrets protegen datos PII encriptados en la base de datos (emails, teléfonos de invitados). Rotarlos requiere re-encriptar todos los datos existentes. Este proceso es:
- Generar nuevo password/salt
- Ejecutar script de migración que desencripte con valores viejos y re-encripte con nuevos
- Verificar integridad de datos
- Actualizar variables de entorno
- Desplegar
Frecuencia: Anual o si se sospecha compromiso.
JWT_SECRET — Impacto en sesiones activas
Al rotar JWT_SECRET, todos los tokens JWT existentes se invalidan. Los usuarios necesitaran re-autenticarse. Para minimizar impacto:
- Rotar en horario de bajo trafico
- Los refresh tokens del mobile (MOBILE_JWT_SECRET) también se invalidan — los usuarios de nvito-client necesitaran re-login
Clerk keys
Al rotar CLERK_SECRET_KEY, actualizar también CLERK_WEBHOOK_SECRET ya que Clerk puede regenerar ambas.
Que hacer si un secret fue comprometido
- Rotar inmediatamente — No esperar al ciclo trimestral
- Revocar el secret antiguo en el servicio externo (Stripe, Twilio, etc.)
- Revisar logs de acceso para detectar uso no autorizado
- Notificar al equipo con detalles del incidente
- Documentar el incidente y acciones tomadas