Générer et valider la provenance de la compilation

Cette page explique comment générer la provenance du build, afficher le résultat et le valider.

La provenance du build est une collection de données vérifiables concernant un build. Les métadonnées de provenance incluent des détails tels que les condensés des images compilées, les emplacements de la source d'entrée, les arguments de la compilation et la durée de compilation. Vous pouvez utiliser ces informations pour vous assurer que les artefacts créés que vous utilisez sont précis et fiables, et qu'ils ont été créés par des sources et des créateurs de confiance.

Cloud Build permet de générer la provenance des builds qui répond au niveau d'assurance 3 des niveaux de la chaîne d'approvisionnement pour les artefacts logiciels (SLSA) en fonction des spécifications des versions 0.1 et 1.0 de SLSA.

Dans le cadre de la prise en charge de la spécification SLSA v1.0, Cloud Build fournit des détails buildType dans la provenance du build. Vous pouvez utiliser le schéma buildType pour comprendre le modèle paramétré utilisé pour le processus de compilation, y compris les valeurs enregistrées par Cloud Build et leur source. Pour en savoir plus, consultez buildType v1 de Cloud Build.

Limites

  • Cloud Build ne génère la provenance de la compilation que pour les artefacts stockés dans Artifact Registry.
  • Pour obtenir la provenance SLSA v1.0 et v0.1, vous devez effectuer la compilation à l'aide de déclencheurs. Si vous démarrez une compilation manuellement à l'aide de la gcloud CLI, Cloud Build ne fournit que la provenance SLSA v0.1.
  • Les pièces jointes des dépôts Docker, y compris la provenance des compilations, ne sont pas soumises aux règles de nettoyage. En revanche, les pièces jointes sont supprimées lorsque l'image à laquelle elles sont associées est supprimée. Pour en savoir plus, consultez Gérer les pièces jointes avec des règles de nettoyage.

Avant de commencer

  1. Enable the Cloud Build, Container Analysis, and Artifact Registry APIs.

    Enable the APIs

  2. Pour utiliser les exemples de ligne de commande de ce guide, installez et configurez le SDK Google Cloud.

  3. Gardez votre code source à portée de main.

  4. Disposer d'un dépôt dans Artifact Registry.

Générer la provenance du build

Les instructions suivantes expliquent comment générer la provenance de la compilation pour les images de conteneurs que vous stockez dans Artifact Registry :

  1. Dans votre fichier de configuration de compilation, ajoutez le champ images pour configurer Cloud Build afin qu'il stocke vos images compilées dans Artifact Registry une fois la compilation terminée.

    Cloud Build ne peut pas générer de provenance si vous transférez votre image vers Artifact Registry à l'aide d'une étape docker push explicite.

    L'extrait suivant présente une configuration de compilation qui génère une image de conteneur et la stocke dans un dépôt Docker dans 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']
    

    Où :

    • LOCATION : emplacement régional ou multirégional de votre dépôt.
    • PROJECT_ID : ID de votre projet Google Cloud .
    • REPOSITORY : nom de votre dépôt Artifact Registry
    • IMAGE : nom de votre image de conteneur.

    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"
      ]
      }
    

    Où :

    • LOCATION : emplacement régional ou multirégional de votre dépôt.
    • PROJECT_ID : ID de votre projet Google Cloud .
    • REPOSITORY : nom de votre dépôt Artifact Registry
    • IMAGE : nom de votre image de conteneur.
  2. Dans la section options de votre configuration de compilation, ajoutez l'option requestedVerifyOption et définissez-la sur la valeur VERIFIED.

    Ce paramètre permet de générer la provenance et configure Cloud Build pour vérifier que les métadonnées de provenance sont présentes. Les compilations ne seront marquées comme réussies que si la provenance est générée.

    YAML

    options:
      requestedVerifyOption: VERIFIED
    

    JSON

    {
        "options": {
            "requestedVerifyOption": "VERIFIED"
        }
    }
    
  3. Lancez votre compilation.

Afficher la provenance du build

Cette section explique comment afficher les métadonnées de provenance du build créées par Cloud Build. Vous pouvez récupérer ces informations à des fins d'audit.

Vous pouvez accéder aux métadonnées de provenance des compilations pour les conteneurs à l'aide du panneau latéral Informations sur la sécurité dans la console Google Cloud ou à l'aide de la gcloud CLI.

