Protezione della pipeline e del flusso di lavoro CI/CD
Questo articolo descrive come proteggere le pipeline CI/CD e il flusso di lavoro.
L'automazione e la metodologia Agile consentono ai team di offrire prestazioni più veloci, ma anche di aggiungere complessità alla sicurezza perché il flusso di lavoro si estende ai team di sviluppo stessi.
Il diagramma seguente illustra un flusso di lavoro CI/CD di base. L'icona di configurazione rossa indica le autorizzazioni di sicurezza che il cliente deve configurare. Si segue il modello di responsabilità condivisa, in cui Azure e altri fornitori rendono disponibili le autorizzazioni che devono essere configurate dal cliente in base al modello di governance e ai requisiti aziendali.
Verranno ora esaminate tutte le fasi di questo flusso di lavoro tipico, per comprendere in che modo le configurazioni spesso dipendono l'una dall'altra. Il flusso di lavoro potrebbe prevedere più fasi. I concetti seguenti consentono di comprendere il CI/CD e di progettare il flusso di lavoro per la sicurezza.
Fase 1: flusso di lavoro Git
Le modifiche apportare al codice, non solo quelle per il software, ma anche quelle per la pipeline come codice e l'infrastruttura come codice, vengono salvate e gestite in Git. Git è un software di gestione del codice sorgente distribuito. Quando si esegue il push del codice dai computer locali al server Git centralizzato, è possibile applicare le regole business prima che il codice venga accettato.
Richieste pull e collaborazione
Il flusso di lavoro standard del settore, indipendentemente dal fornitore del Software as a Service (SaaS) per la gestione della configurazione del software, prevede l'uso di richieste pull, che possono agire sia da gatekeeper di qualità automatizzato che da passaggio di approvazione manuale prima che il codice sorgente venga accettato.
Il flusso di lavoro della richiesta pull è progettato per introdurre conflitti sani, motivo per cui deve essere applicato solo a rami Git specifici protetti. In particolare i rami che attiveranno flussi di lavoro automatizzati che possono distribuire, configurare o in qualsiasi altro modo influire sulle risorse cloud. Questi rami sono denominati rami protetti e, in genere, seguono convenzioni di denominazione come production
o releases/*
.
Di solito le richieste pull richiedono:
- Revisioni paritarie
- Passaggio di build di integrazione continua (CI)
- Approvazione manuale
Se i requisiti vengono soddisfatti, le modifiche del codice vengono accettate e possono essere unite.
Limitare l'accesso ai rami protetti
Il flusso di lavoro della richiesta pull viene usato insieme ai controlli di accesso limitati. Il flusso di lavoro della richiesta pull non può tuttavia essere applicato, a meno che il server non sia configurato per rifiutare le modifiche dirette ai rami protetti.
Uno sviluppatore non può eseguire il push direttamente nel ramo production
, ma deve creare una richiesta pull destinata al ramo protetto. Ogni fornitore di gestione della configurazione del software ha un modo diverso per ottenere l'accesso limitato ai rami protetti. Ad esempio, con GitHub questa funzionalità è disponibile solo per le organizzazioni che usano il team GitHub o il cloud di GitHub Enterprise.
Documentare il modello di accesso Git
Poiché il modello di collaborazione è complesso e include molte parti mobili, è utile creare una tabella che documenti tutti i modi possibili in cui le modifiche del codice possono attivare le distribuzioni, ad esempio:
Nome del ramo | Richiede una richiesta pull? | Esegue la distribuzione? | Accesso sviluppatore | Accesso amministratore |
---|---|---|---|---|
feat/* |
No | No | Lettura/scrittura | Lettura/scrittura |
main |
Sì | Staging | Lettura | Lettura/scrittura |
production |
Sì, solo da main |
Produzione | Lettura | Lettura/scrittura |
Questo esempio di tabella di accesso Git è molto semplificato per illustrarne lo scopo. Nella pratica, spesso ci sono più attori, più destinazioni di distribuzione e più pipeline che vengono eseguite per casi d'uso diversi. La struttura della tabella potrebbe essere diversa a seconda dei requisiti dell'organizzazione e dei carichi di lavoro.
La tabella dovrebbe essere utile per rispondere a domande quali:
- Se uno sviluppatore esegue il push delle modifiche del codice nel ramo X, ne esegue la distribuzione? In tal caso, in quale ambiente?
- A che punto del ciclo di vita del codice dell'applicazione viene eseguita un'analisi delle vulnerabilità?
- Se viene individuata una vulnerabilità di protezione, quanti push del codice e approvazioni sono necessari prima che arrivi nell'ambiente di produzione?
Questa tabella è utile non solo per il debug e la documentazione statica, ma anche per la collaborazione del team. Per gli sviluppatori è evidente il punto in cui sono stati introdotti conflitti sani nel flusso di lavoro per classificare in ordine di priorità la qualità e la sicurezza del codice. Ancora più importante, la tabella mostra allo sviluppatore il percorso previsto affinché le modifiche del codice raggiungano la produzione.
Poiché DevOps è un percorso, il modello di accesso Git non è statico. Cambia e si evolve man mano che i team prendono il ritmo e diventano sempre più competenti. Per questo motivo è importante archiviare la documentazione il più vicino possibile al codice, ad esempio nei repository Git.
Per altre informazioni sulle richieste pull e sui rami protetti, vedere:
- Impostare le autorizzazioni del ramo
- Creare, visualizzare e gestire le richieste pull
- Migliorare la qualità del codice con i criteri del ramo
- Informazioni sulle richieste pull
- Informazioni sui rami protetti
Fase 2: pipelines come codice
Lo spostamento della pipeline come codice ha accelerato l'adozione dell'automazione e le distribuzioni spostando le definizioni e le configurazioni della pipeline dal fornitore di CI agli sviluppatori, avvicinando la logica di compilazione e distribuzione alla logica dell'applicazione corrispondente. La maggiore flessibilità in questo caso comporta anche maggiori responsabilità.
Le verifiche del Controllo degli accessi in base al ruolo in una pipeline basata sull'interfaccia utente possono impedire ai singoli utenti di apportare modifiche distruttive. Tuttavia, le pipeline come codice vengono spesso eseguite con identità con privilegi e, se richiesto, possono eliminare definitivamente i carichi di lavoro.
Fase 3: proteggere le credenziali di distribuzione
Le pipeline e i repository di codice non devono includere credenziali e segreti hardcoded. Le credenziali e i segreti devono essere archiviati altrove e usare le funzionalità del fornitore di CI per la sicurezza. Poiché le pipeline vengono eseguite come agenti headless, non devono mai usare la password di un utente. Le pipeline devono essere eseguite usando entità di sicurezza headless, ad esempio entità servizio o identità gestite. Anche l'accesso alle credenziali di questa entità di sicurezza, alle stringhe di connessione del database e alle chiavi API di terze parti deve essere gestito in modo sicuro nella piattaforma CI.
La modalità di protezione delle credenziali, le attività di controllo e le approvazioni sono funzionalità specifiche del fornitore. Quando si sceglie una piattaforma CI, assicurarsi che supporti tutte le funzionalità necessarie.
Azure Pipelines è una soluzione di integrazione continua su scala aziendale in cui le credenziali vengono archiviate come connessioni al servizio, su cui è possibile configurare approvazioni e controlli. Questa configurazione include l'approvazione manuale e autorizzazioni specifiche per il ramo o la pipeline.
Azure Key Vault
Se la piattaforma CI lo supporta, è consigliabile archiviare le credenziali in un archivio di segreti dedicato, ad esempio Azure Key Vault. Le credenziali vengono recuperate in fase di esecuzione dall'agente di compilazione e la superficie di attacco si riduce.
Fase 4: protezione delle risorse di Azure
Le risorse di Azure devono essere protette in base al principio dei privilegi minimi, applicato sia alle autorizzazioni che all'ambito.
Per altre informazioni, vedi:
Procedure consigliate per il controllo degli accessi in base al ruolo di Azure
Che cos'è il controllo degli accessi in base al ruolo di Azure?
Creare ruoli personalizzati per gli agenti di compilazione
L'automazione CI/CD si applica non solo alle applicazioni, ma anche all'infrastruttura. I modelli di infrastruttura come codice garantiscono distribuzioni coerenti e consentono la scalabilità centralizzata dei team della piattaforma cloud.
È importante comprendere che l'automazione dell'infrastruttura come codice può presentare errori. Può essere configurata in modo errato e, negli scenari peggiori, eliminare definitivamente l'infrastruttura. Quando si pianifica il percorso cloud, individuare in anticipo le operazioni business critical e richiedere l'intervento umano.
Ad esempio, i blocchi di gestione cannot-delete potrebbero essere applicati a risorse business critical come i dati. Per evitare che ciò accada, è possibile rimuovere Microsoft.Authorization/*/Delete
le autorizzazioni da un'entità servizio usata nell'automazione CI. In questo esempio e caso d'uso, l'entità servizio può creare il blocco di gestione, ma non eliminarlo.
È consigliabile creare un ruolo personalizzato per gli agenti CI. Tenere presente che le esecuzioni degli agenti di compilazione sono headless e gli agenti headless non sono autonomi. Scegliere con attenzione le autorizzazioni.
Per altre informazioni, vedere:
Risorse
- Automazione della piattaforma e DevOps
- Procedura dettagliata sulla protezione delle pipeline
- Sicurezza tramite i modelli
- DevSecOps in GitHub
Passaggi successivi
Dopo aver compreso come proteggere DevOps, approfondire la governance end-to-end da DevOps ad Azure.