Proteggere repository e pipeline

Completato

Quando si usa l'automazione per distribuire l'infrastruttura, la pipeline e il repository acquistano un'enorme importanza, in quanto ora rappresentano l'unico modo in cui le modifiche vengono applicate agli ambienti controllati.

Molte parti dell'organizzazione Azure DevOps, del repository GitHub e delle pipeline devono essere protette. La tabella seguente contiene alcuni degli elementi più importanti da proteggere, insieme a esempi di vulnerabilità che potrebbero verificarsi se questi elementi non vengono protetti in modo adeguato.

Elemento da proteggere Esempio di vulnerabilità
L'organizzazione Azure DevOps o il repository GitHub, inclusi gli utenti autorizzati ad accedervi e le azioni che sono autorizzati a eseguire. Un ex dipendente scontento elimina il repository del codice.
Rami importanti del repository e cosa deve accadere per modificare il codice in tali rami. Qualcuno esegue accidentalmente il commit di un codice Bicep non sicuro nel ramo principale del repository.
Il codice all'interno del repository, inclusi definizioni dell'infrastruttura, test e codice dell'applicazione. Qualcuno dimentica di testare il codice scritto e questo non funziona correttamente quando viene rilasciato in produzione.
Definizione della pipeline. Qualcuno aggiunge inavvertitamente un passaggio della pipeline che scrive una stringa di connessione del database nel log della pipeline.
Gli agenti o gli strumenti di esecuzione che eseguono la pipeline. Una pipeline in esecuzione in una bozza di richiesta di pull installa nell'agente una vulnerabilità di sicurezza, che viene successivamente utilizzata per una distribuzione di produzione.
Eventuali attività o componenti di terze parti che potrebbero essere eseguiti all'interno della pipeline. Un'attività di pipeline di terze parti invia le credenziali dell'entità servizio a un sito Web dannoso.
Le entità servizio usate dalla pipeline per accedere ad Azure. Un'entità servizio non di produzione apporta accidentalmente una modifica all'ambiente di produzione.
I segreti usati dalla pipeline per accedere a sistemi esterni. Un membro del team scrive un nuovo file di definizione della pipeline per un prototipo e lo connette accidentalmente all'ambiente di produzione.

Vediamo ora alcuni approcci che è possibile adottare per applicare governance e controlli al repository del codice e alle pipeline di distribuzione, in Azure DevOps e in GitHub.

Gestire utenti e autorizzazioni

Considerare il modo in cui concedere l'accesso all'organizzazione Azure DevOps o al repository GitHub. Riflettere su chi dispone dell'accesso e cosa può fare.

È consigliabile usare l'istanza di Microsoft Entra dell'organizzazione come provider di identità della pipeline. In questo modo è possibile assicurarsi che ogni volta che qualcuno si unisce o lascia l'organizzazione, l'accesso alla pipeline venga concesso o revocato automaticamente. Con Microsoft Entra ID è anche possibile implementare facilmente protezioni come l'accesso condizionale e l'autenticazione a più fattori.

Nota

Per usare l'integrazione di Microsoft Entra con GitHub, l'organizzazione deve disporre di una licenza GitHub Enterprise.

È anche possibile creare team (in GitHub) o gruppi (in Azure DevOps), che rappresentano set di utenti a cui è possibile concedere le autorizzazioni insieme. In questo modo, non è necessario assegnare le autorizzazioni singolarmente. È facile modificare le autorizzazioni degli utenti aggiungendoli e rimuovendoli da un team o un gruppo.

Suggerimento

Azure DevOps usa un modello di autorizzazione con privilegi minimi, diverso dal modello usato da Azure. In Azure DevOps le autorizzazioni di rifiuto sostituiscono le autorizzazioni di concessione. Questo significa che, se si è assegnati a più gruppi con set di autorizzazioni diversi, è possibile eseguire solo le azioni consentite da tutti i gruppi.

Assicurarsi di comprendere come vengono assegnate le autorizzazioni, in particolare ai gruppi.

Proteggere i rami di codice importanti

