Questi contenuti sono stati aggiornati l'ultima volta a settembre 2023 e rappresentano lo status quo al momento della loro redazione. Criteri e sistemi di sicurezza di Google possono variare in futuro, in virtù del costante miglioramento della protezione per i nostri clienti.
Questo documento descrive come utilizziamo le revisioni del codice, l'infrastruttura di sicurezza e un controllo dell'applicazione chiamato Autorizzazione binaria per Borg (BAB) per proteggere la catena di fornitura del software di Google dai rischi provenienti da personale interno. BAB aiuta a ridurre i rischi provenienti da addetti ai lavori perché garantisce che il software di produzione venga esaminato e approvato prima del deployment, in particolare quando il nostro codice può accedere a dati sensibili. Dalla pubblicazione originale del presente documento, abbiamo incluso i concetti chiave di BAB in una specifica aperta denominata Supply chain Levels for Software Artifacts (SLSA).
Questo documento fa parte di una serie di articoli tecnici che descrivono alcuni progetti sviluppati dal team di sicurezza di Google per migliorare la sicurezza, tra cui BeyondCorp e BeyondProd. Per una panoramica della sicurezza della nostra infrastruttura, consulta la panoramica sulla progettazione della sicurezza dell'infrastruttura Google.
Introduzione
I rischi legati agli addetti ai lavori rappresentano una minaccia alla sicurezza dei dati degli utenti, che possono includere dati sull'occupazione, dati finanziari o altri dati proprietari o aziendali. I rischi legati agli addetti ai lavori sono la possibilità che un dipendente utilizzi le proprie conoscenze o il proprio accesso all'organizzazione per eseguire atti dannosi o che un utente malintenzionato esterno utilizzi le credenziali compromesse di un dipendente per fare lo stesso.
Per ridurre al minimo i rischi provenienti da addetti ai lavori all'interno della nostra catena di fornitura del software, utilizziamo BAB. BAB è un controllo di applicazione interno che viene eseguito durante il deployment del software. BAB garantisce che i deployment di codice e configurazione soddisfino determinati standard minimi e supporti l'uniformità nei nostri sistemi di produzione.
Contribuiamo a proteggere i dati utente all'interno dei nostri sistemi di produzione impedendo l'accesso unilaterale da parte dei nostri dipendenti. BAB aiuta a garantire che i dipendenti, mentre agiscono da soli, non possano accedere direttamente o indirettamente ai dati utente o influenzarli in altro modo senza un'autorizzazione e una giustificazione adeguate. BAB e i controlli associati ci aiutano a applicare il privilegio minimo, che migliora la nostra strategia di sicurezza indipendentemente da uno specifico attore della minaccia. In altre parole, BAB impedisce l'accesso unilaterale, indipendentemente dal fatto che l'autore abbia intento dannoso, che il suo account sia stato compromesso o che gli sia stato involontariamente concesso l'accesso.
Vantaggi di BAB
L'adozione di BAB e di un modello di deployment containerizzato offre molti vantaggi in termini di sicurezza all'infrastruttura di Google. I vantaggi includono:
- BAB aiuta a ridurre i rischi complessivi provenienti da addetti ai lavori: BAB richiede che il codice soddisfi determinati standard e pratiche di gestione dei cambiamenti prima che il codice possa accedere ai dati utente. Questo requisito riduce la possibilità che un dipendente che agisca per conto suo (o che un account del dipendente sia compromesso) di accedere ai dati utente in modo programmatico.
- BAB supporta l'uniformità dei sistemi di produzione: utilizzando sistemi containerizzati e verificando i relativi requisiti BAB prima del deployment, i nostri sistemi diventano più facili da eseguire il debug, più affidabili e hanno processi di gestione dei cambiamenti ben definiti. I requisiti BAB forniscono un linguaggio comune per i requisiti del sistema di produzione.
- BAB determina un linguaggio comune per la protezione dei dati: BAB monitora la conformità nei sistemi Google. I dati relativi a questa conformità sono pubblicati internamente e sono disponibili per altri team. La pubblicazione dei dati BAB consente ai team di utilizzare termini comuni nelle comunicazioni tra loro relative alla protezione dell'accesso ai dati. Questo linguaggio comune riduce il lavoro continuativo necessario quando si lavora con i dati tra team.
- BAB consente il monitoraggio programmatico dei requisiti di conformità: BAB semplifica quelle che in precedenza erano attività di conformità manuali. Alcune procedure in Google richiedono controlli più rigidi sulle modalità di trattamento dei dati. Ad esempio, i nostri sistemi di rapporti finanziari devono essere conformi al Sarbanes-Oxley Act (SOX). Prima di BAB, avevamo un sistema che ci aiutava a eseguire manualmente le verifiche per garantire la conformità. Con l'introduzione di BAB, molti di questi controlli sono stati automatizzati in base ai criteri BAB per i servizi. L'automazione di questi controlli ha consentito al team di conformità di ampliare sia l'ambito dei servizi coperti sia l'adozione di controlli appropriati su questi servizi.
BAB fa parte del più ampio framework BeyondProd che utilizziamo per mitigare i rischi provenienti da personale interno.
Il nostro processo di sviluppo e produzione
Il processo di sviluppo e produzione di Google prevede quattro passaggi obbligatori: revisione del codice, build verificabili, deployment containerizzato e identità basata sui servizi. Le seguenti sezioni descrivono questi passaggi in modo più dettagliato.
Passaggio 1: revisione del codice
La maggior parte del nostro codice sorgente è archiviata in un repository monolitico centrale, , che consente a migliaia di dipendenti di controllare il codice in un'unica posizione. Il codebase di Google semplifica la gestione del codice sorgente, in particolare la gestione delle nostre dipendenze da codice di terze parti. Un codebase monolitico consente inoltre l'applicazione di un singolo punto di passaggio obbligato per le revisioni del codice.
Le nostre revisioni del codice includono l'ispezione e l'approvazione di almeno un ingegnere diverso dall'autore. Come minimo, la nostra procedura di revisione del codice richiede che i proprietari di un sistema approvino le modifiche del codice al sistema. Il codice viene creato dopo essere stato registrato.
Quando importi modifiche da o da codice open source di terze parti, verifichiamo che la modifica sia appropriata (ad esempio, la versione più recente). Tuttavia, spesso non mettiamo in atto gli stessi controlli delle recensioni per ogni modifica apportata da sviluppatori esterni al codice di terze parti o open source che utilizziamo.
Passaggio 2: build verificabili
Il nostro sistema di compilazione è simile a Bazel, che crea e compila il codice sorgente per creare un programma binario per il deployment. Il nostro sistema di compilazione viene eseguito in un ambiente isolato e bloccato , separato dai dipendenti che eseguono le build. Per ogni build, il sistema produce la provenienza generata da build verificabili . Questa provenienza è un certificato firmato che descrive le origini e le dipendenze inserite nella build, gli hash di crittografia di eventuali programmi binari o altri artefatti della build e i parametri completi della build. Questa provenienza consente quanto segue:
- La capacità di tracciare un programma binario al codice sorgente utilizzato nella sua creazione. Per estensione, la provenienza può anche tracciare il processo di creazione e invio del codice sorgente descritto.
- Possibilità di verificare che il programma binario non sia stato modificato poiché eventuali modifiche al file renderebbero automaticamente non valida la sua firma.
Poiché le azioni di build possono essere codice arbitrario, il nostro sistema di compilazione è stato protetto per l'architettura multi-tenancy. In altre parole, il nostro sistema di compilazione è progettato per impedire che una build influenzi le altre build. Il sistema impedisce alle build di apportare modifiche che potrebbero compromettere l'integrità della provenienza della build o del sistema stesso. Una volta completata la build, il deployment della modifica viene eseguito utilizzando Borg.
Passaggio 3: deployment containerizzato
Una volta creato dal sistema di compilazione, il programma viene pacchettizzato in un'immagine container e ne viene eseguito il deployment come job Borg nel nostro sistema di orchestrazione dei cluster, Borg. Eseguiamo centinaia di migliaia di job da molte applicazioni diverse, su più cluster, ciascuno con decine di migliaia di macchine. Nonostante la sua vasta scala, il nostro ambiente di produzione è abbastanza omogeneo. Di conseguenza, i touchpoint per l'accesso ai dati utente possono essere controllati e controllati più facilmente.
I container offrono notevoli vantaggi in termini di sicurezza. I container sono pensati per essere immutabili, con frequenti deployment da una rigenerazione completa dell'immagine. La containerizzazione ci consente di esaminare una modifica al codice nel contesto e fornisce un singolo punto di passaggio obbligato per tutte le modifiche di cui viene eseguito il deployment nella nostra infrastruttura.
La configurazione di un job Borg specifica i requisiti per il job di cui eseguire il deployment: immagini container, parametri di runtime, argomenti e flag. Borg pianifica il job, prendendo in considerazione i vincoli, la priorità, la quota e qualsiasi altro requisito del job elencato nella configurazione. Una volta eseguito il deployment, il job Borg può interagire con altri job in produzione.
Passaggio 4: identità basata sul servizio
Un job Borg viene eseguito come identità di servizio. Questa identità viene utilizzata per accedere a datastore o metodi di chiamata di procedura remota (RPC) di altri servizi. Più job possono essere eseguiti con la stessa identità. Solo i dipendenti responsabili dell'esecuzione del servizio (in genere SRE (Site Reliability Engineer))) possono eseguire il deployment o modificare i job con una particolare identità.
Quando Borg avvia un job, esegue il provisioning delle relative credenziali crittografiche. Il job utilizza queste credenziali per dimostrare la sua identità durante l'invio di richieste di altri servizi mediante Application Layer Transport Security (ALTS). Affinché un servizio possa accedere a determinati dati o a un altro servizio, la sua identità deve disporre delle autorizzazioni necessarie.
I nostri criteri richiedono la protezione BAB per le identità di servizio che hanno accesso ai dati utente e a qualsiasi altra informazioni sensibili. I job di sviluppo e controllo qualità che non hanno accesso a dati sensibili possono essere eseguiti con meno controlli.
Come funziona BAB
BAB si integra con Borg per garantire che solo i job autorizzati possano essere eseguiti con l'identità di ciascun servizio. BAB crea inoltre un audit trail del codice e della configurazione utilizzati nei job abilitati da BAB per consentire il monitoraggio e la risposta agli incidenti.
BAB è progettato per garantire che tutto il software di produzione e la configurazione vengano esaminati, registrati, creati in modo verificabile e autorizzati, in particolare quando il codice può accedere ai dati utente.
Criteri specifici per il servizio
Quando i proprietari del servizio eseguono l'onboarding del servizio in BAB, creano un criterio che definisce i requisiti di sicurezza del servizio. Questo criterio è chiamato criterio specifico per il servizio. La definizione o la modifica di un criterio è a sua volta una modifica al codice che deve essere sottoposta a revisione.
Il criterio specifico del servizio definisce il codice e la configurazione che possono essere eseguiti come identità del servizio, nonché le proprietà obbligatorie di quel codice e della configurazione. Tutti i job in esecuzione come identità di servizio devono soddisfare il criterio specifico del servizio.
Tutti i servizi di Google devono avere norme specifiche per il servizio. I servizi che accedono ai dati sensibili devono avere criteri sufficientemente solidi, mentre i servizi che non hanno accesso a dati sensibili potrebbero avere un criterio permissivo "Consenti tutto".
I criteri specifici per i servizi possono applicare i seguenti requisiti:
- Il codice deve essere controllabile: Possiamo risalire all'immagine container alle sue origini leggibili dalle persone mediante la provenienza generata da build verificabili. Le norme di conservazione mantengono le fonti leggibili del codice per almeno 18 mesi, anche se il codice non viene inviato.
- Il codice deve essere inviato: Il codice viene creato da una posizione specificata e definita nel nostro repository di codice sorgente. L'invio generalmente implica che il codice sia stato sottoposto a una revisione.
- Le configurazioni devono essere inviate: Tutte le configurazioni fornite durante il deployment passano attraverso lo stesso processo di revisione e invio del codice normale. Pertanto, i valori dei flag della riga di comando, gli argomenti e i parametri non possono essere modificati senza revisione.
I sistemi e i componenti che applicano BAB sono strettamente controllati mediante i requisiti automatici più severi possibili e controlli manuali aggiuntivi.
Modalità di applicazione
BAB utilizza due modalità di applicazione forzata per garantire che tutti i job siano conformi al criterio specifico del servizio:
- Applicazione forzata in fase di deployment, che blocca il deployment dei job non conformi.
- Convalida continua, che monitora e segnala i job non conformi di cui è stato eseguito il deployment.
Inoltre, in caso di emergenza, le procedure di risposta di emergenza possono bypassare l'applicazione forzata in fase di deployment.
Modalità di applicazione forzata in fase di deployment
Borg Prime è il controller centralizzato di Borg, che agisce come autorità di certificazione per il ALTS. Quando viene inviato un nuovo job, Borg Prime consulta BAB per verificare che quest'ultimo soddisfi i requisiti dei criteri specifici del servizio prima che Borg Prime conceda il certificato ALTS al job. Questo controllo agisce da controller di ammissione: Borg avvia il job solo se soddisfa il criterio specifico del servizio. Questo controllo si verifica anche se il dipendente o il servizio che richiede il deployment è altrimenti autorizzato.
In rari casi, i servizi possono disattivare l'applicazione forzata in fase di deployment con una giustificazione adeguata.
Modalità di verifica continua
Una volta eseguito il deployment, un job viene verificato continuamente per la sua durata, indipendentemente dalla modalità di applicazione forzata al momento del deployment. Un processo BAB viene eseguito almeno una volta al giorno per verificare che i job avviati (e potenzialmente ancora in esecuzione) siano conformi a eventuali aggiornamenti ai relativi criteri. Ad esempio, la modalità di verifica continua verifica costantemente la presenza di job in esecuzione con criteri obsoleti o di cui è stato eseguito il deployment utilizzando procedure di risposta di emergenza. Se un job non rispetta il criterio più recente, BAB invia una notifica ai proprietari del servizio in modo che possano mitigare il rischio.
Procedure di risposta di emergenza
Quando si verifica un incidente o un'interruzione, la nostra prima priorità è ripristinare il servizio interessato il prima possibile. In una situazione di emergenza, potrebbe essere necessario eseguire codice che non è stato rivisto o creato in modo verificabile. Di conseguenza, la modalità di applicazione forzata può essere ignorata utilizzando un flag di risposta di emergenza. Le procedure di risposta di emergenza fungono anche da backup nel caso in cui si verifichi un errore di BAB che altrimenti bloccherebbe un deployment. Quando uno sviluppatore esegue il deployment di un job utilizzando la procedura di risposta di emergenza, deve inviare una giustificazione come parte della richiesta.
Entro pochi secondi dall'utilizzo della procedura di risposta di emergenza, BAB registra i dettagli relativi al job Borg associato. Il log include il codice che è stato utilizzato e la motivazione fornita dall'utente. Pochi secondi dopo, viene inviato un audit trail al team per la sicurezza centralizzata di Google. Nel giro di poche ore, l'audit trail viene inviato al team proprietario dell'identità del lavoro. Le procedure di risposta di emergenza devono essere utilizzate solo come ultima possibilità.
Estensione di BAB ad altri ambienti
Inizialmente, BAB supportava solo la protezione dei job Borg e richiedeva che il software fosse sviluppato utilizzando la tradizionale pipeline di controllo del codice sorgente, build e pacchettizzazione di Google. Ora, BAB ha aggiunto il supporto per la protezione di altri ambienti di distribuzione e deployment del software e il supporto per sistemi alternativi di controllo del codice sorgente, build e pacchettizzazione. I dettagli di implementazione per questi vari ambienti sono diversi, ma i vantaggi di BAB rimangono.
Alcuni casi non si prestano bene alle revisioni del codice umano prima del deployment, in particolare lo sviluppo iterativo di codice di machine learning e l'analisi dei dati ad alta frequenza. In questi casi, disponiamo di controlli alternativi che compensano la revisione da parte di persone fisiche.
Adozione di controlli simili nella propria organizzazione
Questa sezione descrive le best practice che abbiamo imparato con l'implementazione di BAB in modo da poter adottare controlli simili nella tua organizzazione.
Crea una pipeline CI/CD containerizzata e omogenea
L'adozione di BAB è stata semplificata perché la maggior parte dei team utilizzava un sistema di controllo del codice sorgente, un processo di revisione del codice, sistema di compilazione e un sistema di deployment unici. Le revisioni del codice facevano già parte della nostra cultura, quindi siamo riusciti ad apportare modifiche senza troppe modifiche significative visibili agli utenti. Per adottare BAB, ci siamo concentrati su revisioni del codice, build verificabili, deployment containerizzati e identità basate sui servizi per il controllo dell'accesso. Questo approccio ha semplificato l'adozione di BAB e ha rafforzato le garanzie che una soluzione come BAB può fornire.
L'utilizzo diffuso di identità basate su microservizi e servizi (come gli account di servizio), anziché su identità basate su host (come gli indirizzi IP), ci consente di creare un controllo granulare sul software autorizzato a eseguire ciascun servizio.
Se la tua organizzazione non è in grado di adottare direttamente un'identità di servizio, puoi provare a proteggere i token di identità utilizzando altre misure come passaggio temporaneo.
Stabilisci i tuoi obiettivi e definisci le norme in base ai tuoi requisiti
Realizza il processo di release basato su criteri un passo alla volta. Potrebbe essere necessario implementare determinate modifiche prima di altre nella pipeline CI/CD. Ad esempio, potresti dover iniziare a eseguire revisioni formali del codice prima di poterle applicare al momento del deployment.
La conformità è un ottimo motivo che ne giustifica l'adozione di un processo di pubblicazione basato sulle norme. Se riesci a codificare almeno alcuni dei tuoi requisiti di conformità in un criterio, puoi automatizzare i test e assicurarti che siano sempre attivi. Inizia con un insieme di requisiti di base e codifica man mano i requisiti più avanzati.
Applica i criteri fin dalle prime fasi dello sviluppo
È difficile definire criteri completi su un software senza prima sapere dove verrà eseguito e a quali dati avrà accesso. Pertanto, l'applicazione di criteri specifici per il servizio viene eseguita quando viene eseguito il deployment del codice e quando questo accede ai dati, non durante la creazione. Un criterio viene definito in termini di identità di runtime, quindi lo stesso codice potrebbe essere eseguito in ambienti diversi ed essere soggetto a criteri diversi.
BAB viene utilizzato in aggiunta ad altri meccanismi di accesso per limitare l'accesso ai dati utente. I proprietari dei servizi possono inoltre garantire che i dati siano accessibili solo da un job che soddisfa specifici requisiti BAB.
Coinvolgere gli agenti del cambiamento nei vari team
Quando abbiamo creato un mandato per l'intera Google per il deployment di BAB, ciò che ha influito maggiormente sulla nostra percentuale di successo è stata trovare proprietari in grado di guidare il cambiamento in ogni gruppo di prodotti. Abbiamo identificato alcuni proprietari di servizi che hanno visto vantaggi immediati dall'applicazione delle norme e erano disposti a fornire feedback. Abbiamo chiesto a questi proprietari di offrirsi come volontari prima di rendere obbligatoria qualsiasi modifica. Dopo aver ricevuto il loro aiuto, abbiamo istituito un team di gestione dei cambiamenti formale per monitorare i cambiamenti in corso. Abbiamo quindi identificato proprietari responsabili in ciascun team di prodotto per implementare le modifiche.
Determinare come gestire il codice di terze parti
Se devi gestire il codice di terze parti, valuta come introdurre i requisiti dei criteri nel codebase di terze parti. Ad esempio, inizialmente potresti escludere il codice mentre ti sposti verso uno stato ideale per mantenere un repository di tutto il codice di terze parti utilizzato. Ti consigliamo di controllare regolarmente il codice per verificare che soddisfi i tuoi requisiti di sicurezza.
Per saperne di più sulla gestione del codice di terze parti, consulta Il successo condiviso nella creazione di una community open source più sicura.
Passaggi successivi
- Scopri di più su BeyondProd, che utilizziamo per creare un perimetro sicuro attorno ai nostri microservizi.
- Per adottare una pipeline CI/CD sicura, consulta Supply chain Levels for Software Artifacts (SLSA).