Autorizzazione binaria per Borg

Questi contenuti sono stati aggiornati a maggio 2024 e rappresentano lo status quo del momento in cui sono stati redatti. Le norme e i sistemi di sicurezza di Google possono variare in futuro, grazie al costante miglioramento della protezione per i nostri clienti.

Questo documento descrive il modo in cui utilizziamo le revisioni del codice, l'infrastruttura di sicurezza e un controllo di applicazione denominato Autorizzazione binaria per Borg (BAB) per contribuire a proteggere la catena di fornitura del software di Google dai rischi provenienti da personale interno. BAB aiuta a ridurre i rischi legati agli addetti ai lavori perché garantisce che il software di produzione sia esaminato e approvato prima del deployment, 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 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

Il rischio legato agli addetti ai lavori rappresenta una minaccia alla sicurezza dei dati utente, che può includere dati sul lavoro, dati finanziari o altri dati aziendali o proprietari. Il rischio da parte di un dipendente è il potenziale per un dipendente di usare le sue conoscenze o il suo accesso organizzativo per eseguire azioni dannose o per un aggressore esterno che utilizza 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 del software, utilizziamo BAB. BAB è un controllo di applicazione interno che si verifica quando si esegue il deployment del software. BAB garantisce che i deployment di codice e configurazione soddisfino determinati standard minimi e garantiscano 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, pur agendo da soli, non possano accedere direttamente o indirettamente ai dati utente o influire in altro modo sui dati utente senza un'autorizzazione e una giustificazione adeguate. BAB e i controlli associati ci aiutano ad applicare privilegio minimo, il che migliora la nostra security posture indipendentemente da uno specifico soggetto malintenzionato. In altre parole, BAB limita l'accesso unilaterale, indipendentemente dal fatto che l'utente abbia intento dannoso, che il suo account sia stato compromesso o che gli sia stato concesso involontariamente l'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 di Google. I vantaggi includono:

  • BAB aiuta a ridurre i rischi complessivi legati agli addetti ai lavori: BAB richiede che il codice soddisfi determinati standard e pratiche di gestione dei cambiamenti prima che possa accedere ai dati utente. Questo requisito riduce la possibilità che un dipendente agisca da solo (o un account dipendente compromesso) possa accedere ai dati utente in modo programmatico.
  • BAB supporta l'uniformità dei sistemi di produzione: grazie all'utilizzo dei sistemi containerizzati e alla verifica dei relativi requisiti BAB prima del deployment, i nostri sistemi diventano più semplici da eseguire per il debug, sono più affidabili e dispongono di 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à tra i sistemi Google. I dati relativi a questa conformità sono pubblicati internamente e sono disponibili per gli altri team. La pubblicazione di dati BAB consente ai team di utilizzare termini comuni nelle comunicazioni tra loro in merito alla protezione dell'accesso ai dati. Questo linguaggio comune riduce il continuo lavoro necessario per lavorare con i dati tra team.
  • BAB consente il monitoraggio programmatico dei requisiti di conformità: BAB semplifica quelle che in precedenza erano attività di conformità manuale. Alcune procedure in Google richiedono controlli più rigidi sul trattamento dei dati. Ad esempio, i nostri sistemi di rendicontazione finanziaria 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 permesso al team per la conformità di aumentare 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

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. Questi passaggi vengono descritti in maggiore dettaglio nelle sezioni seguenti.

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 di almeno un ingegnere diverso dall'autore. Un codebase monolitico consente l'applicazione di un singolo punto di passaggio obbligato per le revisioni del codice.

Come minimo, il nostro processo di revisione del codice richiede che i proprietari di un sistema debbano approvare le modifiche apportate al codice in quel sistema.

Quando importi le modifiche da un codice open source o di terze parti, verifichiamo che la modifica sia appropriata (ad esempio, la versione più recente). Tuttavia, spesso non disponiamo degli 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 crea e compila codice sorgente per creare un programma binario per il deployment. Il nostro sistema di compilazione viene eseguito in un ambiente isolato e bloccato che è 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 crittografici di eventuali file binari o altri artefatti della build e i parametri di build completi. Questa provenienza consente:

  • La capacità di tracciare un programma binario fino al codice sorgente utilizzato per la creazione. Per estensione, la provenienza può anche tracciare il processo relativo alla creazione e all'invio del codice sorgente che descrive.
  • La possibilità di verificare che il file binario non sia stato modificato, in quanto eventuali modifiche al file comportavano automaticamente la validità della sua firma.

