Questi contenuti sono stati aggiornati per l'ultima volta a maggio 2024 e rappresentano lo status quo al momento della redazione. I criteri e i sistemi di sicurezza di Google potranno 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 di applicazione chiamato Autorizzazione binaria per Borg (BAB) per proteggere la supply chain del software di Google dai rischi provenienti da personale interno. BAB aiuta a ridurre i rischi provenienti da personale interno perché garantisce che il software di produzione venga esaminato e approvato prima dell'implementazione, in particolare quando il nostro codice può accedere a dati sensibili. BAB si applica a tutti i servizi in esecuzione su Borg. Dalla pubblicazione originale di questo documento, abbiamo incluso i concetti chiave di BAB in una specifica aperta chiamata Supply-chain Levels for Software Artifacts (SLSA).
Questo documento fa parte di una serie di articoli tecnici che descrivono alcuni progetti sviluppati dal team addetto alla sicurezza di Google per contribuire a migliorare la sicurezza, inclusi BeyondCorp e BeyondProd. Per una panoramica della sicurezza della nostra infrastruttura, consulta la panoramica sulla progettazione della sicurezza dell'infrastruttura Google.
Introduzione
Il rischio interno rappresenta una minaccia alla sicurezza dei dati utente, che possono includere dati sull'impiego, dati finanziari o altri dati aziendali o proprietari. Il rischio interno è la possibilità che un dipendente utilizzi le proprie conoscenze dell'organizzazione o il proprio accesso per compiere atti illeciti oppure che un malintenzionato esterno utilizzi le credenziali compromesse di un dipendente per fare lo stesso.
Per ridurre al minimo i rischi provenienti da personale interno all'interno della nostra catena di fornitura software, utilizziamo BAB. BAB è un controllo interno dell'applicazione forzata che viene eseguito durante il deployment del software. BAB garantisce che i deployment di codice e configurazione rispettino determinati standard minimi e supporta l'uniformità dei nostri sistemi di produzione.
Contribuiamo a proteggere i dati utente all'interno dei nostri sistemi di produzione limitando l'accesso unilaterale da parte dei nostri dipendenti. BAB contribuisce a garantire che i dipendenti, mentre agiscono per fini propri, non possano accedere direttamente o indirettamente o influire in qualsiasi altro modo sui dati utente senza un'autorizzazione e una giustificazione adeguata. BAB e i relativi controlli ci aiutano ad applicare il principio del privilegio minimo, il che migliora la nostra postura di sicurezza indipendentemente da un attore delle minacce specifico. In altre parole, BAB limita l'accesso unilaterale indipendentemente dall'intento negativo o meno dell'autore, dall'eventuale compromissione del suo account o dall'errata concessione dell'accesso.
Vantaggi di BAB
L'adozione di BAB e di un modello di deployment containerizzato offre numerosi vantaggi in termini di sicurezza per l'infrastruttura Google. I vantaggi includono:
- BAB aiuta a ridurre i rischi complessivi provenienti da personale interno:BAB richiede che il codice soddisfi determinati standard e pratiche di gestione dei cambiamenti prima di poter accedere ai dati utente. Questo requisito riduce la possibilità che un dipendente che agisce per propri fini (o un account dipendente compromesso) acceda ai dati utente in modo programmatico.
- BAB supporta l'uniformità dei sistemi di produzione:utilizzando i sistemi containerizzati e verificandone i requisiti BAB prima del deployment, i nostri sistemi diventano più facili da eseguire il debug, più affidabili e hanno processi di gestione delle modifiche ben definiti. I requisiti BAB offrono un linguaggio comune per i requisiti dei sistemi di produzione.
- BAB determina il linguaggio comune per la protezione dei dati:BAB traccia la conformità tra i sistemi Google. I dati relativi a questa conformità vengono pubblicati internamente e sono disponibili per altri team. La pubblicazione dei dati BAB consente ai team di utilizzare una terminologia comune nelle loro comunicazioni relative alla protezione dell'accesso ai dati. Questo linguaggio comune riduce la necessità di chiarimenti reciproci durante il lavoro sui dati che coinvolge più 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 sul trattamento dei dati. Ad esempio, i nostri sistemi per i report finanziari devono essere conformi al Sarbanes-Oxley Act (SOX). Prima di BAB, avevamo un sistema che agevolava l'esecuzione manuale delle 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 permesso al team per la conformità di aumentare sia l'ambito dei servizi coperti, sia l'adozione di controlli adeguati su tali servizi.
BAB fa parte del framework BeyondProd più ampio che utilizziamo per ridurre i rischi provenienti da personale interno.
Il nostro processo di sviluppo e produzione
Per impostazione predefinita, il processo di sviluppo e produzione di Google include quattro passaggi obbligatori: revisione del codice, build verificabili, deployment containerizzato e identità basata sui servizi. Le sezioni seguenti 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, e richiede la revisione e l'approvazione da parte di almeno un tecnico diverso dall'autore. Un codebase monolitico consente l'applicazione di un singolo punto di passaggio obbligato per le revisioni del codice.
Come minimo, la nostra procedura di revisione del codice richiede che i proprietari di un sistema approvino le modifiche al codice del sistema stesso.
Quando importiamo modifiche da codice di terze parti o open source, verifichiamo che la modifica sia appropriata (ad esempio, che sia la versione più recente). Tuttavia, spesso non applichiamo gli stessi controlli di revisione 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 build è simile a Bazel, che genera e compila il codice sorgente per creare un programma binario per il deployment. Il nostro sistema di build viene eseguito in un ambiente isolato e bloccato separato dai dipendenti che eseguono le build. Per ogni build, il sistema produce una provenienza generata da build verificabili . Questa provenienza è un certificato firmato che descrive le origini e le dipendenze che sono state inserite nella build, gli hash crittografici di eventuali file binari o altri artefatti della build e i parametri completi della build. Questa provenienza consente quanto segue:
- La possibilità di tracciare un programma binario risalendo al codice sorgente utilizzato per crearlo. Per estensione, la provenienza può anche tracciare il processo di creazione e invio del codice sorgente che descrive.
- La possibilità di verificare che il programma binario non sia stato modificato, in quanto eventuali modifiche al file comprometterebbero automaticamente la validità della firma.
Poiché le azioni di build possono riguardare il codice arbitrario, il nostro sistema di build è stato protetto per l'architettura multi-tenancy. In altri termini, il nostro sistema di build è progettato per impedire che una build ne influenzi altre. Il sistema impedisce alle build di apportare modifiche in grado di compromettere l'integrità della provenienza della build o del sistema stesso. Una volta completata la build, il deployment della modifica viene eseguito tramite Borg.
Passaggio 3: deployment in container
Dopo che il sistema di compilazione crea il binario, questo viene pacchettizzato in un'immagine container e implementato come job Borg sul nostro sistema di orchestrazione dei cluster, Borg. Eseguiamo centinaia di migliaia di job di numerose applicazioni, tra diversi cluster, ciascuno anche 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 sottoposti ad audit più facilmente.
I container offrono notevoli vantaggi in termini di sicurezza. I container sono pensati per essere immutabili, con frequenti redeployment da una rigenerazione completa dell'immagine. La containerizzazione ci consente di esaminare una modifica al codice in contesto e offre un singolo punto di passaggio obbligato per le modifiche implementate nella nostra infrastruttura.
La configurazione di un job Borg specifica i requisiti per il job da implementare: le immagini container, i parametri di runtime, gli argomenti e i flag. Borg programma il job prendendo in considerazione i vincoli, la priorità, la quota e qualsiasi altro requisito elencato nella configurazione. Dopo il deployment del job, il job Borg può interagire con altri job in produzione.
Passaggio 4: identità basata sui servizi
Un job Borg viene eseguito come identità di servizio. Questa identità viene utilizzata per accedere ai datastore o ai metodi di chiamata di procedura remota (RPC) di altri servizi. Più job potrebbero essere eseguiti con la stessa identità. Solo i dipendenti responsabili dell'esecuzione del servizio (in genere SRE (Site Reliability Engineer)) possono implementare 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 provare la sua identità quando esegue richieste di altri servizi utilizzando Application Layer Transport Security (ALTS). Per poter accedere a determinati dati o ad altri servizi, l'identità di un servizio deve avere le autorizzazioni necessarie.
I nostri criteri richiedono la protezione BAB per le identità di servizio che hanno accesso ai dati utente e a qualsiasi altra informazione sensibile. I job di sviluppo e garanzia di 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 ogni servizio. BAB crea anche 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, compilati in modo verificabile e autorizzati in modo adeguato, 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 su Borg, creano un criterio BAB che definisce i requisiti di sicurezza per il servizio. Questi criteri sono denominati criteri specifici per il servizio. La definizione o la modifica di un criterio è a sua volta una modifica al codice che deve essere sottoposta a revisione.
La policy specifica del servizio definisce il codice e la configurazione consentiti per l'esecuzione come identità del servizio, nonché le proprietà richieste di questo codice e di questa configurazione. Tutti i job eseguiti come identità del servizio devono soddisfare il criterio specifico del servizio.
Tutti i servizi Borg di Google devono configurare un criterio specifico del servizio.
Per impostazione predefinita, questa pratica applica i seguenti requisiti:
- Il codice deve essere verificabile: Possiamo risalire all'immagine container dalle sue origini leggibili tramite la provenienza generata da build verificabili. Una norma di conservazione mantiene le origini del codice leggibili per almeno 18 mesi, anche se il codice non viene inviato.
- È necessario inviare il codice: la build del codice è stata creata da una posizione specifica 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: le configurazioni fornite durante il deployment passano attraverso lo stesso processo di revisione e invio del codice normale. Di conseguenza, i valori flag, gli argomenti e i parametri della riga di comando non possono essere modificati senza revisione.
I servizi che non hanno accesso a dati sensibili o, in rari casi, i servizi che dispongono di un'eccezione valida e approvata potrebbero avere una norma più permissiva, ad esempio una che richiede solo l'auditabilità del codice o persino una che disattiva completamente BAB.
I sistemi e i componenti che applicano BAB sono strettamente controllati utilizzando requisiti automatizzati rigorosi e controlli manuali aggiuntivi.
Modalità di applicazione
BAB utilizza due modalità di applicazione forzata per garantire che i lavori siano conformi alle norme specifiche del servizio:
- Applicazione forzata al momento del deployment, che impedisce il deployment dei job non conformi.
- Convalida continua, che monitora e invia avvisi relativi ai job non conformi che sono stati implementati.
Inoltre, in caso di emergenza, le procedure di risposta di emergenza possono ignorare l'applicazione forzata al momento del deployment.
Modalità di applicazione forzata in fase di deployment
Borg Prime è il controller centralizzato di Borg, che funge da autorità di certificazione per ALTS. Quando viene inviato un nuovo job, Borg Prime consulta BAB per verificare che il job soddisfi i requisiti dei criteri specifici del servizio prima che Borg Prime conceda il certificato ALTS al job. Questo controllo funge da controller di ammissione: Borg avvia il job solo se soddisfa i criteri specifici del servizio. Questo controllo viene eseguito anche quando il dipendente o il servizio che effettua la richiesta di deployment è altrimenti autorizzato.
In rari casi, i servizi possono disattivare l'applicazione in fase di deployment con una giustificazione adeguata.
Modalità di verifica continua
Una volta implementato, un job viene sottoposto a verifica continua per tutta la sua durata, indipendentemente dalla modalità di applicazione forzata in fase di deployment. Un processo BAB viene eseguito almeno una volta al giorno per verificare che i job avviati (e potenzialmente ancora in esecuzione) siano conformi agli eventuali aggiornamenti dei rispettivi criteri. Ad esempio, la modalità di verifica continua ricerca costantemente job in esecuzione con criteri obsoleti o implementati tramite procedure di risposta di emergenza. Se viene trovato un job che non è conforme al 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 guasto, la nostra prima priorità consiste nel ripristinare il servizio interessato il prima possibile. In una situazione di emergenza, potrebbe essere necessario eseguire codice senza revisione o build verificabile. Di conseguenza, la modalità di applicazione forzata può essere ignorata tramite un flag di risposta di emergenza. Le procedure di risposta di emergenza fungono anche da backup in caso di errore del 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 motivazione come parte della richiesta.
Durante una risposta di emergenza, BAB registra i dettagli relativi al job Borg associato e invia una notifica sia al team di sicurezza centralizzato di Google sia al team proprietario dell'identità del servizio. La voce di log include un riferimento a uno snapshot del codice di cui è stato eseguito il deployment e alla giustificazione fornita dall'utente. 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 lo sviluppo del software utilizzando la pipeline tradizionale di controllo del codice sorgente, compilazione e packaging di Google. Ora BAB supporta la protezione di altri ambienti di distribuzione e deployment del software, nonché sistemi alternativi di controllo dell'origine, build e packaging. I dettagli di implementazione per questi vari ambienti sono diversi, ma i vantaggi di BAB rimangono.
Esistono alcuni casi che non si prestano bene alle revisioni del codice umane prima del deployment, in particolare lo sviluppo iterativo del codice di machine learning e l'analisi dei dati ad alta frequenza. In questi casi, disponiamo di controlli alternativi che compensano la revisione umana.
Adozione di controlli simili nella propria organizzazione
Questa sezione descrive le best practice che abbiamo appreso durante l'implementazione di BAB in modo che tu possa adottare controlli simili nella tua organizzazione.
Crea una pipeline CI/CD containerizzata omogenea
L'adozione di BAB è stata semplificata perché la maggior parte dei team utilizzava un unico sistema di controllo del codice sorgente, processo di revisione del codice, sistema di compilazione e sistema di deployment. Le revisioni del codice facevano già parte della nostra cultura, quindi siamo riusciti ad apportare modifiche senza troppi cambiamenti significativi 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 degli accessi. Questo approccio ha semplificato l'adozione di BAB e ha rafforzato le garanzie che una soluzione come BAB è in grado di fornire.
L'uso diffuso di microservizi e identità basate sui servizi (come gli account di servizio), anziché 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, come passaggio intermedio potresti provare a proteggere i token di identità utilizzando altre misure.
Determina gli obiettivi e definisci i criteri in base ai requisiti
Realizza il processo di release basato su criteri un passo alla volta. Potrebbe essere necessario implementare alcune modifiche prima di altre nella pipeline CI/CD. Ad esempio, potrebbe essere necessario avviare revisioni del codice formali prima di poterne richiedere l'applicazione forzata in fase di deployment.
Uno dei motivi principali per l'adozione di un processo di release basato su criteri è la conformità. Se puoi codificare almeno alcuni dei requisiti di conformità in un criterio, questo può facilitare l'automazione dei test e assicurare che siano sempre attivi. Inizia con un set di requisiti di base e codifica man mano i requisiti più avanzati.
Applica i criteri fin dalle prime fasi dello sviluppo
È difficile definire criteri esaurienti su un software senza prima sapere dove verrà eseguito e a quali dati avrà accesso. Pertanto, l'applicazione forzata dei criteri specifici del servizio viene eseguita durante il deployment del codice e l'accesso ai dati e non in fase di build. Un criterio è definito in termini di identità di runtime, quindi lo stesso codice potrebbe essere eseguito in ambienti diversi ed essere soggetto a criteri differenti.
BAB viene utilizzato in aggiunta ad altri meccanismi di accesso per limitare l'accesso ai dati utente. I proprietari dei servizi possono garantire ulteriormente che ai dati possa accedere solo un job che soddisfi particolari requisiti BAB.
Elenca gli agenti dei cambiamenti nei vari team
Quando abbiamo reso obbligatorio il deployment di BAB nell'intera organizzazione di Google , ciò che ha favorito maggiormente il nostro successo è stato trovare proprietari disposti a guidare il cambiamento in ciascun gruppo di prodotti. Abbiamo identificato un gruppo di proprietari di servizi che hanno riscontrato vantaggi immediati dall'applicazione e che erano disposti a fornire feedback. Abbiamo chiesto a questi proprietari di offrirsi come volontari prima di rendere obbligatoria qualsiasi modifica. Una volta ottenuto il loro aiuto, abbiamo definito un team ufficiale per la gestione dei cambiamenti per monitorare i cambiamenti in corso. Quindi, abbiamo identificato i proprietari responsabili per ciascun team di prodotto per l'implementazione dei cambiamenti.
Determinare come gestire il codice di terze parti
Se devi gestire codice di terze parti, valuta come introdurre i requisiti dei tuoi criteri nel codebase di terze parti. Ad esempio, potresti inizialmente iniziare a tenere un repository di tutto il codice di terze parti utilizzato. Ti consigliamo di esaminare regolarmente questo codice rispetto ai tuoi requisiti di sicurezza.
Per saperne di più sulla gestione del codice di terze parti, consulta 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 intorno ai nostri microservizi.
- Per adottare una pipeline CI/CD sicura, consulta Supply chain Levels for Software Artifacts (SLSA).