Proteggere le build

Questo documento descrive le best practice per proteggere le build. Il codice di costruzione può fare riferimento a diversi tipi di operazioni, ad esempio:

  • Ottimizzazione o offuscamento del codice: ad esempio, lo strumento open source di Google Closure Compiler analizza e analizza JavaScript, rimuove il codice inutilizzato e riscrivi e riduci al minimo ciò che rimane. Inoltre, controlla la presenza di errori comuni di JavaScript nel codice.
  • Compilazione del codice in codice intermedio: ad esempio, puoi compilare il codice Java in un file di classe Java (.class) o il codice C++ in un file oggetto (.obj).
  • Compilazione del codice e collegamento, creazione di una libreria o di un file eseguibile: ad esempio, compilation del codice C++ in una libreria condivisa (.so) o in un file eseguibile Windows (.exe).
  • Imballaggio del codice in un formato distribuibile o di cui è possibile eseguire il deployment: ad esempio, la creazione di file WAR (.war) Java da file di classi Java, la creazione di un'immagine Docker o la creazione di una distribuzione compilata in Python (.whl).

A seconda del linguaggio di programmazione utilizzato e dell'ambiente in cui esegui il deployment, la compilazione potrebbe contenere combinazioni diverse di queste operazioni. Ad esempio, una build potrebbe pacchettizzare il codice Python in una distribuzione compilata e caricarla in un archivio di elementi come Artifact Registry o PyPI in modo da poterlo utilizzare come dipendenza nelle funzioni Cloud Run. Puoi anche eseguire il containerizzazione del codice Python ed eseguire il deployment dell'immagine del container in Cloud Run o Google Kubernetes Engine.

Le pratiche descritte in questo documento si concentrano sulla creazione di codice per la pacchettizzazione o il deployment in ambienti di runtime anziché sulla compilazione del codice.

Utilizzare le build automatiche

Una build automatica o build basata su script definisce tutti i passaggi di compilazione nello script di compilazione o nella configurazione di compilazione, inclusi i passaggi per recuperare il codice sorgente e quelli per compilare il codice. L'unico comando manuale, se presente, è il comando per eseguire la compilazione.

Ad esempio, uno script di compilazione può essere:

  • Un progetto Cloud Build cloudbuild.yaml.
  • Un file Makefile che esegui con lo strumento make.
  • Un file di flusso di lavoro GitHub Actions in formato YAML archiviato nella directory.github/workflows/.

Le build automatiche garantiscono la coerenza dei passaggi di compilazione. Tuttavia, è importante anche eseguire le build in un ambiente coerente e attendibile.

Sebbene le build locali possano essere utili per il debug, il rilascio di software da build locali può introdurre molti problemi di sicurezza, incoerenze e inefficienze nel processo di compilazione.

  • La possibilità di eseguire build locali offre a un utente malintenzionato un modo per modificare il processo di compilazione.
  • Le incoerenze negli ambienti locali e nelle pratiche degli sviluppatori rendono difficile riprodurre le build e diagnosticare i problemi di build.

Le build manuali rendono il processo inefficiente sfruttando più risorse di infrastruttura come calcolo, archiviazione e reti. Nei requisiti del framework SLSA, le build automatiche sono un requisito per il livello 1 di SLSA e l'utilizzo di un servizio di build anziché di ambienti sviluppatore per le build è un requisito per il livello 2 di SLSA.

Cloud Build è il servizio di build gestito su Google Cloud. Utilizza un file di configurazione della build per fornire i passaggi di compilazione a Cloud Build. Puoi configurare le build per recuperare le dipendenze, eseguire test delle unità, analisi statiche e test di integrazione e creare artefatti con strumenti di build come Docker, Gradle, Maven, Go e Python. Cloud Build è completamente integrato con altri servizi CI/CD su Google Cloud, come Artifact Registry e Cloud Deploy, nonché con ambienti di runtime come GKE e Cloud Run. Fornisce inoltre l'integrazione con i principali sistemi di gestione del codice sorgente come GitHub e Bitbucket.

Genera la provenienza della build