Le pipeline e l'automazione devono essere basate sull'identificazione di specifici rami di codice, come main. Il codice di questi rami designati è generalmente attendibile e può essere distribuito agli ambienti di produzione. Applicare i controlli per assicurarsi che il codice presente nei rami importanti sia stato verificato ed esaminato.

Prendere in considerazione la possibilità di usare le regole di protezione dei rami (in GitHub) o i criteri di ramo (in Azure Repos) per impedire il commit diretto a rami di codice importanti. È quindi possibile richiedere al team di usare le richieste di pull per unire le modifiche. Prima dell'unione, è possibile applicare controlli automatizzati e processi di revisione manuale per verificare che le modifiche siano valide.

Testare e rivedere il codice

Assicurarsi che il team comprenda le aspettative relative alla revisione e al test di tutto il codice, incluse le definizioni dell'infrastruttura.

Le definizioni della pipeline sono file YAML, quindi sono una forma di codice. Le modifiche alle definizioni di pipeline devono essere riviste e valutate. In caso contrario, qualcuno potrebbe creare inavvertitamente o in modo dannoso un passaggio della pipeline che divulga le credenziali dell'entità servizio o apporta una modifica pericolosa alla proprietà di Azure.

Le eventuali modifiche apportate ai file di definizione della pipeline devono essere esaminate in modo approfondito. Assicurarsi che tutti i membri del team comprendano che le pipeline sono altamente privilegiate e necessitano di particolare attenzione.

Proteggere gli agenti e gli strumenti di esecuzione delle pipeline

La pipeline viene eseguita in agenti (per Azure Pipelines) o strumenti di esecuzione (per GitHub Actions). Agenti e strumenti di esecuzione possono essere considerati macchine virtuali. La definizione della pipeline controlla tali macchine virtuali eseguendo le attività e gli script forniti.

Sia Azure Pipelines che GitHub Actions forniscono agenti e strumenti di esecuzione ospitati, configurati e gestiti da Microsoft o GitHub. Il proprietario della piattaforma configura i computer in modo che siano conformi alle procedure di sicurezza consigliate. Le responsabilità del proprietario della piattaforma includono l'applicazione di patch alle vulnerabilità del sistema operativo.

È invece possibile scegliere di usare le proprie macchine fisiche o virtuali per gli agenti e gli strumenti di esecuzione. I computer di questo tipo sono denominati strumenti di esecuzione e agenti self-hosted. Se si usano strumenti di esecuzione e agenti self-hosted, è responsabilità dell'utente verificare che i computer siano configurati correttamente e protetti dalle minacce.

Gli agenti ospitati da Microsoft e gli strumenti di esecuzione ospitati da GitHub sono effimeri. Tutti i file o le modifiche alla configurazione apportate a un agente o uno strumento di esecuzione vengono eliminati definitivamente al termine dell'esecuzione di una pipeline. Se usa un agente o uno strumento di esecuzione self-hosted, è probabile che lo stesso computer venga usato per più pipeline o ambienti separati, inclusi gli ambienti di produzione e non di produzione. Si supponga che qualcuno crei una definizione di pipeline che modifichi alcuni file importanti nel sistema operativo dell'agente ed esegua la pipeline da una richiesta di pull. La volta successiva che viene eseguita una distribuzione nell'ambiente di produzione, l'agente potrebbe essere riutilizzato. Ora non è possibile prevedere quale potrebbe essere l'impatto del file danneggiato sull'ambiente di produzione.

Per questi motivi, è consigliabile usare agenti ospitati da Microsoft e strumenti di esecuzione ospitati da GitHub ogni volta che è possibile. Se è necessario usare strumenti di esecuzione self-hosted, valutare attentamente i rischi associati alla configurazione e all'uso.

Valutare i componenti di terze parti eseguiti all'interno della pipeline

Se vengono usate estensioni GitHub Actions o Azure DevOps fornite dalla community, è possibile capire da chi sono state create e cosa fanno. I componenti della pipeline di terze parti potrebbero avere accesso alle credenziali dell'entità servizio e quindi all'intero ambiente in Azure.

