Gere e valide a proveniência da compilação

Esta página fornece instruções sobre como gerar a proveniência da compilação, ver o resultado e validá-lo.

A origem da compilação é uma coleção de dados validáveis sobre uma compilação. Os metadados de proveniência incluem detalhes como os resumos das imagens criadas, as localizações das origens de entrada, os argumentos de criação e a duração da criação. Pode usar estas informações para garantir que os artefactos criados que está a usar são precisos e fiáveis, criados por fontes e criadores fidedignos.

O Cloud Build suporta a geração de proveniência da compilação que cumpre a garantia de nível 3 dos níveis da cadeia de fornecimento para artefactos de software (SLSA) com base nas especificações da versão 0.1 e 1.0 do SLSA.

Como parte do suporte para a especificação SLSA v1.0, o Cloud Build fornece detalhes de buildType na proveniência da compilação. Pode usar o esquema buildType para compreender o modelo parametrizado usado para o processo de compilação, incluindo os valores que o Cloud Build regista e a origem desses valores. Para mais informações, consulte o artigo buildType v1 do Cloud Build.

Limitações

  • O Cloud Build só gera a proveniência da compilação para artefactos armazenados no Artifact Registry.
  • Para obter a proveniência SLSA v1.0 e v0.1, tem de criar usando acionadores. Se iniciar uma compilação manualmente através da CLI gcloud, o Cloud Build fornece apenas proveniência SLSA v0.1.
  • Os anexos do repositório Docker, incluindo a proveniência da compilação, não estão sujeitos a políticas de limpeza. Em alternativa, os anexos são eliminados quando a imagem à qual estão anexados é eliminada. Para mais informações, consulte o artigo Faça a gestão de anexos com políticas de limpeza.

Antes de começar

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

    Enable the APIs

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

  3. Tenha o código-fonte à mão.

  4. Ter um repositório no Artifact Registry.

Gere a proveniência da compilação

As instruções seguintes explicam como gerar a proveniência da compilação para imagens de contentores que armazena no Artifact Registry:

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

    O Cloud Build não pode gerar a proveniência se enviar a sua imagem para o Artifact Registry através de um passo docker push explícito.

    O seguinte fragmento mostra uma configuração de compilação para compilar uma imagem de contentor e armazenar a imagem num 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']
    

    Onde:

    • LOCATION: a localização regional ou multirregional do seu repositório.
    • PROJECT_ID: o ID do seu Google Cloud projeto.
    • REPOSITORY: o nome do seu repositório do Artifact Registry.
    • IMAGE: o nome da imagem do contentor.

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

    Onde:

    • LOCATION: a localização regional ou multirregional do seu repositório.
    • PROJECT_ID: o ID do seu Google Cloud projeto.
    • REPOSITORY: o nome do seu repositório do Artifact Registry.
    • IMAGE: o nome da imagem do contentor.
  2. Na secção options da configuração de compilação, adicione a opção requestedVerifyOption e defina o valor VERIFIED.

    Esta definição ativa a geração de proveniência e configura o Cloud Build para verificar se os metadados de proveniência estão presentes. As compilações só são marcadas como bem-sucedidas se for gerada a proveniência.

    YAML

    options:
      requestedVerifyOption: VERIFIED
    

    JSON

    {
        "options": {
            "requestedVerifyOption": "VERIFIED"
        }
    }
    
  3. Comece a criar.

Veja a proveniência da compilação

Esta secção explica como ver os metadados de proveniência da compilação criados pelo Cloud Build. Pode obter estas informações para fins de auditoria.

Pode aceder aos metadados de proveniência da compilação para contentores através do painel lateral Estatísticas de segurança na Google Cloud consola ou através da CLI gcloud.

consola

O painel lateral Estatísticas de segurança oferece uma vista geral de alto nível das informações de segurança dos artefactos armazenados no Artifact Registry.

Para ver o painel Estatísticas de segurança:

  1. Abra a página Histórico de compilações na Google Cloud consola:

    Abra a página Histórico de compilação

  2. Na tabela com as compilações, localize a linha com a compilação para a qual quer ver estatísticas de segurança.

  3. Na coluna Estatísticas de segurança, clique em Ver.

    É apresentado o painel Informações de segurança para o artefacto selecionado.

    O cartão Criar apresenta detalhes de proveniência e um link. Pode ver o fragmento de proveniência clicando no ícone de link.

Para saber mais sobre o painel lateral e como pode usar o Cloud Build para ajudar a proteger a sua cadeia de fornecimento de software, consulte o artigo Veja estatísticas de segurança de compilação.

CLI gcloud

Para ver os metadados de proveniência das imagens de contentores, execute o seguinte comando:

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

Substitua o seguinte:

  • LOCATION: a localização regional ou multirregional do seu repositório.
  • PROJECT_ID: o ID do seu Google Cloud projeto.
  • REPOSITORY: o nome do seu repositório do Artifact Registry.
  • IMAGE: o nome da imagem do contentor.
  • HASH: o valor hash sha256 da imagem. Pode encontrar esta informação no resultado da compilação.
  • FORMAT: uma definição opcional onde pode especificar um formato de saída.

Exemplo de resultado

A proveniência da compilação é semelhante à seguinte:

      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'
    