La provenienza della build è una raccolta di dati verificabili su una build.

I metadati della provenienza includono dettagli come i digest delle immagini create, le posizioni delle origini di input, la toolchain di compilazione e la durata della compilazione.

La generazione dell'origine della build ti consente di:

  • Verifica che un elemento compilato sia stato creato da una posizione della sorgente attendibile e da un sistema di compilazione attendibile.
  • Identificare il codice iniettato da una posizione di origine o da un sistema di compilazione non attendibile.

Puoi utilizzare i meccanismi di avviso e dei criteri per utilizzare in modo proattivo i dati sulla provenienza della compilazione. Ad esempio, puoi creare criteri che consentano solo il deployment di codice compilato da origini verificate.

Per il livello SLSA 1, l'origine della compilazione deve essere disponibile per i consumatori degli elementi compilati. Per il livello 2 di SLSA, i dati sulla provenienza della compilazione devono inoltre:

  • Generati dal servizio di build o leggibili direttamente dal servizio di build.
  • Verificabile da un consumatore per verificarne l'autenticità e l'integrità. Questa operazione deve essere eseguita con una firma digitale generata dal servizio che crea i dati sull'origine della build.

Per il livello 3 di SLSA, i contenuti di provenienza devono includere anche:

  • Il punto di contatto della definizione di build.
  • Tutti i parametri di compilazione sotto il controllo di un utente.

Cloud Build può generare la provenienza della build per le immagini container che forniscono la garanzia di build SLSA di livello 3. Per ulteriori informazioni, consulta la sezione Visualizzare la provenienza della compilazione.

Utilizzare un ambiente di compilazione temporaneo

Gli ambienti effimeri sono ambienti temporanei pensati per durare per una singola chiamata di compilazione. Dopo la compilazione, l'ambiente viene resettato o eliminato. Le build effimere assicurano che il servizio di compilazione e i relativi passaggi vengano eseguiti in un ambiente effimero, ad esempio un contenitore o una VM. Anziché riutilizzare un ambiente di build esistente, il servizio di build esegue il provisioning di un nuovo ambiente per ogni build e poi lo elimina al termine del processo di compilazione.

Gli ambienti effimeri garantiscono build pulite perché non sono presenti file residuali o impostazioni dell'ambiente delle build precedenti che possono interferire con il processo di compilazione. Un ambiente non effimero offre agli aggressori l'opportunità di inserire file e contenuti dannosi. Un ambiente effimero riduce inoltre i costi generali di manutenzione e le incoerenze nell'ambiente di compilazione.

Cloud Build configura un nuovo ambiente di macchine virtuali per ogni compilazione ed elimina l'ambiente al termine della compilazione.

Limitare l'accesso al servizio di compilazione

Rispetta il principio di sicurezza del privilegio minimo concedendo le autorizzazioni minime necessarie al servizio di compilazione e alle risorse di compilazione. Dovresti anche utilizzare un'identità non umana per eseguire le build e interagire con altri servizi per conto della build.

Se utilizzi Cloud Build:

  • Concedi le autorizzazioni minime richieste ai membri della tua organizzazione.
  • Personalizza le autorizzazioni per l'account di servizio che agisce per conto di Cloud Build in modo che disponga solo delle autorizzazioni necessarie per il tuo utilizzo. Modifica le autorizzazioni dell'account di servizio Cloud Build predefinito o valuta la possibilità di utilizzare un account di servizio personalizzato.
  • Utilizza il criterio dell'organizzazione Integrazioni consentite di Cloud Build per controllare i servizi esterni che possono invocare gli attivatori di build.
  • Inserisci Cloud Build in un perimetro di servizio utilizzando Controlli di servizio VPC. Il perimetro consente la libera comunicazione tra i servizi Google Cloud all'interno del perimetro, ma limita la comunicazione all'esterno del perimetro in base alle regole specificate. Il perimetro riduce anche il rischio di esfiltrazione di dati.

    Cloud Build supporta i Controlli di servizio VPC solo per le build eseguite in un pool privato.

Proteggere le credenziali

