Gerar e validar a procedência do build

Esta página fornece instruções sobre como gerar a procedência do build, visualizar a saída e validá-la.

A procedência do build é uma coleção de dados verificáveis sobre um build. Os metadados de procedência incluem detalhes como os resumos das imagens criadas, os locais de origem da entrada, os argumentos e a duração do build. É possível usar essas informações para garantir que os artefatos criados sejam precisos e confiáveis, criados por fontes e criadores confiáveis.

O Cloud Build oferece suporte à geração de procedências que atendam à garantia de nível 3 da cadeia de suprimentos para artefatos de software (SLSA) com base nas especificações das versões de SLSA 0.1 e 1.0.

Como parte do suporte à especificação SLSA v1.0, o Cloud Build fornece detalhes de buildType na procedência do build. É possível usar o esquema buildType para entender o modelo parametrizado usado no processo de compilação, incluindo os valores que o Cloud Build registra e a origem desses valores. Para mais informações, consulte Cloud Build buildType v1.

Limitações

  • O Cloud Build só gera a procedência do build para artefatos armazenados no Artifact Registry.
  • Para conseguir a procedência do SLSA v1.0 e v0.1, você precisa criar usando acionadores. Se você iniciar uma versão manualmente usando a gcloud CLI, o Cloud Build fornecerá apenas a procedência SLSA v0.1.

Antes de começar

  1. Ative as APIs Cloud Build, Container Analysis, and Artifact Registry.

    Ative as APIs

  2. Para usar os exemplos de linha de comando neste guia, instale e configure o SDK Google Cloud.

  3. Tenha o código-fonte em mãos.

  4. Ter um repositório no Artifact Registry.

Gerar procedência do build

As instruções abaixo explicam como gerar a procedência do build para imagens de contêiner armazenadas no Artifact Registry:

  1. No arquivo de configuração do build, adicione o campo images para configurar o Cloud Build para armazenar as imagens criadas no Artifact Registry após a conclusão do build.

    O Cloud Build não poderá gerar procedência se você enviar a imagem para o Artifact Registry usando uma etapa docker push explícita.

    O snippet a seguir mostra uma configuração de build para criar uma imagem de contêiner e armazenar a imagem em um repositório do Docker no 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']
    

    Em que:

    • LOCATION: o local regional ou multirregional do seu repositório.
    • PROJECT_ID: é seu ID do projeto no Google Cloud.
    • REPOSITORY: o nome do repositório do Artifact Registry
    • IMAGE: o nome da imagem do contêiner.

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

    Em que:

    • LOCATION: o local regional ou multirregional do seu repositório.
    • PROJECT_ID: é seu ID do projeto no Google Cloud.
    • REPOSITORY: o nome do repositório do Artifact Registry
    • IMAGE: o nome da imagem do contêiner.
  2. Na seção options da configuração da versão, adicione a opção requestedVerifyOption e defina como o valor VERIFIED.

    Essa configuração ativa a geração da procedência e configura o Cloud Build para verificar se os metadados da procedência estão presentes. Os builds só serão marcados como bem-sucedidos se a procedência for gerada.

    YAML

    options:
      requestedVerifyOption: VERIFIED
    

    JSON

    {
        "options": {
            "requestedVerifyOption": "VERIFIED"
        }
    }
    
  3. Comece o build.

Ver a origem do build

Nesta seção, explicamos como ver os metadados de procedência do build criados pelo Cloud Build. É possível buscar essas informações para fins de auditoria.

É possível acessar os metadados da procedência do build para contêineres usando o painel lateral Insights de segurança no console do Google Cloud ou usando a CLI gcloud.

Console

O painel lateral Insights de segurança fornece uma visão geral de alto nível das informações de segurança para artefatos armazenados no Artifact Registry.

Para ver o painel Insights de segurança, faça o seguinte:

  1. Abra a página Histórico de builds no console do Google Cloud:

    Abrir a página "Histórico de criações"

  2. Selecione o projeto e clique em Abrir.

  3. No menu suspenso Região, selecione a região em que você executou o build.

  4. Na tabela com os builds, localize a linha com o build que você quer ver insights de segurança.

  5. Na coluna Insights de segurança, clique em Visualizar.

    O painel Insights de segurança do artefato selecionado será exibido.

    O card Build mostra detalhes da procedência e um link. Para conferir o snippet de procedência, clique no ícone de link.

Para saber mais sobre o painel lateral e como usar o Cloud Build para ajudar a proteger sua cadeia de suprimentos de software, consulte Ver insights de segurança do build.

CLI da gcloud

Para exibir metadados de procedência das imagens de contêiner, execute o seguinte comando:

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

Substitua:

  • LOCATION: o local regional ou multirregional do seu repositório.
  • PROJECT_ID: é seu ID do projeto no Google Cloud.
  • REPOSITORY: o nome do repositório do Artifact Registry.
  • IMAGE: o nome da imagem do contêiner.
  • HASH: o valor de hash sha256 da imagem. Isso pode ser encontrado na saída do seu build.
  • FORMAT: uma configuração opcional em que é possível especificar um formato de saída.

Exemplo de saída

A procedência do build é semelhante a esta:

      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'
    

