Skip to main content
Twenty ha due famiglie di chiavi indipendenti:
  • Chiavi di firma JWT — coppie di chiavi asimmetriche ES256 (con tag kid) archiviate in core."signingKey", utilizzate per firmare e verificare i token di accesso / aggiornamento.
  • Chiave di crittografia a riposoENCRYPTION_KEY, utilizzata per crittografare token OAuth, variabili dell’applicazione, chiavi private delle chiavi di firma, valori di configurazione sensibili e segreti TOTP all’interno di un involucro enc:v2:.
APP_SECRET è un segreto legacy mantenuto per compatibilità con le versioni precedenti: quando ENCRYPTION_KEY non è impostata funge da fallback per la crittografia a riposo / cookie di sessione e continua a verificare i token di accesso HS256 preesistenti. Sarà deprecata.

Chiavi di firma JWT

Ogni chiave contiene una publicKey (mantenuta indefinitamente così da poter verificare i token emessi in precedenza), una privateKey crittografata (utilizzata solo mentre la chiave è quella corrente), un flag isCurrent (esattamente una riga alla volta) e un campo revokedAt opzionale.

Ruotare la chiave corrente

Imposta SIGNING_KEY_ROTATION_DAYS per aderire: un cron giornaliero emette quindi una nuova chiave corrente quando quella esistente è più vecchia di tale soglia. Le chiavi precedenti non vengono revocate, quindi i token firmati con esse continuano a essere verificati. Lascia la variabile non impostata per disattivare la rotazione automatica.
La rotazione automatica è disponibile a partire dalla versione v2.6+.

Revocare una chiave (solo in caso di fuga di dati / emergenza)

Settings → Admin Panel → Signing keys → Revoke su una riga non corrente. Cancella il materiale privato crittografato, imposta revokedAt e rifiuta ogni token esistente firmato con quel kid.

Ruotare ENCRYPTION_KEY

Il comando secret-encryption:rotate descritto di seguito è disponibile dalla v2.6+.
Ogni valore crittografato è incapsulato come enc:v2:\<keyId>:\<payload>, dove \<keyId> è un prefisso esadecimale a 8 caratteri derivato dalla chiave grezza. La rotazione è online e riprendibile.
  1. Generare una nuova chiave: openssl rand -base64 32.
  2. Configurare entrambe le chiavi affiancate in .env, quindi riavviare:
    ENCRYPTION_KEY=NEW_VALUE
    FALLBACK_ENCRYPTION_KEY=OLD_VALUE
    
    Le nuove scritture usano la nuova chiave, le righe esistenti vengono ancora decrittate tramite il fallback.
  3. Ricrittografare le righe esistenti:
    docker exec -it {server_container} yarn command:prod secret-encryption:rotate
    
    Il comando passa in rassegna sei sezioni (connected-account-tokens, application-variable, application-registration-variable, signing-key-private-keys, sensitive-config-storage, totp-secrets). Un filtro SQL salta le righe già con il nuovo \<keyId>, quindi il comando è idempotente: interrompi e riesegui secondo necessità. Esce con codice diverso da zero se una qualsiasi riga fallisce — riesegui per riprovare.
    OpzioneDescrizione
    -s, --site \<site>Limita a un singolo sito.
    -b, --batch-size \<n>Righe per batch (predefinito 200, massimo 5000).
    -d, --dry-runDecrittografa + ricrittografa in memoria, salta l’UPDATE.
  4. Eliminare il fallback una volta che --dry-run mostra zero righe rimanenti: rimuovere FALLBACK_ENCRYPTION_KEY e riavviare.

Supporto legacy per APP_SECRET

Le istanze meno recenti che non hanno mai impostato ENCRYPTION_KEY usano APP_SECRET come chiave di crittografia a riposo (e come segreto del cookie di sessione, derivato da essa). Questo percorso è mantenuto per compatibilità con le versioni precedenti ma è deprecato — imposta una ENCRYPTION_KEY dedicata e segui la procedura di rotazione sopra per migrare. APP_SECRET continua a essere utilizzata per verificare i token di accesso HS256 legacy.