In Azure DevOps, in genere l'amministratore dell'organizzazione approva ogni estensione prima che possa essere usata. Se si è l'amministratore dell'organizzazione, considerare il rischio per la sicurezza associato a ogni componente che viene usato. L'amministratore ha la responsabilità di verificare che i componenti siano affidabili e sicuri.

Ogni volta che si usa un'azione o un'attività di terze parti, specificare la versione. Prendere in considerazione la possibilità di specificare la versione esatta esaminata. Se si consente alla pipeline di usare automaticamente una versione successiva, si potrebbe comportare un rischio che non è stato esaminato.

Proteggere le entità servizio della pipeline

Le pipeline usano le entità servizio per accedere ad Azure e ad altri servizi. È importante proteggere le entità servizio e assicurarsi che le credenziali non possano essere usate in modo inappropriato. Valutare l'applicazione di più livelli di protezione.

Prima di tutto, è possibile prendere in considerazione di proteggere le credenziali per le entità servizio:

  • Ogni volta che è possibile, usare identità gestite o identità del carico di lavoro per evitare di archiviare completamente le credenziali. Anche se non è possibile usare identità gestite o identità del carico di lavoro con tutte le pipeline, è consigliabile farlo quando si riesce.
  • Pianificare il modo in cui si modificheranno o si ruoteranno le credenziali dell'entità servizio regolarmente. Ad esempio, l'organizzazione potrebbe avere un criterio che prevede di ruotare le credenziali ogni 90 o 120 giorni. Riflettere su chi sarà responsabile della rotazione e come verranno aggiornate tutte le posizioni in cui vengono usate le credenziali.
  • Valutare di progettare un custode segreto il cui ruolo è gestire segreti, chiavi e certificati in modo che non siano esposti ad altre parti dell'organizzazione.

Considerare quindi le autorizzazioni concesse alle entità servizio:

  • Applicare i criteri di accesso condizionale di Microsoft Entra alle entità servizio della pipeline. Questi criteri aiutano a identificare gli accessi e i comportamenti rischiosi. Ad esempio, se le entità servizio della pipeline accedono sempre da un'area geografica, l'accesso condizionale può rilevare e impedire gli accessi da posizioni impreviste, che potrebbero indicare che le credenziali sono state compromesse.
  • Valutare con attenzione le autorizzazioni che vengono concesse a ogni entità servizio. Si supponga, ad esempio, di avere un'entità servizio che viene usata per leggere la configurazione di una risorsa condivisa. Considerare se è possibile concedere solo l'accesso di lettore a tale entità servizio, perché l'entità servizio non deve eseguire alcuna operazione che richieda più privilegi.
  • Usare l'ambito minimo per ogni autorizzazione che si assegna a un'entità servizio. Ad esempio, se l'entità servizio deve essere distribuita a un solo gruppo di risorse, definire l'ambito dell'assegnazione del ruolo a tale gruppo di risorse invece che all'intero abbonamento.
  • Usare entità servizio separate per ogni ambiente. In questo modo, anche se le credenziali di un'entità vengono compromesse o se qualcuno ottiene l'accesso a un ambiente, non può accedere ad altri ambienti.

Proteggere le connessioni del servizio e i segreti

Una connessione del servizio (in Azure Pipelines) o un segreto (in GitHub) contiene le credenziali dell'entità servizio usata dalla pipeline per accedere all'ambiente Azure. È importante proteggere le connessioni del servizio e i segreti e controllare quali pipeline usano ogni connessione del servizio e ogni segreto. In caso contrario, si rischia di consentire accidentalmente a un ambiente non di produzione di usare un'entità servizio con accesso alle risorse di produzione.

In Azure DevOps, quando si crea una connessione del servizio, è possibile configurarla in modo da richiedere l'approvazione prima che una nuova pipeline o un nuovo ambiente possa usarla.

