Vai al contenuto

Rotazione di chiave master e chiavi di firma, e accesso di emergenza

Ruota la chiave master che protegge le credenziali archiviate e usa l'accesso di emergenza.

I controlli nella sezione 14 di 21-compliance.md che un auditor chiede per nome. Questa pagina è la procedura; i record che produce sono la prova.

Le chiavi

Ogni credenziale archiviata è sigillata con una chiave di cifratura dati (DEK) nuova. La DEK è avvolta dalla chiave master (la KEK), e il riferimento della chiave master è conservato accanto (key_ref, oppure il riferimento dentro un valore impacchettato). Ruotare la chiave master riavvolge le DEK. Non decifra né ricifra mai una credenziale.

Impostazione Significato
QUIRE_MASTER_KEY La chiave master corrente: 32 byte, base64. Ogni nuovo segreto è avvolto sotto di essa
QUIRE_MASTER_KEY_VERSION La sua etichetta di versione. v1 se non impostata. Alzala ogni volta che cambi la chiave
QUIRE_MASTER_KEY_RETIRED Chiavi precedenti sotto cui potrebbero ancora trovarsi segreti archiviati, come v1=<base64>,v0=<base64>. Lettura, mai scrittura

Il livello web, il worker e il comando bun run kek:rotate leggono le stesse tre impostazioni. Devono avere tutte gli stessi valori, altrimenti una non può aprire ciò che un’altra ha sigillato.

Senza QUIRE_MASTER_KEY ciascun sottosistema conserva la chiave che deriva da QUIRE_SECRET_KEY. Funziona, la pagina Stato del sistema la mostra come degradata, e resta leggibile dopo aver impostato una chiave master, ed è così che la prima rotazione sposta tutto fuori da essa. Chiunque possa leggere l’ambiente del processo può decifrare ogni credenziale archiviata, quindi un’installazione di produzione dovrebbe avere una chiave master, conservata in un archivio di segreti e non nello stesso backup del database.

Rotazione

L’età della chiave è mostrata in Console piattaforma, Sicurezza, Chiave master, e come metrica quire.secrets.master_key.age (giorni). La programmazione giornaliera platform.key_age (03:41 UTC) scrive una voce promemoria nella catena di audit della piattaforma quando la chiave compie 365 giorni, e di nuovo ogni 30 giorni finché non viene ruotata. Ruota al promemoria, e ogni volta che una chiave potrebbe essere stata esposta.

  1. Genera la nuova chiave: openssl rand -base64 32.
  2. Imposta QUIRE_MASTER_KEY su di essa e QUIRE_MASTER_KEY_VERSION sulla prossima etichetta (v2). Sposta la vecchia chiave in QUIRE_MASTER_KEY_RETIRED come v1=<old base64>. Conserva una copia di entrambe altrove rispetto a questo host.
  3. Distribuisci il livello web e il worker con le nuove impostazioni. I nuovi segreti sono ora avvolti sotto env:QUIRE_MASTER_KEY:v2; quelli vecchi si aprono ancora tramite la chiave ritirata.
  4. Richiedi la rotazione, con la motivazione che resterà nella traccia di audit:
    • nella console: Sicurezza, Chiave master, Ruota la chiave master; oppure
    • su una shell con lo stesso ambiente: bun run kek:rotate request --reason "Annual rotation, ticket SEC-114".
  5. Il worker riavvolge una fetta al minuto (la programmazione platform.key_rotation dello scheduler) e riprende dopo un riavvio. Per finirla in una sola seduta: bun run kek:rotate run. Seguila con bun run kek:rotate status.
  6. Quando il record mostra che la rotazione è completata con zero irrisolti e zero falliti, rimuovi la chiave ritirata da QUIRE_MASTER_KEY_RETIRED e ridistribuisci. Fino ad allora conservala: un valore che non è stato possibile spostare è ancora avvolto sotto la vecchia chiave.

Cosa percorre il job

Ogni archivio che contiene una DEK avvolta: quelli in SEALED_STORES (apps/worker/src/key-rotation.ts). Gli archivi del database di controllo sono percorsi sul database di controllo; gli archivi delle organizzazioni sono percorsi un’organizzazione alla volta sotto sicurezza a livello di riga, nel database che contiene l’organizzazione, così un tenant fissato a un database dedicato viene ruotato in quel database. Un test fallisce quando lo schema acquisisce una colonna con chiave avvolta che l’elenco non nomina, e un altro quando la revisione delle credenziali classifica una colonna sigillata che l’elenco manca.

Il record

  • ops.key_rotation: una riga per rotazione, con motivazione, chi l’ha richiesta, stato e totali (riavvolti, già aggiornati, irrisolti, falliti).
  • ops.key_rotation_progress: una riga per archivio e ambito una volta percorso, con i riferimenti di chiave non leggibili e quanti valori si trovavano sotto ciascuno. Una rotazione ripresa salta questi.
  • Catena di audit della piattaforma: platform/key_rotation_request (con la motivazione), una platform/key_rotation_store per archivio con i suoi conteggi, e platform/key_rotation_complete oppure platform/key_rotation_fail; platform/key_age_reminder per il promemoria.
  • Metriche: quire.secrets.master_key.age e quire.secrets.rewrap.outstanding (valori che l’ultima rotazione non ha potuto spostare).

