Utilizzo di Valint per applicare policy al tuo SDLC

Tutti i messaggi

Valint è lo strumento principale di Scribe per creare, gestire, firmare e verificare prove. In un post precedente, abbiamo trattato la teoria dell'utilizzo della firma e della verifica delle prove come strumento principale per convalidare la sicurezza della pipeline CI/CD. Come breve promemoria, il modello proposto da Scribe include diversi elementi costitutivi che possono essere mescolati e impilati in qualsiasi modo si adatti alle tue esigenze. Gli elementi costitutivi includono le prove raccolte (SBOM, SLSA provenienza, eventuali risultati di test di terze parti che desideri includere), il contesto ambientale delle prove raccolte (chi le ha create, dove, quando, ecc.) e la politica che desideri applicare a tali prove.

Poiché le politiche che desideri applicare alle tue prove sono un fattore chiave in questo modello, abbiamo pensato di dedicare un post sul blog per esplorare in modo più dettagliato il potenziale del motore delle politiche che offriamo.

In questo articolo esamineremo la policy più elementare che abbiamo ideato (firmare e verificare le informazioni). Tratteremo l'aspetto del modello per una policy più complessa e forniremo alcuni esempi standard di policy, ad esempio come verificare che un utente specifico sia stato quello che ha creato l'ultimo ramo "principale" o come verificare che la pipeline venga eseguita include un test di strumenti di terze parti che deve essere incluso.

Inizia qui: firma e verifica delle prove

Valente è uno strumento molto versatile ma per mantenere questo articolo semplice utilizzeremo principalmente l'interfaccia CLI di Valint come esempio.

Il primo passo sarebbe scaricare Valint:

curl -sSfL https://get.scribesecurity.com/install.sh | sh -s -- -t valint

Il comando per creare una SBOM da un repository o da un'immagine è 'bom'. Quindi, ad esempio, se vuoi bom l'immagine di busybox:latest il comando sarà simile al seguente:

$HOME/.scribe/bin/valint bom busybox:latest -o attest -f

Si noti che attest è un alias per attest-cyclonedx-json.

Per impostazione predefinita, Valint utilizza sigstore flusso interattivo come motore dietro il meccanismo di firma incorporato nella libreria Cocosign di Scribe. Questa libreria si occupa delle firme digitali per la firma e la verifica. Una volta applicato il comando dovrai prima approvare che desideri firmare la prova con un'opzione S/[N]:

Un'immagine della libreria Cocosign

Puoi anche utilizzare la PKI standard per la firma (supportiamo i certificati x509). Esistono più opzioni per archiviare la chiave di firma, ad esempio KMS, archivio segreto GitHub, e puoi configurare facilmente Valint per utilizzare qualsiasi meccanismo di firma desideri.

Supponendo che approvi la firma, verrai indirizzato a Sigstore nel tuo browser dove dovrai accedere utilizzando il tuo account GitHub, il tuo account Google o il tuo account Microsoft:

Un'immagine dell'accesso a Sigstore

Una volta effettuato l'accesso vedrai che il login è andato a buon fine:

a quel punto puoi chiudere il browser e tornare alla tua shell dove puoi vedere che la prova è stata creata con successo.

Un'immagine di una generazione SBOM di successo

L'attestazione viene scritta per impostazione predefinita nella cache locale la cui posizione è fornita da --output-directory flag nel file di configurazione flag. Puoi anche usare il -file di uscita flag per fornire un percorso personalizzato per l'attestazione.

Ora che abbiamo creato un'attestazione firmata, proviamo a verificare che esista e sia firmata. Il comando per verificare le prove è verify. Il modo di usarlo è quasi identico a bom comando tranne che utilizzeremo il flag -iche è l'abbreviazione di --input-format e l'impostazione predefinita è, come in bom, attestare-cyclonedx-json. Il comando verify cercherà innanzitutto le prove necessarie nella posizione predefinita utilizzata da Valint. È possibile specificare una posizione diversa se si desidera sia per salvare le prove che per cercarle in seguito.

Quindi, se vogliamo verificare il busybox:latest attestazione dell'immagine che abbiamo generato e firmato nell'esempio precedente, il comando sarà simile a questo:

$HOME/.scribe/bin/valint verify busybox:latest -i attest

Supponendo che tu abbia fatto tutto bene, il risultato dovrebbe essere simile a questo:

Un'immagine di una verifica riuscita

Puoi visualizzare l'elenco di messaggi di posta elettronica che include l'email del firmatario nell'attestazione originale e puoi anche vedere il tipo di attestazione che è stata verificata, in questo caso, cyclonedx-json. 

Sembra piuttosto semplice, vero? Facciamo un salto di qualità.

Modelli di politica

A politica è costituito da un insieme di moduli. La policy viene verificata se tutti i moduli che include vengono valutati e verificati. Un modulo viene verificato se viene trovata QUALSIASI prova conforme alla configurazione e all'impostazione del modulo.  