Alguns pontos importantes a serem observados neste exemplo:

  • Origem: o build foi acionado de um repositório do GitHub.

  • Referência de objeto: os campos denominados digest e fileHash se referem ao mesmo objeto. O campo digest incluído na saída de exemplo é codificado na base 16 (codificado em hexadecimal). Se você estiver usando a procedência da SLSA versão 0.1, a saída usará o campo fileHash codificado na base 64.

  • Assinaturas: se você estiver usando a procedência do SLSA versão 0.1, sua saída conterá duas assinaturas no campo envelope. A primeira assinatura, que tem o nome de chave provenanceSigner, usa uma assinatura em conformidade com o DSSE (formatada com codificação de pré-autenticação (PAE, na sigla em inglês)), que pode ser verificada nas políticas de autorização binária. Recomendamos que você use essa assinatura em novos usos dessa procedência. A segunda assinatura, que tem o nome de chave builtByGCB, é fornecida para uso legado.

  • Contas de serviço: as assinaturas incluídas automaticamente na procedência do Cloud Build ajudam a verificar o serviço de compilação que executou uma compilação. Também é possível configurar o Cloud Build para registrar metadados verificáveis sobre a conta de serviço usada para iniciar um build. Para mais informações, consulte Assinar imagens de contêiner com cosign.

  • Payload: a procedência de exemplo exibida nesta página foi reduzida para facilitar a leitura. A saída real será mais longa, já que o payload é uma versão codificada em base64 de todos os metadados de procedência.

Conferir a procedência dos artefatos que não são de contêiner

O Cloud Build gera metadados de procedência SLSA para aplicativos independentes Java (Maven), Python e Node.js (npm) quando você faz upload dos artefatos de build para o Artifact Registry.

  1. Para gerar os metadados de procedência dos artefatos, execute uma compilação com o Cloud Build. Use um dos seguintes guias:

    Quando o build for concluído, observe o BuildID.

  2. Execute a seguinte chamada de API no seu terminal, em que PROJECT_ID é o ID associado ao projeto do Google Cloud:

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

    Nas ocorrências do seu projeto, pesquise por BuildID para encontrar as informações de procedência associadas a cada artefato de build.

Validar procedência

Nesta seção, explicamos como validar a procedência do build para imagens de contêiner.

Validar a procedência do build ajuda você a:

  • confirmar se os artefatos de build estão sendo gerados de fontes e criadores confiáveis
  • garantir que os metadados de procedência que descrevem o processo de build sejam completos e autênticos;

Para mais informações, consulte Proteger builds.

Validar a procedência usando o verificador de SLSA

O verificador SLSA é uma ferramenta de CLI de código aberto para validar a integridade do build com base nas especificações de SLSA.

Se o verificador encontrar problemas, ele vai retornar mensagens de erro detalhadas para ajudar você a atualizar o processo de build e reduzir os riscos.

Para usar o verificador SLSA:

  1. Instale a versão 2.1 ou mais recente pelo repositório slsa-verifier:

    go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@VERSION
    
  2. Na CLI, defina uma variável para o identificador de imagem:

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

    Substitua os valores de marcador no comando pelo seguinte:

    • LOCATION: local regional ou multirregional.
    • PROJECT_ID: ID do projeto do Google Cloud
    • REPOSITORY: nome do repositório.
    • IMAGE: nome da imagem.
    • HASH: o valor de hash sha256 da imagem. Você pode encontrar isso na saída do seu build.
  3. Autorize a CLI gcloud para que o verificador de SLSA possa acessar os dados de procedência:

    gcloud auth configure-docker LOCATION-docker.pkg.dev
    
  4. Recupere a procedência da imagem e armazene-a como JSON:

    gcloud artifacts docker images describe $IMAGE --format json --show-provenance > provenance.json
    
  5. Verifique a procedência:

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

    Em que:

    • SOURCE é o URI do repositório de origem da sua imagem. Por exemplo, github.com/my-repo/my-application.
    • BUILDER_ID é o ID exclusivo do builder, por exemplo, https://cloudbuild.googleapis.com/GoogleHostedWorker.

    Se você quiser imprimir a procedência validada para uso em um mecanismo de políticas, use o comando anterior com a sinalização --print-provenance.

    A saída será semelhante a esta: PASSED: Verified SLSA provenance ou FAILED: SLSA verification failed: <error details>.

Para mais informações sobre sinalizações opcionais, consulte opções.

Validar metadados de procedência com a CLI gcloud

Se você quiser verificar se os metadados da procedência do build não foram adulterados, valide-a executando as seguintes etapas:

  1. Crie um novo diretório e acesse-o.

    mkdir provenance && cd provenance
    
  2. Usando as informações do campo keyid, acesse a chave pública.

    gcloud kms keys versions get-public-key 1 --location global --keyring attestor \
      --key builtByGCB --project verified-builder --output-file my-key.pub
    
  3. O payload contém a representação JSON da procedência, codificada em base64url. Decodifique os dados e armazene-os em um arquivo.

    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
    

    Os tipos de procedência do SLSA versões 0.1 e 1.0 são armazenados quando disponíveis. Se você quiser filtrar a versão 1.0, altere predicateType para usar https://slsa.dev/provenance/v1. Exemplo:

    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. O envelope também contém a assinatura sobre a procedência. Decodifique os dados e armazene-os em um arquivo.

      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 você quiser filtrar pela versão 1.0, altere predicateType para usar https://slsa.dev/provenance/v1. Exemplo:

    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. O comando acima faz referência à primeira assinatura de procedência (.provenance_summary.provenance[0].envelope.signatures[0]), assinada pela chave provenanceSigner. O payload é assinado sobre o envelope no formato PAE. Para verificá-lo, execute este comando e transforme a procedência no formato PAE esperado 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. Valide a assinatura.

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

    Após a validação, a saída é Verified OK.

A seguir