Le build spesso includono connessioni ad altri sistemi come il controllo della versione, i depositi di elementi e gli ambienti di deployment. La protezione delle credenziali che utilizzi nelle build contribuisce a impedire l'accesso non autorizzato ai sistemi della catena di fornitura del software e l'esfiltrazione dei dati.

Evita di memorizzare le credenziali hardcoded direttamente nel controllo versione o nella configurazione di compilazione. Memorizza invece le credenziali in un keystore sicuro.

In Google Cloud, Secret Manager archivia in modo sicuro chiavi API, password e altri dati sensibili. Puoi configurare Cloud Build in modo da utilizzare i secret archiviati in Secret Manager.

Gestire le dipendenze

L'integrità delle tue applicazioni si basa sull'integrità sia del codice sviluppato sia delle eventuali dipendenze utilizzate. Devi anche considerare dove pubblichi le dipendenze, chi ha accesso in lettura e scrittura ai tuoi repository di artefatti e i criteri per le origini attendibili degli artefatti di compilazione che esegui il deployment negli ambienti di runtime.

Per scoprire di più sulla gestione delle dipendenze, consulta Gestire le dipendenze.

In Cloud Build, utilizzi i comandi cloud per eseguire i comandi. I builder sono immagini container in cui sono installati linguaggi e strumenti comuni. Puoi utilizzare immagini container pubbliche da registri pubblici come Docker Hub, builder forniti da Cloud Build, builder forniti dalla community e builder personalizzati che crei. Puoi anche utilizzare i buildpacks come builder, inclusi i buildpack di Google Cloud.

Esamina i builder che utilizzi nelle build di Cloud Build, scopri chi li fornisce e decidi se ritieni che siano attendibili nella tua catena di approvvigionamento del software. Per mantenere un maggiore controllo sul codice in un generatore, puoi creare generatori personalizzati anziché utilizzare quelli provenienti da una fonte pubblica.

Riduci le opportunità di modificare la compilazione

Esistono diversi altri fattori che possono influire su una build, tra cui:

  • Build che vengono eseguite contemporaneamente e sono in grado di influenzarsi a vicenda oppure una build che persiste e influisce su una build successiva.
  • Build che accettano parametri utente diversi dal punto di contatto della build e dalla posizione della fonte di primo livello.
  • Build che specificano dipendenze con intervalli o dipendenze immutabili, ad esempio l'utilizzo di un'immagine con il tag latest. Questi metodi comportano il rischio che le build utilizzino versioni errate o indesiderate delle dipendenze.

Le seguenti pratiche contribuiscono a mitigare questi rischi:

  • Esegui ogni build in un ambiente temporaneo.
  • Evita di eseguire build con parametri aggiuntivi in modo che gli utenti non possano influenzare le variabili definite negli script di compilazione.
  • Limita l'accesso al servizio di compilazione e alle risorse di compilazione.
  • Fai riferimento a versioni immutabili delle dipendenze anziché a identificatori come i tag che in futuro possono puntare a una versione diversa dell'elemento. Per ulteriori informazioni sulle dipendenze, consulta Gestione delle dipendenze.

Sicurezza della catena di fornitura del software

Google Cloud fornisce un insieme di funzionalità e strumenti modulari che puoi utilizzare per migliorare la security posture delle tue supply chain di software. Mostra insight sulla sicurezza per le applicazioni create da Cloud Build. È incluso quanto segue:

  • Il livello SLSA, che identifica il livello di maturità della sicurezza della catena di fornitura del software.
  • Vulnerabilità, bill of materials (SBOM) del software e dichiarazioni Vulnerability Exploitability eXchange (VEX) per gli artefatti di compilazione.
  • La provenienza della build, ovvero una raccolta di metadati verificabili su una build. Sono inclusi dettagli come i digest delle immagini create, le località delle origini di input, la toolchain di build, i passaggi di build e la durata della build.

Per istruzioni su come visualizzare gli insight sulla sicurezza per le applicazioni create, consulta Creare un'applicazione e visualizzare insight sulla sicurezza.

Passaggi successivi