Genera e convalida la provenienza della build

Questa pagina fornisce istruzioni su come generare la provenienza della build, visualizzare l'output e convalidarlo.

La provenienza della build è una raccolta di dati verificabili su una build. I metadati di provenienza includono dettagli come la sintesi delle immagini create, le località dell'origine di input, gli argomenti di build e la durata della build. Puoi utilizzare queste informazioni per assicurarti che gli artefatti creati che stai utilizzando siano accurati e affidabili, creati da origini e builder attendibili.

Cloud Build supporta la generazione della provenienza delle build che soddisfa il livello di garanzia SLSA (Supply-chain Levels for Software Artifacts) di livello 3 in base alle specifiche per SLSA versione 0.1 e 1.0.

Nell'ambito del supporto della specifica SLSA v1.0, Cloud Build fornisce dettagli buildType sulla provenienza della build. Puoi utilizzare lo schema buildType per comprendere il modello con parametri utilizzato per il processo di compilazione, inclusi i valori registrati da Cloud Build e l'origine di questi valori. Per ulteriori informazioni, consulta BuildType Cloud Build v1.

Limitazioni

  • Cloud Build genera solo la provenienza della build per gli artefatti archiviati in Artifact Registry.
  • Per ottenere la provenienza di SLSA v1.0 e v0.1, devi creare utilizzando trigger. Se avvii una build manualmente, utilizzando gcloud CLI, Cloud Build fornisce solo la provenienza SLSA v0.1.

Prima di iniziare

  1. Abilita le API Cloud Build, Container Analysis, and Artifact Registry.

    Abilita le API

  2. Per utilizzare gli esempi a riga di comando in questa guida, installa e configura Google Cloud SDK.

  3. Tieni a portata di mano il codice sorgente.

  4. Avere un repository in Artifact Registry.

Generare la provenienza della build

Le seguenti istruzioni spiegano come generare la provenienza della build per le immagini container archiviate in Artifact Registry:

  1. Nel file di configurazione della build, aggiungi il campo images per configurare Cloud Build in modo da archiviare le immagini create in Artifact Registry al termine della build.

    Cloud Build non può generare la provenienza se esegui il push della tua immagine in Artifact Registry utilizzando un passaggio docker push esplicito.

    Lo snippet seguente mostra una configurazione di compilazione per creare un'immagine container e archiviare l'immagine in un repository Docker in Artifact Registry:

    YAML

      steps:
      - name: 'gcr.io/cloud-builders/docker'
        args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE', '.' ]
      images: ['LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE']
    

    Dove:

    • LOCATION: la località a livello di una o più regioni del tuo repository.
    • PROJECT_ID: l'ID del tuo progetto Google Cloud.
    • REPOSITORY: il nome del tuo repository Artifact Registry.
    • IMAGE: il nome dell'immagine container.

    JSON

      {
      "steps": [
          {
              "name": "gcr.io/cloud-builders/docker",
              "args": [
                  "build",
                  "-t",
                  "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE",
                  "."
              ]
          }
      ],
      "images": [
          "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE"
      ]
      }
    

    Dove:

    • LOCATION: la località a livello di una o più regioni del tuo repository.
    • PROJECT_ID: l'ID del tuo progetto Google Cloud.
    • REPOSITORY: il nome del tuo repository Artifact Registry.
    • IMAGE: il nome dell'immagine container.
  2. Nella sezione options della configurazione della build, aggiungi l'opzione requestedVerifyOption e imposta il valore VERIFIED.

    Questa impostazione consente la generazione della provenienza e configura Cloud Build per verificare che siano presenti metadati di provenienza. Le build verranno contrassegnate come riuscite solo se viene generata la provenienza.

    YAML

    options:
      requestedVerifyOption: VERIFIED
    

    JSON

    {
        "options": {
            "requestedVerifyOption": "VERIFIED"
        }
    }
    
  3. Inizia la build.

Visualizza la provenienza della build

Questa sezione spiega come visualizzare i metadati di provenienza della build creati da Cloud Build. Puoi recuperare queste informazioni per motivi di controllo.

Puoi accedere ai metadati di provenienza della build per i container utilizzando il riquadro laterale Approfondimenti sulla sicurezza nella console Google Cloud oppure utilizzando gcloud CLI.

console

Il riquadro laterale Approfondimenti sulla sicurezza fornisce una panoramica di alto livello delle informazioni sulla sicurezza per gli artefatti archiviati in Artifact Registry.