Poiché le azioni di build possono essere costituite da 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 altre build. Il sistema impedisce alle build di apportare modifiche che potrebbero compromettere l'integrità della provenienza della build o del sistema stesso. Al termine della build, il deployment della modifica viene eseguito utilizzando Borg.

Passaggio 3: deployment containerizzato

Dopo che il sistema di compilazione ha creato il file 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 da molte applicazioni diverse, su più cluster, ognuno con decine di migliaia di macchine. Nonostante questa scala, il nostro ambiente di produzione è abbastanza omogeneo. Di conseguenza, i touchpoint per l'accesso ai dati utente possono essere controllati e sottoposti più facilmente ad audit.

I container offrono notevoli vantaggi in termini di sicurezza. I container sono pensati per essere immutabili, con frequenti rideployment da una ricreazione completa dell'immagine. La containerizzazione ci consente di esaminare le modifiche apportate al codice nel contesto e fornisce un singolo punto di passaggio per 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: le immagini container, i parametri di runtime, gli argomenti e i flag. Borg pianifica il job, prendendo in considerazione i vincoli, la priorità, la quota e tutti gli altri requisiti elencati nella configurazione del job. Dopo il deployment, 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 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 Site Reliability Engineer (SRE)) 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à quando effettua richieste di altri servizi utilizzando Application Layer Transport Security (ALTS). Affinché un servizio possa accedere a determinati dati o a un altro servizio, la sua identità deve avere le autorizzazioni necessarie.

Le nostre norme 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 ciascun servizio. BAB crea anche un audit trail del codice e della configurazione utilizzati nei job abilitati per BAB per consentire il monitoraggio e la risposta agli incidenti.

BAB è progettato per garantire che tutto il software e la configurazione di produzione vengano esaminati, archiviati, creati in modo verificabile e autorizzati, in particolare quando il codice può accedere ai dati utente.

Criteri specifici per il servizio

Quando i proprietari dei servizi eseguono l'onboarding del loro servizio in Borg, creano un criterio BAB che definisce i requisiti di sicurezza per il loro servizio. Queste norme prendono il nome di norme specifiche dei servizi. 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 quale codice e configurazione è consentito eseguire come identità del servizio, nonché le proprietà richieste di tale codice e configurazione. Tutti i job in esecuzione con l'identità del servizio devono soddisfare i criteri specifici del servizio.

Tutti i servizi Borg di Google devono configurare un criterio specifico per il servizio.

Per impostazione predefinita, questa pratica applica i seguenti requisiti:

  • Il codice deve essere controllabile: Possiamo far risalire l'immagine container alle sue fonti leggibili da persone attraverso la provenienza generata da build verificabili. Un criterio di conservazione conserva le origini del codice leggibili da una persona 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 implica in genere che il codice è stato sottoposto a una revisione.
  • Le configurazioni devono essere inviate: Tutte le configurazioni fornite durante il deployment seguono la stessa procedura di revisione e invio del codice normale. Pertanto, i valori, gli argomenti e i parametri del flag 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 per cui è prevista un'eccezione valida e approvata, potrebbero avere norme più permissive, ad esempio quelle che richiedono solo la verificabilità del codice o che disattiva completamente BAB.

I sistemi e i componenti che applicano BAB sono controllati rigorosamente tramite rigorosi requisiti automatizzati e controlli manuali aggiuntivi.

Modalità di applicazione

BAB utilizza due modalità di applicazione per garantire che i job siano conformi ai criteri specifici 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 in fase di 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 il criterio specifico del servizio. Questo controllo si verifica anche se il dipendente o il servizio che effettua la richiesta di deployment è autorizzato in altro modo.

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, il job viene continuamente verificato 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 controllare che i job avviati (e che potrebbero essere ancora in esecuzione) siano conformi a eventuali aggiornamenti dei criteri. Ad esempio, la modalità di verifica continua controlla costantemente la presenza di job in esecuzione con criteri obsoleti o per i quali è stato eseguito il deployment utilizzando procedure di risposta di emergenza. Se un job non è conforme ai criteri più recenti, BAB invia una notifica ai proprietari del servizio in modo che possano mitigare il rischio.

Procedure di risposta di emergenza