Console

Le panneau latéral Insights sur la sécurité fournit un aperçu général des informations de sécurité pour les artefacts stockés dans Artifact Registry.

Pour afficher le panneau Insights sur la sécurité :

  1. Ouvrez la page Historique de compilation dans la console Google Cloud  :

    Ouvrir la page Historique de compilation

  2. Dans le tableau des compilations, recherchez la ligne correspondant à la compilation pour laquelle vous souhaitez afficher les insights sur la sécurité.

  3. Dans la colonne Insights sur la sécurité, cliquez sur Afficher.

    Le panneau Insights sur la sécurité de l'artefact sélectionné s'affiche.

    La fiche Compilation affiche les détails de la provenance et un lien. Pour afficher l'extrait de provenance, cliquez sur l'icône en forme de lien.

Pour en savoir plus sur le panneau latéral et sur la façon dont vous pouvez utiliser Cloud Build pour protéger votre chaîne d'approvisionnement logicielle, consultez Afficher les insights de sécurité des compilations.

CLI gcloud

Pour afficher les métadonnées de provenance des images de conteneurs, exécutez la commande suivante :

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

Remplacez les éléments suivants :

  • LOCATION : emplacement régional ou multirégional de votre dépôt.
  • PROJECT_ID : ID de votre projet Google Cloud .
  • REPOSITORY : nom de votre dépôt Artifact Registry.
  • IMAGE : nom de votre image de conteneur.
  • HASH : valeur de hachage sha256 de l'image. Vous la trouverez dans le résultat de votre compilation.
  • FORMAT : paramètre facultatif permettant de spécifier un format de sortie.

Exemple de résultat :

La provenance de la compilation ressemble à ce qui suit :

      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'
    