Azure DevOps consente anche di associare controlli a connessioni del servizio specifiche. I controlli aggiungono un altro livello di protezione. Ad esempio, è possibile configurare un controllo su una connessione del servizio di produzione in modo da verificare che venga usata solo sul codice del ramo principale del repository. Questo controllo impedisce la distribuzione di codice non autorizzato nell'ambiente di produzione.

In GitHub è possibile configurare segreti specifici dell'ambiente in modo che, quando il flusso di lavoro GitHub Actions viene eseguito in tale ambiente, fornisca solo il valore del segreto. Usando segreti specifici dell'ambiente e controlli dell'ambiente come le approvazioni, si può ridurre il rischio che venga usata una distribuzione non di produzione per la distribuzione all'ambiente di produzione. È anche possibile usare le identità del carico di lavoro per evitare di usare credenziali nei flussi di lavoro di GitHub Actions ed eliminare la possibilità che le credenziali possano essere esposte.

Usare le funzionalità di sicurezza di GitHub

GitHub offre funzionalità di sicurezza che è consigliabile valutare e usare. Queste funzionalità sono:

  • Dependabot, che analizza le dipendenze del codice sorgente alla ricerca di vulnerabilità note.
  • Analisi segreta, che identifica il testo ne repository che ha l'aspetto di chiavi o credenziali. Archiviare segreti in un repository è una procedura sconsigliata. Se si viene avvisati di un segreto nel repository, è consigliabile considerare il valore del segreto che può essere compromesso, quindi revocarlo o modificarlo.
  • Controllo, per capire chi ha apportato modifiche alla configurazione di GitHub.
  • Panoramica della sicurezza, che consolida tutti gli avvisi di sicurezza in tutti i repository dell'organizzazione.

Usare i log di controllo di Azure DevOps

Azure DevOps fornisce log di controllo per aiutare a capire chi ha apportato modifiche alle pipeline, ai criteri del ramo, ai repository e ad altre risorse. È consigliabile abilitare il controllo e rivedere regolarmente i log di controllo.

Proteggere il repository e la pipeline

Sono stati illustrati i controlli importanti che è possibile applicare al repository e alla pipeline. A questo punto si vedrà quali controlli è possibile usare per proteggere ognuno degli elementi importanti elencati in precedenza in questa unità:

Elemento da proteggere Controlli da applicare
L'organizzazione Azure DevOps o il repository GitHub, inclusi gli utenti autorizzati ad accedervi e le azioni che sono autorizzati a eseguire.
  • Usare Microsoft Entra ID per l'autenticazione.
  • Usare team e gruppi per assegnare le autorizzazioni.
  • Abilitare la registrazione di controllo ed esaminare regolarmente i log di controllo.
Rami importanti del repository e cosa deve accadere per modificare il codice in tali rami. Applicare regole di protezione dei rami o criteri di ramo.
Il codice all'interno del repository, inclusi definizioni dell'infrastruttura, test e codice dell'applicazione.
  • Applicare i requisiti per la revisione del codice.
  • Aggiungere test automatizzati o manuali.
  • In GitHub usare Dependabot e l'analisi segreta.
Definizione della pipeline. Applicare i requisiti per la revisione del codice.
Gli agenti o gli strumenti di esecuzione che eseguono la pipeline.
  • In Azure Pipelines usare gli agenti ospitati da Microsoft.
  • In GitHub Actions usare gli strumenti di esecuzione ospitati da GitHub.
Eventuali attività o componenti di terze parti che potrebbero essere eseguiti all'interno della pipeline. Esaminare i rischi per la sicurezza associati a tutte le estensioni e le attività di terze parti.
Le entità servizio usate dalla pipeline per accedere ad Azure.
  • Usare le identità del carico di lavoro in GitHub Actions. Per Azure Pipelines usare le entità servizio e ruotare regolarmente le credenziali.
  • Usare entità servizio separate per ogni ambiente.
  • Applicare i criteri di accesso condizionale.
I segreti usati dalla pipeline per accedere a sistemi esterni.
  • In Azure DevOps usare le approvazioni e i controlli sulle connessioni del servizio.
  • In GitHub usare segreti specifici dell'ambiente e identità del carico di lavoro.