Per visualizzare il riquadro Approfondimenti sulla sicurezza:

  1. Apri la pagina Cronologia build nella console Google Cloud:

    Apri la pagina Cronologia build

  2. Seleziona il progetto e fai clic su Apri.

  3. Nel menu a discesa Regione, seleziona la regione in cui hai eseguito la build.

  4. Nella tabella con le build, individua la riga con la build per la quale vuoi visualizzare insight sulla sicurezza.

  5. Nella colonna Approfondimenti sulla sicurezza, fai clic su Visualizza.

    Viene visualizzato il riquadro Approfondimenti sulla sicurezza per l'artefatto selezionato.

    La scheda Crea mostra i dettagli sulla provenienza e un link. Puoi visualizzare lo snippet di provenienza facendo clic sull'icona del link.

Per scoprire di più sul riquadro laterale e su come utilizzare Cloud Build per proteggere la catena di fornitura del software, consulta Visualizzare gli insight sulla sicurezza della build.

Interfaccia a riga di comando gcloud

Per visualizzare i metadati di provenienza per le immagini container, esegui questo comando:

  gcloud artifacts docker images describe \
  LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH \
  --show-provenance --format=FORMAT

Sostituisci quanto segue:

  • LOCATION: la località a livello di una o più regioni del tuo repository.
  • PROJECT_ID: l'ID del tuo progetto Google Cloud.
  • REPOSITORY: il nome del tuo repository Artifact Registry.
  • IMAGE: il nome dell'immagine container.
  • HASH: il valore hash sha256 dell'immagine. Puoi trovare questo codice nell'output della build.
  • FORMAT: un'impostazione facoltativa in cui puoi specificare un formato di output.

Output di esempio

La provenienza della build è simile alla seguente:

      image_summary:
      digest: sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3
      fully_qualified_digest: us-central1-docker.pkg.dev/my-project/my-repo/my-image@sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3
      registry: us-central1-docker.pkg.dev
      repository: my-repo
      slsa_build_level: 0
    provenance_summary:
      provenance:
      - build:
          inTotoSlsaProvenanceV1:
            _type: https://in-toto.io/Statement/v1
            predicate:
              buildDefinition:
                buildType: https://cloud.google.com/build/gcb-buildtypes/google-worker/v1
                externalParameters:
                  buildConfigSource:
                    path: cloudbuild.yaml
                    ref: refs/heads/main
                    repository: git+https://github.com/my-username/my-git-repo
                  substitutions: {}
                internalParameters:
                  systemSubstitutions:
                    BRANCH_NAME: main
                    BUILD_ID: e73ca1d4-ec4a-4ea6-acdd-ac8bb16dcc79
                    COMMIT_SHA: 525c52c501739e6df0609ed1f944c1bfd83224e7
                    LOCATION: us-west1
                    PROJECT_NUMBER: '265426041527'
                    REF_NAME: main
                    REPO_FULL_NAME: my-username/my-git-repo
                    REPO_NAME: my-git-repo
                    REVISION_ID: 525c52c501739e6df0609ed1f944c1bfd83224e7
                    SHORT_SHA: 525c52c
                    TRIGGER_BUILD_CONFIG_PATH: cloudbuild.yaml
                    TRIGGER_NAME: github-trigger-staging
                  triggerUri: projects/265426041527/locations/us-west1/triggers/a0d239a4-635e-4bd3-982b-d8b72d0b4bab
                resolvedDependencies:
                - digest:
                    gitCommit: 525c52c501739e6df0609ed1f944c1bfd83224e7
                  uri: git+https://github.com/my-username/my-git-repo@refs/heads/main
                - digest:
                    sha256: 154fcd4d2d65c6a35b06b98053a0829c581e223d530be5719326f5d85d680e8d
                  uri: gcr.io/cloud-builders/docker@sha256:154fcd4d2d65c6a35b06b98053a0829c581e223d530be5719326f5d85d680e8d
              runDetails:
                builder:
                  id: https://cloudbuild.googleapis.com/GoogleHostedWorker
                byproducts:
                - {}
                metadata:
                  finishedOn: '2023-08-01T19:57:10.734471Z'
                  invocationId: https://cloudbuild.googleapis.com/v1/projects/my-project/locations/us-west1/builds/e73ca1d4-ec4a-4ea6-acdd-ac8bb16dcc79
                  startedOn: '2023-08-01T19:56:57.451553160Z'
            predicateType: https://slsa.dev/provenance/v1
            subject:
            - digest:
                sha256: 7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3
              name: https://us-central1-docker.pkg.dev/my-project/my-repo/my-image
            - digest:
                sha256: 7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3
              name: https://us-central1-docker.pkg.dev/my-project/my-repo/my-image:latest
        createTime: '2023-08-01T19:57:14.810489Z'
        envelope:
          payload:
          eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdMWQ0LWVjNGEtNGVhNi1hY2RkLWFjOGJiMTZkY2M3OSIsICJzdGFydGVkT24iOiIyMDIzLTA4LTAxVDE5OjU2OjU3LjQ1MTU1MzE2MFoiLCAiZmluaXNoZWRPbiI6IjIwMjMtMDgtMDFUMTk6NTc6MTAuNzM0NDcxWiJ9LCAiYnlwcm9kdWN0cyI6W3t9XX19fQ==...
          payloadType: application/vnd.in-toto+json
          signatures:
          - keyid: projects/verified-builder/locations/global/keyRings/attestor/cryptoKeys/google-hosted-worker/cryptoKeyVersions/1
            sig: MEUCIQCss8UlQL2feFePRJuKTE8VA73f85iqj4OJ9SvVPqTNwAIgYyuyuIrl1PxQC5B109thO24Y6NA4bTa0PJY34EHRSVE=
        kind: BUILD
        name: projects/my-project/occurrences/71787589-c6a6-4d6a-a030-9fd041e40468
        noteName: projects/argo-qa/notes/intoto_slsa_v1_e73ca1d4-ec4a-4ea6-acdd-ac8bb16dcc79
        resourceUri: https://us-central1-docker.pkg.dev/my-project/my-repo/my-image@sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3
        updateTime: '2023-08-01T19:57:14.810489Z'
    