In caso di incidente o interruzione del servizio, la nostra prima priorità è ripristinare il servizio interessato il più rapidamente possibile. In una situazione di emergenza, potrebbe essere necessario eseguire codice che non è stato rivisto o creato in modo verificabile. Di conseguenza, è possibile eseguire l'override della modalità di applicazione utilizzando un flag di risposta di emergenza. Le procedure di risposta di emergenza fungono anche da backup in caso di 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.

Durante una risposta di emergenza, BAB registra i dettagli del job Borg associato e invia una notifica al team di sicurezza centralizzato di Google e il team proprietario dell'identità del servizio. La voce di log include un riferimento a un'istantanea del codice di cui è stato eseguito il deployment e la voce di log fornita dall'utente. Le procedure di risposta di emergenza devono essere usate solo come ultima risorsa.

Estensione di BAB ad altri ambienti

Inizialmente, BAB supportava solo la protezione dei job Borg e richiedeva lo sviluppo del software utilizzando la pipeline di controllo del codice sorgente, build e pacchettizzazione di Google tradizionale. Ora, BAB ha aggiunto il supporto per la protezione di altri ambienti di distribuzione del software e di deployment e per sistemi alternativi di controllo dell'origine, build e pacchettizzazione. I dettagli di implementazione per questi diversi ambienti sono diversi, ma i vantaggi di BAB rimangono.

Alcuni casi non si prestano bene alle revisioni del codice da parte di persone fisiche prima del deployment, in particolare lo sviluppo iterativo del codice di machine learning e l'analisi dei dati ad alta frequenza. In questi casi, esistono 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 e omogenea

L'adozione di BAB è stata semplificata perché la maggior parte dei team ha utilizzato un unico sistema di controllo di origine, processo di revisione del codice, sistema di compilazione e sistema di deployment. Le revisioni del codice facevano già parte della nostra cultura, quindi abbiamo potuto 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 rafforzato le garanzie che una soluzione come BAB può fornire.

Il nostro ampio utilizzo di microservizi e identità basate sui servizi (come gli account di servizio), piuttosto che di identità basate su host (come gli indirizzi IP), ci consente di creare un controllo granulare sul software a cui è consentito 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 i criteri in base ai tuoi 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 iniziare a eseguire revisioni formali del codice prima di poterle applicare in fase di deployment.

Un ottimo motivo per un processo di rilascio guidato dalle norme è la conformità. Se riesci a codificare almeno alcuni dei requisiti di conformità in un criterio, puoi automatizzare i test e assicurarti che siano efficaci in modo affidabile. Inizia con un insieme base di requisiti e codifica man mano quelli più avanzati.

Applica i criteri nelle prime fasi di sviluppo

È difficile definire criteri esaustivi su un software senza prima sapere dove verrà eseguito e a quali dati avrà accesso. Di conseguenza, l'applicazione dei criteri specifici del servizio viene eseguita durante il deployment del codice e quando accede ai dati, non quando viene creato. 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 i requisiti BAB specifici.

Affidati agli agenti dei cambiamenti tra i vari team

Quando abbiamo creato un mandato a livello Google per il deployment di BAB, ciò che ha influito maggiormente sul nostro tasso di successo è stato trovare proprietari che dovessero promuovere il cambiamento in ciascun gruppo di prodotti. Abbiamo identificato alcuni proprietari di servizi che hanno riscontrato vantaggi immediati dall'applicazione delle norme ed erano disposti a fornire feedback. Abbiamo chiesto a questi proprietari di fare volontariato prima di rendere obbligatorie eventuali modifiche. Dopo aver ricevuto il loro aiuto, abbiamo istituito un team formale di gestione dei cambiamenti per monitorare i cambiamenti in atto. Abbiamo quindi identificato i proprietari responsabili di ciascun team di prodotto che dovevano implementare le modifiche.

Determinare come gestire il codice di terze parti

Se devi gestire codice di terze parti, valuta come introdurre i requisiti delle norme nel codebase di terze parti. Ad esempio, puoi iniziare mantenendo un repository di tutto il codice di terze parti utilizzato. Ti consigliamo di verificare regolarmente il codice in base ai tuoi requisiti di sicurezza.

Per ulteriori informazioni sulla gestione del codice di terze parti, consulta Successo condiviso nella creazione di una community open source più sicura.

Passaggi successivi