Seguem-se alguns aspetos importantes a ter em conta neste exemplo:

  • Origem: a compilação foi acionada a partir de um repositório do GitHub.

  • Referência de objeto: os campos com os nomes digest e fileHash referem-se ao mesmo objeto. O campo digest incluído no exemplo de saída está codificado em base 16 (codificado no formato hexadecimal). Se estiver a usar a proveniência da versão 0.1 da SLSA, o resultado usa o campo fileHash codificado em base 64.

  • Assinaturas: se estiver a usar a proveniência da versão 0.1 da SLSA, o resultado contém duas assinaturas no campo envelope. A primeira assinatura, que tem o nome da chave provenanceSigner, usa uma assinatura em conformidade com DSSE (formatada com codificação de pré-autenticação [PAE]), que pode ser validada nas políticas de autorização binária. Recomendamos que use esta assinatura em novas utilizações desta proveniência. A segunda assinatura, que tem o nome da chave builtByGCB, é fornecida para utilização antiga.

  • Contas de serviço: as assinaturas incluídas automaticamente na proveniência do Cloud Build ajudam a validar o serviço de compilação que executou uma compilação. Também pode configurar o Cloud Build para registar metadados validáveis acerca da conta de serviço usada para iniciar uma compilação. Para mais informações, consulte o artigo Assine imagens de contentores com o Cosign.

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

  • Dependências: as dependências que especificar no ficheiro de compilação são incluídas na proveniência, no campo resolvedDependencies.

Veja a proveniência de artefactos que não são contentores

O Cloud Build gera metadados de proveniência SLSA para aplicações autónomas Go, Java (Maven), Python e Node.js (npm) quando carrega os artefactos de compilação para o Artifact Registry. Pode obter os metadados de proveniência fazendo uma chamada API direta.

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

    Quando a compilação estiver concluída, tome nota do BuildID.

  2. Recupere os metadados de proveniência executando a seguinte chamada da API no seu terminal, onde PROJECT_ID é o ID associado ao seu projeto: Google Cloud

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

    Tem de usar uma chamada API para aceder aos metadados de proveniência deste tipo de artefacto. Os metadados de proveniência para artefactos não contentorizados não são apresentados na Google Cloud consola nem acessíveis através da CLI gcloud.

  3. Nas ocorrências do seu projeto, pesquise por BuildID para encontrar as informações de proveniência associadas a um artefacto de compilação.

Valide a proveniência

Esta secção explica como validar a proveniência da compilação para imagens de contentores.

A validação da proveniência da compilação ajuda a:

  • confirmar que os artefactos de compilação estão a ser gerados a partir de fontes e compiladores fidedignos
  • garantir que os metadados de proveniência que descrevem o processo de compilação estão completos e são autênticos

Para mais informações, consulte o artigo Salvaguarde as compilações.

Valide a proveniência através do verificador SLSA

O validador SLSA é uma ferramenta CLI de código aberto para validar a integridade da compilação com base nas especificações SLSA.

Se o validador encontrar problemas, devolve mensagens de erro detalhadas para ajudar a atualizar o processo de compilação e mitigar os riscos.

Para usar o validador SLSA, faça o seguinte:

  1. Instale a versão 2.1 ou superior a partir do 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 da imagem:

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

    Onde:

    • LOCATION: Localização regional ou multirregional.
    • PROJECT_ID: Google Cloud ID do projeto.
    • REPOSITORY: nome do repositório.
    • IMAGE: nome da imagem.
    • HASH: o valor hash sha256 da imagem. Pode encontrar esta opção no resultado da compilação.
  3. Autorize a CLI gcloud para que o validador SLSA possa aceder aos seus dados de proveniência:

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

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

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

    Onde:

    • 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 criador, por exemplo, https://cloudbuild.googleapis.com/GoogleHostedWorker

    Se quiser imprimir a proveniência validada para utilização num motor de políticas, use o comando anterior com a flag --print-provenance.

    O resultado é semelhante ao seguinte: PASSED: Verified SLSA provenance ou FAILED: SLSA verification failed: <error details>.

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

Valide os metadados de proveniência com a CLI gcloud

Se quiser validar se os metadados de proveniência da compilação não foram adulterados, pode validar a proveniência seguindo estes passos:

  1. Crie um novo diretório e aceda a esse diretório.

    mkdir provenance && cd provenance
    
  2. Com as informações do campo keyid, obtenha 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 elemento payload contém a representação JSON da proveniência, codificada em base64url. Descodifique os dados e armazene-os num ficheiro.

    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 proveniência da versão 0.1 e 1.0 da SLSA são armazenados quando disponíveis. Se quiser filtrar pela versão 1.0, altere o predicateType para usar https://slsa.dev/provenance/v1. Por 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 proveniência. Descodifique os dados e armazene-os num ficheiro.

      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
    

    Se quiser filtrar pela versão 1.0, altere o predicateType para usar https://slsa.dev/provenance/v1. Por 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 proveniência (.provenance_summary.provenance[0].envelope.signatures[0]), que é assinada pela chave provenanceSigner. O payload é assinado através do envelope formatado em PAE. Para a validar, execute este comando para transformar a proveniê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. Validar a assinatura.

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

    Após uma validação bem-sucedida, o resultado é Verified OK.

O que se segue?