2b3b2362db
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
61 lines
4.2 KiB
Plaintext
61 lines
4.2 KiB
Plaintext
---
|
|
title: Rotación de claves
|
|
icon: rotate
|
|
---
|
|
|
|
Twenty tiene dos familias de claves independientes:
|
|
|
|
* **Claves de firma JWT** — pares de claves asimétricas ES256 (etiquetados con `kid`) almacenados en `core."signingKey"`, utilizados para firmar y verificar tokens de acceso/renovación.
|
|
* **Clave de cifrado en reposo** — `ENCRYPTION_KEY`, se usa para cifrar tokens OAuth, variables de la aplicación, claves privadas de las claves de firma, valores de configuración confidenciales y secretos TOTP dentro de un sobre `enc:v2:`.
|
|
|
|
`APP_SECRET` es un secreto heredado mantenido para compatibilidad retroactiva: cuando `ENCRYPTION_KEY` no está definido actúa como el cifrado en reposo / alternativa para la cookie de sesión, y todavía verifica los tokens de acceso HS256 preexistentes. Quedará obsoleto.
|
|
|
|
## Claves de firma JWT
|
|
|
|
Cada clave contiene una `publicKey` (conservada indefinidamente para poder verificar los tokens emitidos anteriormente), una `privateKey` cifrada (usada solo mientras la clave sea la actual), un indicador `isCurrent` (exactamente una fila a la vez) y un `revokedAt` opcional.
|
|
|
|
### Rotar la clave actual
|
|
|
|
Establece `SIGNING_KEY_ROTATION_DAYS` para habilitarlo: un cron diario emite una nueva clave actual cuando la existente es más antigua que ese umbral. Las claves anteriores *no* se revocan, por lo que los tokens firmados con ellas siguen verificándose. Deja la variable sin configurar para desactivar la rotación automática.
|
|
|
|
<Note>La rotación automática se incluye a partir de la versión v2.6+.</Note>
|
|
|
|
### Revocar una clave (solo en caso de filtración / emergencia)
|
|
|
|
**Settings → Admin Panel → Signing keys → Revoke** en una fila que no sea la actual. Borra el material privado cifrado, establece `revokedAt` y rechaza todos los tokens existentes firmados con ese `kid`.
|
|
|
|
## Rotar `ENCRYPTION_KEY`
|
|
|
|
<Note>El comando `secret-encryption:rotate` descrito a continuación se incluye a partir de la versión v2.6+.</Note>
|
|
|
|
Cada valor cifrado se encapsula como `enc:v2:\<keyId>:\<payload>`, donde `\<keyId>` es un prefijo hexadecimal de 8 caracteres derivado de la clave en bruto. La rotación es en línea y reanudable.
|
|
|
|
1. **Generar una nueva clave**: `openssl rand -base64 32`.
|
|
|
|
2. **Configurar ambas claves en paralelo** en `.env`, luego reinicie:
|
|
```ini
|
|
ENCRYPTION_KEY=NEW_VALUE
|
|
FALLBACK_ENCRYPTION_KEY=OLD_VALUE
|
|
```
|
|
Las nuevas escrituras usan la nueva clave, las filas existentes todavía se descifran mediante la clave de respaldo.
|
|
|
|
3. **Volver a cifrar las filas existentes**:
|
|
|
|
```bash
|
|
docker exec -it {server_container} yarn command:prod secret-encryption:rotate
|
|
```
|
|
|
|
El comando recorre seis sitios (`connected-account-tokens`, `application-variable`, `application-registration-variable`, `signing-key-private-keys`, `sensitive-config-storage`, `totp-secrets`). Un filtro SQL omite las filas que ya están en el nuevo `\<keyId>`, por lo que el comando es idempotente: interrúmpalo y vuelva a ejecutarlo según sea necesario. Finaliza con código distinto de cero si falla alguna fila; vuelva a ejecutar para reintentar.
|
|
|
|
| Opción | Descripción |
|
|
| ---------------------------------------- | ----------------------------------------------------------- |
|
|
| `-s, --site \<site>` | Limitar a un solo sitio. |
|
|
| `-b, --batch-size \<n>` | Filas por lote (predeterminado `200`, máximo `5000`). |
|
|
| `-d, --dry-run` | Descifrar + volver a cifrar en memoria, omitir el `UPDATE`. |
|
|
|
|
4. **Elimine la clave de respaldo** una vez que `--dry-run` muestre cero filas restantes: quite `FALLBACK_ENCRYPTION_KEY` y reinicie.
|
|
|
|
## Compatibilidad heredada con `APP_SECRET`
|
|
|
|
Las instancias más antiguas que nunca configuraron `ENCRYPTION_KEY` usan `APP_SECRET` como la clave de cifrado en reposo (y como el secreto de la cookie de sesión, derivado de esta). Esta ruta se conserva por compatibilidad retroactiva, pero está **en desuso**: configure una `ENCRYPTION_KEY` dedicada y siga el procedimiento de rotación anterior para migrar y dejar de usarla. El propio `APP_SECRET` sigue utilizándose para verificar tokens de acceso HS256 heredados.
|