Quando i valori sono irrisolti

Un valore irrisolto è avvolto sotto un riferimento di chiave che questa installazione non possiede, oppure non è nella forma promessa dalla sua colonna. Il record di avanzamento nomina il riferimento (ad esempio env:QUIRE_MASTER_KEY:v0 (unreadable)). Ripristina quella chiave in QUIRE_MASTER_KEY_RETIRED ed esegui un’altra rotazione, oppure, se la chiave è persa per sempre, chiedi all’amministratore dell’organizzazione di inserire di nuovo la credenziale: essa verrà sigillata sotto la chiave corrente. Le rotazioni fallite mostrano il loro errore sul record; correggi la causa e richiedi di nuovo.

Chiavi di firma

Separate dalla chiave master: ciascuna organizzazione firma i propri token OpenID Connect e messaggi LTI con la propria chiave RSA, pubblicata in /.well-known/jwks.json. Qui nulla richiede un operatore. La programmazione oraria platform.signing_keys pubblica un successore sette giorni prima che i novanta della chiave corrente scadano, una settimana dopo il successore inizia a firmare e la vecchia chiave diventa in ritiro, e novanta giorni dopo la vecchia chiave viene eliminata e lascia il set di chiavi. Ogni passaggio è una voce platform/signing_key_advance sulla catena di audit della piattaforma.

Per sostituire prima la chiave di un’organizzazione, ad esempio dopo un’esposizione:

  • nella console: Sicurezza, Chiave master, Pubblica una nuova chiave di firma (serve platform/keys_manage); oppure
  • su una shell con l’ambiente del worker: bun run kek:rotate signing-keys rotate --tenant <slug or id> --reason "Key exposed, INC-3310". bun run kek:rotate signing-keys status elenca le chiavi di ogni organizzazione per fase.

La nuova chiave viene pubblicata subito e inizia a firmare dopo sette giorni, quando la chiave corrente va in ritiro. La settimana è intenzionale: le parti fidate memorizzano il set di chiavi, e una sovrapposizione più breve fa fallire ogni strumento in una volta sola. La chiave in ritiro resta nel set di chiavi per altri novanta giorni così i token già firmati continuano a verificarsi; se l’esposizione richiede che smetta di essere attendibile prima, eliminare la sua riga è una modifica effettuata con l’accesso database proprio dell’operatore sotto un record di modifica (l’accesso di emergenza è di sola lettura), e i token firmati con essa falliscono poi la verifica. La rotazione forzata è platform/signing_key_rotate nella catena di audit, con la motivazione. Il worker necessita delle stesse impostazioni QUIRE_MASTER_KEY del livello web per avvolgere la nuova chiave; bun run kek:rotate per la chiave master riavvolge le chiavi di firma con tutto il resto (oauth_signing_key è in SEALED_STORES).

Accesso di emergenza alla produzione

Nessuno detiene un accesso permanente alla produzione. Quando qualcosa non può attendere, un proprietario emette una concessione di emergenza: Console piattaforma, Sicurezza, Accesso di emergenza.

  • Una concessione ha un ambito (un’organizzazione, oppure il registro della piattaforma), una motivazione di almeno 20 caratteri che nomina l’incidente o il ticket, e una finestra da 5 a 240 minuti. Scade da sola: viene verificata contro l’orologio a ogni istruzione.
  • Può essere emessa al proprietario che la emette, oppure a un altro proprietario (il modulo a due persone). Solo la persona a cui è stata emessa può usarla. Emettere richiede platform/break_glass_issue e usare richiede platform/break_glass_use; entrambi sono riservati ai proprietari per impostazione predefinita.
  • Le istruzioni girano tramite il gateway, non su un login database: sola lettura, una alla volta, confinate all’organizzazione o al registro di controllo, con timeout di cinque secondi e al massimo 500 righe. I valori binari sono mostrati per dimensione.
  • La catena di audit della piattaforma registra l’emissione (con la motivazione), la revoca, ogni istruzione prima che giri (platform/break_glass_statement, quelle rifiutate con esito denied) e ogni risultato (platform/break_glass_result). ops.break_glass_statement contiene gli id delle voci di audit, così il record di emissione si unisce alle sue voci di audit.
  • Le scritture non sono offerte. Una modifica che non può attendere una release usa l’accesso database proprio dell’operatore sotto un proprio record di modifica, fuori da questo prodotto, e il record dovrebbe citare il riferimento di incidente usato qui.

Perché non emettere credenziali database: un login Postgres sopravvive alla sessione che l’ha chiesto, aggira la sicurezza a livello di riga su cui l’applicazione fa affidamento, e non può scrivere nella catena di audit di questo prodotto, così le sue istruzioni sarebbero verificate solo fin dove qualcuno ha spedito il registro del server. Il gateway rende la traccia di audit una proprietà dell’accesso anziché una pratica attorno a esso.

Per rispondere a una richiesta di audit: elenca le concessioni del periodo (Accesso di emergenza), apri la cronologia di una concessione per le sue istruzioni e gli id delle voci di audit, e leggi quelle voci sulla catena di audit della piattaforma (bun run audit:verify --platform prova che la catena è integra).

Navigazione

Digita per cercare…

↑↓ per spostarti↵ per selezionareEsc per chiudere