Alcuni aspetti importanti da notare in questo esempio:

  • Origine: la build è stata attivata da un repository GitHub.

  • Riferimento oggetto: i campi denominati digest e fileHash fanno riferimento allo stesso oggetto. Il campo digest incluso nell'output di esempio è codificato in base 16 (con codifica esadecimale). Se utilizzi la provenienza di SLSA versione 0.1, l'output utilizza il campo fileHash codificato in base 64.

  • Firme: se utilizzi la provenienza di SLSA versione 0.1, l'output contiene due firme nel campo envelope. La prima firma, con il nome della chiave provenanceSigner, utilizza una firma conforme a DSSE (formattata con la codifica di pre-autenticazione (PAE)), che può essere verificata nei criteri relativi all'autorizzazione binaria. Ti consigliamo di utilizzare questa firma nei nuovi utilizzi di questa provincia. La seconda firma, con il nome della chiave builtByGCB, viene fornita per l'utilizzo precedente.

  • Account di servizio: le firme che vengono incluse automaticamente nella provenienza di Cloud Build ti aiutano a verificare il servizio di build che ha eseguito una build. Puoi anche configurare Cloud Build per registrare metadati verificabili sull'account di servizio usato per avviare una build. Per maggiori informazioni, consulta Firmare le immagini dei container con cosign.

  • Payload: la provenienza dell'esempio visualizzata in questa pagina è abbreviata per migliorarne la leggibilità. L'output effettivo sarà più lungo, poiché il payload è una versione con codifica Base64 di tutti i metadati di provenienza.

Visualizza la provenienza degli artefatti non containerizzati

Cloud Build genera metadati di provenienza SLSA per applicazioni Java (Maven), Python e Node.js (npm) autonome quando carichi gli artefatti della build in Artifact Registry.

  1. Per generare i metadati di provenienza per i tuoi artefatti, esegui una build con Cloud Build. Utilizza una delle seguenti guide:

    Quando la build è completata, prendi nota del BuildID.

  2. Esegui la seguente chiamata API nel tuo terminale, dove PROJECT_ID è l'ID associato al tuo progetto Google Cloud:

    alias gcurl='curl -H"Authorization: Bearer $(gcloud auth print-access-token)"'
        gcurl 'https://containeranalysis.googleapis.com/v1/projects/PROJECT_ID/occurrences'
    

    Nelle occorrenze del tuo progetto, cerca per BuildID per trovare le informazioni di provenienza associate a ogni artefatto della build.

Convalida la provenienza

Questa sezione spiega come convalidare la provenienza della build per le immagini container.

La convalida della provenienza della build ti aiuta a:

  • per confermare che gli artefatti di build vengano generati da origini e builder attendibili
  • garantire che i metadati di provenienza che descrivono il processo di compilazione siano completi

Per maggiori informazioni, vedi Build di salvaguardia.

Convalida la provenienza utilizzando lo strumento di verifica SLSA

Lo strumento di verifica SLSA è uno strumento di interfaccia a riga di comando open source per convalidare l'integrità della build in base alle specifiche SLSA.

Se lo strumento di verifica individua dei problemi, restituisce messaggi di errore dettagliati per aiutarti ad aggiornare il processo di compilazione e mitigare i rischi.