Le policy vengono configurate come parte del file di configurazione di Valint, nella sezione policy. Questo è un esempio di parte di un file di configurazione Valint, la parte contenente le potenziali policy. 

Un'immagine del file di configurazione di Valint

Ricorda che non è necessario includere un file di configurazione nel tuo progetto: Valint può funzionare perfettamente solo con le opzioni predefinite abilitate. Inoltre, poiché tutto in questo file è facoltativo, è perfettamente valido avere un file di questo tipo che includa SOLO le tue politiche. 

Il file di configurazione, denominato per impostazione predefinita .valint.yaml, dovrebbe essere incluso nella root del tuo repository. In base alle policy incluse in questo file quando esegui il comando valint verify eseguirà qualunque policy e modulo sia abilitato. Poiché la policy di "verifica" di base è quella predefinita, non è necessario configurare nulla per il file verify comando per funzionare correttamente anche senza un file .valint.yaml.

Qualunque policy aggiungi al file di configurazione dipende dalla disponibilità di prove da cercare. Per impostazione predefinita, quando esegui il comando 'bom' nella tua pipeline, le prove risultanti verranno caricate nell'archivio prove di Scribe. Allo stesso modo, quando esegui il comando "verifica", cercherà le prove nell'archivio prove di Scribe. Puoi modificare questa impostazione predefinita e utilizzare un OCI o una cache come archivio prove, ma per questo articolo presupporremo che venga utilizzata l'impostazione predefinita e che tutte le prove vengano caricate ed estratte dall'archivio prove di Scribe.

Quindi, sulla base di questo esempio, esaminiamo i componenti di una politica. IL politica supporta i seguenti campi:

  • Nome, il nome della policy (obbligatorio).
  • enable, abilitare il modulo (il valore predefinito è false).
  • moduli, elenco delle configurazioni del modulo criteri.  

 

Il modulo le sezioni supportano i seguenti campi:

  • Nome, il nome del modulo policy (obbligatorio).
  • enable, abilitare il modulo (il valore predefinito è false).
  • Digitare, tipo di modulo, attualmente supportato verifica-artefatto e proprietario-git.
  • stile, abbinare le prove con un contesto specifico.
  • ingresso, configurazione specifica del modulo.

Una policy può avere più moduli e tutti i moduli abilitati verranno eseguiti una volta eseguito il comando "verifica". 

Poiché so che un elenco scarno di campi non è molto informativo, passiamo direttamente alla sezione successiva, con le policy di esempio.

Politiche di esempio

Politica di verifica delle immagini

Iniziamo con la policy più semplice, quella che esprime il flusso di verifica del segno Valint. 

attestare: cocosign: politiche: - nome: verify_policy abilita: true moduli: - nome: Signed_sbom tipo: verify-artifact abilita: true input: firmato: true formato: attest-cyclonedx-json identità: email: - barak@scribesecurity.com

Ancora una volta, questa policy dovrebbe essere inclusa nel file .valint.yaml nella root del tuo repository. Affinché funzioni, è necessario aver creato in anticipo una SBOM firmata eseguendo il file valint bom comando. Una volta che sei pronto per verificarlo dovrai eseguire il file valint verify comando.

Osservando questo esempio possiamo vedere che la policy è abilitata e che ha un modulo di tipo abilitato ‘verify-artifact‘. Il modulo verifica che l'input sia firmato e di formato ‘attest-cyclonedx-json’, e che sia stato firmato dall'identità rappresentata dall'e-mail ‘barak@scribesecurity.com’.

Per eseguire questa policy dovremo eseguire il file verifycomando nella nostra pipeline in questo modo:

valint verify busybox:latest

Poiché verify il comando è ora basato sulla policy che abbiamo fornito e cercherà a busybox:latest pezzo di prova nel tuo negozio di prove Scribe. Cercherà una SBOM di formato firmata `cyclonedx-json` e controllerà che l'identità che ha firmato la SBOM utilizzi l'e-mail prescritta nella policy `barak@scribesecurity.com`.

Potresti dire che potrebbero esserci più immagini del genere in quell'archivio prove e avresti ragione. È qui che entra in gioco il contesto. Per impostazione predefinita, verify il comando cercherà la corrispondenza più vicina disponibile. Puoi, tuttavia, specificare che il comando dovrà corrispondere al contesto dell'ID di esecuzione della pipeline o al sistema di compilazione in cui è stato creato l'artefatto. Per fare ciò dovrai utilizzare il campo match: con il tipo di contesto appropriato. Per esempio:

            corrispondenza: context_type: github git_url: github.com/my_org/myimage.git branch: main

