Ogni applicazione ha bisogno di credenziali: la password del database, la chiave per inviare email, il token di un servizio di pagamento, la chiave privata di un certificato. Questi dati, chiamati genericamente segreti, sono tra le informazioni più preziose di un'infrastruttura. Eppure finiscono spesso nei posti sbagliati: nel codice sorgente, in un messaggio di chat, in un file condiviso. Gestirli bene non richiede strumenti costosi, ma regole chiare.
Il primo errore: segreti nel codice
Scrivere una password direttamente nel codice è comodo e pericoloso. Il codice viene copiato, condiviso, salvato nei backup, caricato su servizi di integrazione continua, letto da collaboratori esterni. Ogni copia è una possibile fuga.
Il problema peggiora con Git. Se un segreto viene salvato in un commit e poi cancellato in un commit successivo, resta nella cronologia. Chiunque abbia accesso al repository può recuperarlo. Se il repository è pubblico, esistono programmi automatici che cercano chiavi e token appena vengono pubblicati.
Variabili d'ambiente e file .env
Il passo minimo è separare la configurazione dal codice, leggendo i segreti da variabili d'ambiente. L'applicazione cerca DATABASE_PASSWORD all'avvio invece di contenerla.
In sviluppo è comune usare un file .env caricato automaticamente. Le regole sono due:
- il file
.envva inserito in.gitignoreprima ancora di crearlo; - nel repository si tiene un
.env.examplecon i nomi delle variabili e valori fittizi.
Le variabili d'ambiente hanno però dei limiti. Possono comparire nei log di errore, nei dump di diagnostica o nell'output di comandi che elencano i processi. Sono un miglioramento rispetto al codice, non una soluzione completa per la produzione.
I secret manager
Un secret manager è un servizio dedicato a custodire segreti. Tutti i grandi provider cloud ne offrono uno, e tra le soluzioni installabili la più nota è HashiCorp Vault. Le funzioni tipiche sono:
- cifratura dei segreti a riposo e durante il trasferimento;
- controllo degli accessi: ogni applicazione legge solo i segreti che le servono;
- registro degli accessi: si sa chi ha letto quale segreto e quando;
- versioni: si può tornare a un valore precedente;
- rotazione: alcuni segreti, come le password dei database gestiti, possono essere cambiati automaticamente.
L'applicazione si autentica presso il secret manager con un'identità propria, per esempio il ruolo assegnato alla macchina virtuale o al container, e riceve il segreto al momento dell'avvio. Nessuna password è scritta su disco in chiaro.
Confronto tra le opzioni
| Metodo | Sicurezza | Complessità | Adatto a |
|---|---|---|---|
| Segreto nel codice | Molto bassa | Nessuna | Mai |
| File .env non versionato | Bassa | Minima | Sviluppo locale |
| Variabili nella piattaforma di hosting o CI | Media | Bassa | Piccoli progetti |
| File cifrati nel repository | Media | Media | Team piccoli con flussi Git |
| Secret manager | Alta | Media | Produzione |
Principi di buona gestione
Minimo privilegio
Ogni credenziale deve permettere solo ciò che serve. L'utente del database usato dall'applicazione web non ha bisogno di cancellare tabelle; la chiave per caricare file in un bucket non deve poterne leggere un altro. Se una credenziale viene rubata, il danno è limitato a ciò che essa consente.
Un segreto per ogni uso
Non riutilizzare la stessa chiave per sviluppo e produzione, né per due applicazioni diverse. Se una deve essere revocata, le altre continuano a funzionare, e i registri mostrano con precisione quale è stata usata.
Credenziali temporanee
Dove possibile, preferisci credenziali che scadono da sole. Molti servizi cloud permettono a una pipeline o a una macchina di ottenere token validi per pochi minuti, invece di custodire chiavi permanenti. Una chiave che scade dopo un'ora vale poco per chi la ruba.
Rotazione
Cambia periodicamente i segreti più importanti e, soprattutto, sii capace di cambiarli rapidamente. Se ruotare la password del database richiede di modificare dieci file su cinque server, nel momento dell'emergenza non lo farà nessuno.
Se un segreto è finito in Git
Succede anche ai migliori. L'ordine delle operazioni conta:
- Revoca o cambia subito il segreto presso il servizio a cui appartiene. È il passo più importante: da quel momento la copia trapelata non vale più.
- Controlla i registri del servizio per verificare se la credenziale è stata usata da qualcuno di non autorizzato.
- Rimuovi il segreto dal codice e dalla cronologia, con strumenti come
git filter-repo, sapendo che le copie già scaricate da altri non si possono cancellare. - Aggiungi un controllo automatico che impedisca il ripetersi del problema.
Riscrivere la cronologia senza aver prima revocato il segreto è inutile: la chiave potrebbe essere già stata copiata.
Prevenire con l'automazione
Strumenti come gitleaks o le funzioni di scansione integrate nelle piattaforme di hosting del codice analizzano ogni commit alla ricerca di chiavi e token. Configurati come hook prima del commit o come passo della pipeline, bloccano il problema prima che il segreto lasci il computer dello sviluppatore. È una protezione economica che, nel mio lavoro, considero obbligatoria su ogni repository.
In sintesi
- I segreti non vanno mai nel codice: anche se cancellati, restano nella cronologia di Git.
- Variabili d'ambiente e file
.envnon versionati vanno bene per lo sviluppo; in produzione serve un secret manager. - Applica il minimo privilegio, usa un segreto per ogni scopo e preferisci credenziali temporanee.
- Se un segreto trapela, revocalo prima di tutto, poi verifica i registri e pulisci la cronologia.
- Scanner automatici nei commit e nelle pipeline evitano la maggior parte degli incidenti.