2b3b2362db
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
61 lines
4.4 KiB
Plaintext
61 lines
4.4 KiB
Plaintext
---
|
||
title: Rotation des clés
|
||
icon: rotate
|
||
---
|
||
|
||
Twenty possède deux familles de clés indépendantes :
|
||
|
||
* **Clés de signature JWT** — paires de clés asymétriques ES256 (avec balise `kid`) stockées dans `core."signingKey"`, utilisées pour signer et vérifier les jetons d’accès / de rafraîchissement.
|
||
* **Clé de chiffrement au repos** — `ENCRYPTION_KEY`, utilisée pour chiffrer les jetons OAuth, les variables d’application, les clés privées de clés de signature, les valeurs de configuration sensibles et les secrets TOTP à l’intérieur d’une enveloppe `enc:v2:`.
|
||
|
||
`APP_SECRET` est un secret hérité conservé pour la rétrocompatibilité : lorsque `ENCRYPTION_KEY` n’est pas défini, il agit comme mécanisme de secours pour le chiffrement au repos / le cookie de session, et il continue de vérifier les jetons d’accès HS256 préexistants. Il sera déprécié.
|
||
|
||
## Clés de signature JWT
|
||
|
||
Chaque clé contient une `publicKey` (conservée indéfiniment afin de pouvoir vérifier les jetons émis précédemment), une `privateKey` chiffrée (utilisée uniquement tant que la clé est actuelle), un indicateur `isCurrent` (exactement une ligne à la fois) et un champ `revokedAt` facultatif.
|
||
|
||
### Faire pivoter la clé actuelle
|
||
|
||
Définissez `SIGNING_KEY_ROTATION_DAYS` pour l’activer : une tâche cron quotidienne émet alors une nouvelle clé actuelle dès que l’ancienne dépasse ce seuil. Les clés précédentes ne sont *pas* révoquées, donc les jetons signés avec celles-ci restent vérifiables. Laissez la variable non définie pour désactiver la rotation automatique.
|
||
|
||
<Note>La rotation automatique est disponible à partir de la v2.6+.</Note>
|
||
|
||
### Révoquer une clé (fuite / urgence uniquement)
|
||
|
||
**Settings → Admin Panel → Signing keys → Revoke** sur une ligne non actuelle. Efface le matériel privé chiffré, définit `revokedAt` et rejette chaque jeton existant signé avec ce `kid`.
|
||
|
||
## Faire pivoter `ENCRYPTION_KEY`
|
||
|
||
<Note>La commande `secret-encryption:rotate` décrite ci-dessous est fournie à partir de la v2.6+.</Note>
|
||
|
||
Chaque valeur chiffrée est encapsulée sous la forme `enc:v2:\<keyId>:\<payload>`, où `\<keyId>` est un préfixe hexadécimal sur 8 caractères dérivé de la clé brute. La rotation est en ligne et reprenable.
|
||
|
||
1. **Générez une nouvelle clé** : `openssl rand -base64 32`.
|
||
|
||
2. **Configurez les deux clés côte à côte** dans `.env`, puis redémarrez :
|
||
```ini
|
||
ENCRYPTION_KEY=NEW_VALUE
|
||
FALLBACK_ENCRYPTION_KEY=OLD_VALUE
|
||
```
|
||
Les nouvelles écritures utilisent la nouvelle clé, les lignes existantes se déchiffrent toujours via la clé de secours.
|
||
|
||
3. **Rechiffrez les lignes existantes** :
|
||
|
||
```bash
|
||
docker exec -it {server_container} yarn command:prod secret-encryption:rotate
|
||
```
|
||
|
||
La commande parcourt six sites (`connected-account-tokens`, `application-variable`, `application-registration-variable`, `signing-key-private-keys`, `sensitive-config-storage`, `totp-secrets`). Un filtre SQL ignore les lignes déjà sur le nouveau `\<keyId>`, de sorte que la commande est idempotente : interrompez-la et relancez-la si nécessaire. Quitte avec un code de sortie non nul si une ligne échoue — relancez pour réessayer.
|
||
|
||
| Option | Description |
|
||
| ---------------------------------------- | ----------------------------------------------------------------- |
|
||
| `-s, --site \<site>` | Limiter à un seul site. |
|
||
| `-b, --batch-size \<n>` | Lignes par lot (valeur par défaut `200`, maximum `5000`). |
|
||
| `-d, --dry-run` | Déchiffrer + rechiffrer en mémoire, ignorer la commande `UPDATE`. |
|
||
|
||
4. **Supprimez la clé de secours** une fois que `--dry-run` n’affiche plus aucune ligne restante : supprimez `FALLBACK_ENCRYPTION_KEY` et redémarrez.
|
||
|
||
## Prise en charge héritée de `APP_SECRET`
|
||
|
||
Les instances plus anciennes qui n’ont jamais défini `ENCRYPTION_KEY` utilisent `APP_SECRET` comme clé de chiffrement au repos (et comme secret de cookie de session, dérivé de celle-ci). Ce chemin est conservé pour la rétrocompatibilité mais est **déprécié** — définissez une `ENCRYPTION_KEY` dédiée et suivez la procédure de rotation ci-dessus pour migrer. `APP_SECRET` reste lui-même utilisé pour vérifier les anciens jetons d’accès HS256.
|