Voici quelques points importants à noter dans cet exemple :

  • Source : la compilation a été déclenchée à partir d'un dépôt GitHub.

  • Référence d'objet : les champs nommés digest et fileHash font référence au même objet. Le champ digest inclus dans l'exemple de résultat est encodé en base 16 (encodage hexadécimal). Si vous utilisez la provenance SLSA version 0.1, votre sortie utilise le champ fileHash encodé en base64.

  • Signatures : si vous utilisez la provenance SLSA version 0.1, votre résultat contient deux signatures dans le champ envelope. La première signature, dont le nom de clé est provenanceSigner, utilise une signature conforme à DSSE (mise en forme avec l'encodage de pré-authentification (PAE)), qui peut être validée dans les règles Autorisation binaire. Nous vous recommandons d'utiliser cette signature pour les nouvelles utilisations de cette provenance. La deuxième signature, dont le nom de clé est builtByGCB, est fournie pour l'ancienne utilisation.

  • Comptes de service : les signatures incluses automatiquement dans la provenance Cloud Build vous aident à vérifier le service de compilation qui a exécuté une compilation. Vous pouvez également configurer Cloud Build pour qu'il enregistre des métadonnées vérifiables sur le compte de service utilisé pour lancer une compilation. Pour en savoir plus, consultez Signer des images de conteneurs avec Cosign.

  • Charge utile : l'exemple de provenance affiché sur cette page est abrégé pour une meilleure lisibilité. Le résultat réel sera plus long, car la charge utile est une version encodée en base64 de toutes les métadonnées de provenance.

  • Dépendances : les dépendances que vous spécifiez dans votre fichier de compilation sont incluses dans la provenance, dans le champ resolvedDependencies.

Afficher la provenance des artefacts non issus de conteneurs

Cloud Build génère des métadonnées de provenance SLSA pour les applications autonomes Go, Java (Maven), Python et Node.js (npm) lorsque vous importez vos artefacts de compilation dans Artifact Registry. Vous pouvez récupérer les métadonnées de provenance en effectuant un appel d'API direct.

  1. Pour générer les métadonnées de provenance de vos artefacts, exécutez une compilation avec Cloud Build. Consultez l'un des guides suivants :

    Une fois la compilation terminée, notez le BuildID.

  2. Récupérez les métadonnées de provenance en exécutant l'appel d'API suivant dans votre terminal, où PROJECT_ID correspond à l'ID associé à votre projet Google Cloud  :

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

    Vous devez utiliser un appel d'API pour accéder aux métadonnées de provenance de ce type d'artefact. Les métadonnées de provenance pour les artefacts non conteneurisés ne sont pas affichées dans la console Google Cloud ni accessibles via gcloud CLI.

  3. Dans les occurrences de votre projet, recherchez par BuildID pour trouver les informations de provenance associées à un artefact de compilation.

Valider la provenance

Cette section explique comment valider la provenance du build pour les images de conteneurs.

La validation de la provenance de la compilation vous aide à :

  • confirmer que les artefacts de compilation sont générés à partir de sources et de compilateurs fiables ;
  • Assurez-vous que les métadonnées de provenance décrivant votre processus de compilation sont complètes et authentiques.

Pour en savoir plus, consultez Protéger les compilations.

Valider la provenance à l'aide du vérificateur SLSA

Le vérificateur SLSA est un outil de CLI Open Source permettant de valider l'intégrité des compilations en fonction des spécifications SLSA.

Si le vérificateur détecte des problèmes, il renvoie des messages d'erreur détaillés pour vous aider à mettre à jour votre processus de compilation et à atténuer les risques.

Pour utiliser le vérificateur SLSA, procédez comme suit :

  1. Installez la version 2.1 ou ultérieure à partir du dépôt slsa-verifier.

    go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@VERSION
    
  2. Dans votre CLI, définissez une variable pour l'identifiant de votre image :

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

    Où :

    • LOCATION : emplacement régional ou multirégional.
    • PROJECT_ID : ID du projet Google Cloud
    • REPOSITORY : nom du dépôt.
    • IMAGE : nom de l'image.
    • HASH : valeur de hachage sha256 de l'image. Vous la trouverez dans le résultat de votre compilation.
  3. Autorisez gcloud CLI afin que le vérificateur SLSA puisse accéder à vos données de provenance :

    gcloud auth configure-docker LOCATION-docker.pkg.dev
    
  4. Récupérez la provenance de votre image et stockez-la sous le nom JSON :

    gcloud artifacts docker images describe $IMAGE --format json --show-provenance > provenance.json
    
  5. Vérifiez la provenance :

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

    Où :

    • SOURCE correspond à l'URI du dépôt source de votre image, par exemple github.com/my-repo/my-application.
    • BUILDER_ID : identifiant unique du compilateur, par exemple https://cloudbuild.googleapis.com/GoogleHostedWorker

    Si vous souhaitez imprimer la provenance validée pour l'utiliser dans un moteur de règles, utilisez la commande précédente avec l'option --print-provenance.

    Le résultat ressemble à ce qui suit : PASSED: Verified SLSA provenance ou FAILED: SLSA verification failed: <error details>.

Pour en savoir plus sur les options facultatives, consultez la section Options.

Valider les métadonnées de provenance avec gcloud CLI

Si vous souhaitez vérifier que les métadonnées de provenance de la compilation n'ont pas été altérées, vous pouvez valider la provenance en procédant comme suit :

  1. Créez un répertoire, puis accédez-y.

    mkdir provenance && cd provenance
    
  2. À l'aide des informations du champ keyid, obtenez la clé publique.

    gcloud kms keys versions get-public-key 1 --location global --keyring attestor \
      --key builtByGCB --project verified-builder --output-file my-key.pub
    
  3. payload contient la représentation JSON de la provenance, encodée en base64url. Décodez les données et les stockez-les dans un fichier.

    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
    

    Les types de provenance SLSA versions 0.1 et 1.0 sont stockés lorsqu'ils sont disponibles. Si vous souhaitez filtrer la version 1.0, remplacez predicateType par https://slsa.dev/provenance/v1. Exemple :

    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. L'enveloppe contient également la signature sur la provenance. Décodez les données et stockez-les dans un fichier.

      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.signatures[0].sig' | tr '\-_' '+/' | base64 -d > signature.bin
    

    Si vous souhaitez filtrer la version 1.0, remplacez predicateType par https://slsa.dev/provenance/v1. Exemple :

    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. La commande ci-dessus fait référence à la première signature de provenance (.provenance_summary.provenance[0].envelope.signatures[0]), qui est signée par la clé provenanceSigner. La charge utile est signée sur l'enveloppe au format PAE. Pour le vérifier, exécutez cette commande afin de transformer la provenance au format PAE attendu de "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. Validez la signature.

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

    Après une validation réussie, le résultat est Verified OK.

Étapes suivantes