In questo caso le prove dovevano essere state generate da Github, dal repository indicato dal git_url e dal main ramo di quel repository. È importante utilizzare il contesto giusto laddove necessario per garantire che le policy verifichino esattamente ciò che desideri che verifichino. 

Politica di verifica binaria

Esaminiamo un altro esempio. Questa policy ha lo scopo di verificare che un file exe che stiamo controllando provenga da un repository specifico e sia stato firmato da una delle numerose persone conosciute. 

attestare: cocosign: politiche: - nome: verify_policy abilita: true moduli: - nome: binario_module tipo: verify-artifact abilita: true input: firmato: true formato: attest-cyclonedx-json identità: email: - barak@scribesecurity.com - mikey@scribesecurity.com - adam@scribesecurity.com corrispondenza: target_type: file context_type: azure git_url: https://dev.azure.com/mycompany/somerepo # URL Git dell'ambiente. nome_input: mio_binario.exe

Osservando questo esempio possiamo vedere che la policy è abilitata e che ha un modulo di tipo abilitato ‘verify-artifact‘ Il modulo verifica che l'input sia firmato, che sia in formato ‘attest-cyclonedx-json’, e che sia stato firmato da 1 delle 3 email consentite elencate nel modulo. Inoltre, controlla che verify il comando riceve un input per verificare che l'input sia denominato ‘my_binary.exe’, che l'input è un file creato in Azure e che proviene da un URL git specifico: https://dev.azure.com/mycompany/somerepo.

Come puoi vedere, in questo esempio ci sono molti più requisiti affinché la policy possa essere verificata.

Per eseguire questa policy dovremo eseguire il file verify comando nella nostra pipeline in questo modo:

valint verify file:my_binary.exe

Per assicurarti che il tuo archivio di prove di Scribe abbia una versione firmata di questo codice binario, dovresti prima creare le prove in questo modo:

valint bom file:my_binary.exe -o attest

Politica sulla verifica delle prove da parte di terzi

Nel nostro esempio finale vediamo come possiamo verificare che uno strumento di terze parti che utilizziamo abbia funzionato correttamente nella nostra pipeline e abbia creato il risultato che ci aspettiamo sotto forma di un file JSON. 

attestare: cocosign: politiche: - nome: verify_policy abilita: true moduli: - nome: tipo regola di terze parti: verify-artifact abilita: true input: firmato: false formato: identità attesta-generica: email: - bob@scribesecurity. com match: target_type: generic context_type: azure git_url: https://dev.azure.com/mycompany/somerepo git_branch: main input_name: 3rd-party-scan.json

In questo esempio, immaginiamo che a un certo punto della pipeline sia stato eseguito uno strumento di terze parti che ha creato, come risultato, il file "3rd-party-scan.json". Per soddisfare la policy, il file avrebbe dovuto avere origine da Azure DevOps, attivato dal file `https://dev.azure.com/mycompany/somerepo` repository e firmato da `bob@scribesecurity.com`. 

Per generare le prove che stiamo cercando, subito dopo l'esecuzione dello strumento di terze parti dobbiamo acquisire il file risultante e trasformarlo in prove utilizzando Valint:

valint bom 3rd-party-scan.json -o attest-generic --predicate-type https://scanner.com/scan_format

Cosa dimostrano le prove? 

Quindi abbiamo visto che possiamo usare Valine per verificare varie cose nella nostra pipeline. A cosa può servire realmente questa capacità?

Immaginiamo che il nostro gasdotto sia stato violato e che alcuni cattivi abbiano iniziato a fare cose che non vogliamo che facciano. Verificando che le diverse fasi del processo si siano svolte come previsto, producendo i risultati attesi e firmati dal personale approvato, rendiamo molto più difficile per i cattivi ingannarci.

Un potenziale attacco consiste nel sostituire il file binario alla fine della pipeline in modo che la versione ricevuta dai client sia dannosa anziché originale. Firmando la tua versione e chiedendo ai tuoi clienti di verificare rispetto alla copia originale, puoi assicurarti che tutti utilizzino lo stesso file che hai prodotto e non una contraffazione intelligente.

Questo modello di creazione di prove e quindi di verifica delle stesse è solo all’inizio. Lavoriamo costantemente per aggiungere ulteriori funzionalità a Valint per renderlo ancora più robusto e versatile. Nel frattempo ti incoraggio a dare un'occhiata al nostro documentazione per saperne di più su ciò che Scribe ha da offrire e su cosa altro puoi fare con Valint. Valint può essere scaricato e utilizzato gratuitamente, quindi non dovrebbe esserci nulla che ti impedisca di provare questo strumento oggi stesso. 

Questo contenuto è offerto da Scribe Security, un fornitore leader di soluzioni di sicurezza end-to-end per la catena di fornitura di software, che offre sicurezza all'avanguardia per artefatti di codice e processi di sviluppo e distribuzione del codice attraverso le catene di fornitura di software. Per saperne di più.