Per utilizzare lo strumento di verifica SLSA:

  1. Installa la versione 2.1 o successive dal repository slsa-verifier:

    go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@VERSION
    
  2. Nell'interfaccia a riga di comando, imposta una variabile per l'identificatore immagine:

    export IMAGE=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH
    

    Sostituisci i valori segnaposto nel comando con i seguenti:

    • LOCATION: località a livello di una o più regioni.
    • PROJECT_ID: ID progetto Google Cloud.
    • REPOSITORY: nome del repository.
    • IMAGE: nome immagine.
    • HASH: il valore hash sha256 dell'immagine. Puoi trovarlo nell'output della build.
  3. Autorizza gcloud CLI in modo che lo strumento di verifica SLSA possa accedere ai dati di provenienza:

    gcloud auth configure-docker LOCATION-docker.pkg.dev
    
  4. Recupera la provenienza dell'immagine e archiviala come JSON:

    gcloud artifacts docker images describe $IMAGE --format json --show-provenance > provenance.json
    
  5. Verifica la provenienza:

    slsa-verifier verify-image "$IMAGE" \
    --provenance-path provenance.json \
    --source-uri SOURCE \
    --builder-id=BUILDER_ID
    

    Dove:

    • SOURCE è l'URI del repository di origine dell'immagine, ad esempio github.com/my-repo/my-application.
    • BUILDER_ID l'ID univoco per il generatore, ad esempio https://cloudbuild.googleapis.com/GoogleHostedWorker

    Se vuoi stampare la provenienza convalidata per l'utilizzo in un motore dei criteri, usa il comando precedente con il flag --print-provenance.

    L'output è simile al seguente: PASSED: Verified SLSA provenance o FAILED: SLSA verification failed: <error details>.

Per ulteriori informazioni sui flag facoltativi, vedi le opzioni.

Convalida i metadati di provenienza con gcloud CLI

Se vuoi verificare che i metadati relativi alla provenienza della build non siano stati manomessi, puoi convalidarla eseguendo questi passaggi:

  1. Crea una nuova directory e vai a quella directory.

    mkdir provenance && cd provenance
    
  2. Recupera la chiave pubblica utilizzando le informazioni contenute nel campo keyid.

    gcloud kms keys versions get-public-key 1 --location global --keyring attestor \
      --key builtByGCB --project verified-builder --output-file my-key.pub
    
  3. payload contiene la rappresentazione JSON della provenienza, codificata in base64url. Decodifica i dati e archiviali in un file.

    gcloud artifacts docker images describe \
    LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \
      --format=json | jq -r '.provenance_summary.provenance[] | select(.build.intotoStatement.predicateType == "https://slsa.dev/provenance/v0.1") | .envelope.payload' | tr '\-_' '+/' | base64 -d > provenance.json
    

    Entrambi i tipi di provenienza SLSA versione 0.1 e 1.0 sono memorizzati quando disponibili. Se vuoi filtrare in base alla versione 1.0, modifica predicateType in modo da utilizzare https://slsa.dev/provenance/v1. Ad esempio:

    gcloud artifacts docker images describe \
    LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \
      --format=json | jq -r '.provenance_summary.provenance[] | select(.build.intotoStatement.predicateType == "https://slsa.dev/provenance/v1") | .envelope.payload' | tr '\-_' '+/' | base64 -d > provenance.json
    
  4. La busta contiene anche la firma sulla provenienza. Decodificare i dati e archiviarli in un file.

      gcloud artifacts docker images describe LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \
      --format=json | '.provenance_summary.provenance[] | select(.build.intotoStatement.predicateType == "https://slsa.dev/provenance/v0.1") | .envelope.signatures[0].sig' | tr '\-_' '+/' | base64 -d > signature.bin
    

    Se vuoi filtrare in base alla versione 1.0, modifica predicateType in modo da utilizzare https://slsa.dev/provenance/v1. Ad esempio:

    gcloud artifacts docker images describe LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \
    --format=json | jq -r '.provenance_summary.provenance[] | select(.build.intotoStatement.predicateType == "https://slsa.dev/provenance/v1") | .envelope.signatures[0].sig' | tr '\-_' '+/' | base64 -d > signature.bin
    
  5. Il comando riportato sopra fa riferimento alla prima firma di provenienza (.provenance_summary.provenance[0].envelope.signatures[0]) firmata dalla chiave provenanceSigner. Il payload viene firmato sulla busta in formato PAE. Per verificarlo, esegui questo comando per trasformare la provenienza nel formato PAE previsto di "DSSEv1" + SP + LEN(type) + SP + type + SP + LEN(body) + SP + body.

    echo -n "DSSEv1 28 application/vnd.in-toto+json $(cat provenance.json | wc -c) $(cat provenance.json)" > provenance.json
    
  6. Convalida la firma.

    openssl dgst -sha256 -verify my-key.pub -signature signature.bin provenance.json
    

    Dopo una convalida riuscita, l'output è Verified OK.

Passaggi successivi