Crie atestações

Esta página descreve os passos para criar uma atestação de autorização binária.

Usa atestações para autorizar a implementação de imagens de contentores específicas em plataformas, como o Google Kubernetes Engine (GKE) e o Cloud Run. Para usar as atestações, tem de as exigir na regra adequada da sua política.

Uma única atestação pode autorizar imagens idênticas armazenadas em vários locais diferentes ou registos diferentes, como o Artifact Registry, o Container Registry ou um registo de contentores externo.

No momento da implementação, a autorização binária usa atestadores para validar as atestações.

Para configurar a Autorização binária no Cloud Run, GKE, Google Distributed Cloud e Cloud Service Mesh, consulte Configuração por plataforma e selecione a sua plataforma.

Utilizadores do GKE: para um tutorial completo que descreve a aplicação baseada em atestação através da autorização binária e do Google Kubernetes Engine (GKE), consulte os artigos Introdução à utilização da ferramenta de linha de comandos ou Introdução à utilização da consola Google Cloud .

Antes de começar

A vista geral das atestações fornece os passos a concluir antes de criar uma atestação.

  1. Ative a autorização binária

  2. Crie atestadores através da Google Cloud consola, da CLI do Google Cloud, ou da API REST.

Configure o ambiente

  1. Especifique os IDs dos seus projetos:

    ATTESTOR_PROJECT_ID=ATTESTOR_PROJECT_ID
    ATTESTATION_PROJECT_ID=ATTESTATION_PROJECT_ID
    

    Substitua o seguinte:

    • ATTESTOR_PROJECT_ID: o nome do projeto onde armazena os seus atestadores
    • ATTESTATION_PROJECT_ID: o nome do projeto onde armazena as suas atestações

    Se quiser que a atestação seja criada no mesmo projeto que os atestadores, use o mesmo ID do projeto para ambas as variáveis. Para um tutorial completo que demonstre a separação de funções com diferentes projetos, consulte o artigo Configuração de vários projetos.

  2. Especifique as informações do nome e da imagem do atestante:

    ATTESTOR_NAME=ATTESTOR_NAME
    IMAGE_PATH=IMAGE_PATH
    IMAGE_DIGEST=IMAGE_DIGEST
    IMAGE_TO_ATTEST="${IMAGE_PATH}@${IMAGE_DIGEST}"
    

    Substitua o seguinte:

    • ATTESTOR_NAME: o nome do atestador, por exemplo, build-secure ou prod-qa.
    • IMAGE_PATH: um URI que representa um caminho de imagem. Embora o URI tenha de incluir um domínio e um nome de imagem, não tem de se referir a uma imagem real. Não é acedido a imagens durante a criação da atestação. Seguem-se alguns exemplos de caminhos de imagens:

      • us-docker.pkg.dev/google-samples/containers/gke/hello-app
      • gcr.io/example-project/quickstart-image
      • example.com/hello-app.
    • IMAGE_DIGEST: o resumo do manifesto de imagens. Por exemplo, sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567 é o resumo da imagem associado ao caminho da imagem us-docker.pkg.dev/google-samples/containers/gke/hello-app de exemplo. Para saber como obter o resumo de uma imagem no Artifact Registry, consulte o artigo Gerir imagens; para uma imagem no Container Registry, consulte o artigo Listar as versões de uma imagem.

Conceda funções de gestão de identidade e de acesso

Para criar atestações, tem de conceder as seguintes funções de gestão de identidade e acesso (IAM) à identidade que cria o atestador, da seguinte forma:

  • roles/containeranalysis.notes.attacher no recurso de nota associado ao atestador.
  • roles/containeranalysis.occurrences.editor no recurso do projeto de atestação.

Cria uma atestação com base num atestador. O atestador está associado a uma nota de análise de artefactos. A criação de uma atestação, por sua vez, cria uma ocorrência de análise de artefactos e anexa-a à nota.

Saiba mais sobre como conceder acesso.

Para saber como criar uma atestação num pipeline do Cloud Build, consulte o artigo Criar atestações com o Cloud Build.

Crie uma atestação

Crie uma atestação com uma chave armazenada localmente

Para criar atestações assinadas com uma chave local, faça o seguinte:

  1. Crie um ficheiro de payload de assinatura:

    gcloud

    Para criar o ficheiro de payload da assinatura, introduza o seguinte comando:

    gcloud container binauthz create-signature-payload \
        --artifact-url="${IMAGE_TO_ATTEST}" > /tmp/generated_payload.json
    

    O ficheiro de payload formatado em JSON tem um aspeto semelhante ao seguinte resultado:

    {
      "critical": {
        "identity": {
          "docker-reference": "us-docker.pkg.dev/google-samples/containers/gke/hello-app"
        },
        "image": {
          "docker-manifest-digest": "sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567"
        },
        "type": "Google cloud binauthz container signature"
      }
    }
    

    API REST

    Crie um ficheiro de carga útil com o nome /tmp/generated_payload.json usando as variáveis de ambiente que definiu anteriormente neste documento:

    cat > /tmp/generated_payload.json << EOM
    {
      "critical": {
        "identity": {
          "docker-reference": "${IMAGE_PATH}"
        },
        "image": {
          "docker-manifest-digest": "${IMAGE_DIGEST}"
        },
        "type": "Google cloud binauthz container signature"
      }
    }
    EOM
    
  2. Assine a carga útil com a sua chave privada para gerar um ficheiro de assinatura.

    Este guia usa o algoritmo Elliptic Curve Digital Signature Algorithm (ECDSA) recomendado para a assinatura. Também pode usar o algoritmo RSA. Para mais informações sobre algoritmos de assinatura, consulte Finalidades e algoritmos das chaves. Este guia também usa o formato de assinatura da infraestrutura de chave pública (X.509) (PKIX). Também pode usar o PGP.

    PRIVATE_KEY_FILE=PRIVATE_KEY_FILE
    openssl dgst -sha256 -sign ${PRIVATE_KEY_FILE} /tmp/generated_payload.json > /tmp/ec_signature
    

    Substitua PRIVATE_KEY_FILE pelo caminho para a chave privada que gerou quando criou o atestador.

  3. Obtenha o ID da chave pública.

    Pode obter o ID da chave pública do atestador introduzindo o seguinte comando:

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
      --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
    
  4. Crie a atestação:

    gcloud

    Para criar e validar a atestação, introduza o seguinte:

    gcloud container binauthz attestations create \
        --project="${ATTESTATION_PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}" \
        --signature-file=/tmp/ec_signature \
        --public-key-id="${PUBLIC_KEY_ID}" \
        --validate
    

    A flag validate verifica se a atestação pode ser validada pelo atestador que configurou na sua política.

    Nota: o ID da chave pode ser qualquer string.

    API REST

    Para criar a atestação:

    1. Obtenha o atestador associado à atestação e extraia o ID da chave pública armazenada:

      curl \
          -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
          -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
          "https://binaryauthorization.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/attestors/"
      

      A autorização binária devolve um objeto JSON semelhante ao seguinte:

      {
        "name": "projects/example-project/attestors/test-attestor",
        "userOwnedGrafeasNote": {
          "noteReference": "projects/example-project/notes/test-attestor",
          "publicKeys": [
            {
              "id": "ni:///sha-256;EwVxs8fNUAHq9FI2AMfh8WNIXVBuuTMeGtPH72U-I70",
              "pkixPublicKey": {
                "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXnpuYEfvLl1kj4fjxViFRwY1a+zC\n5qzlf9LJIK+rnjq42tiKGyyXMbnZKJiYPPdMDGyltnkrABnztg2jJ48aYQ==\n-----END PUBLIC KEY-----\n",
                "signatureAlgorithm": "ECDSA_P256_SHA256"
              }
            }
          ],
          "delegationServiceAccountEmail": "service-363451293945@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
        },
        "updateTime": "2019-06-26T16:58:33.977438Z"
      }
      

      A chave pública encontra-se no campo id.

    2. Crie um ficheiro JSON em /tmp/attestation.json que descreva a atestação:

      cat > /tmp/attestation.json << EOM
      {
        "resourceUri": "${IMAGE_TO_ATTEST}",
        "note_name": "${NOTE_URI}",
        "attestation": {
           "serialized_payload": "$(base64 --wrap=0 /tmp/generated_payload.json)",
           "signatures": [
              {
               "public_key_id": "${PUBLIC_KEY_ID}",
               "signature": "$(base64 --wrap=0 /tmp/ec_signature)"
              }
           ]
        }
       }
      EOM
      
    3. Crie a atestação:

      curl -X POST \
          -H "Content-Type: application/json" \
          -H "X-Goog-User-Project: ${ATTESTATION_PROJECT_ID}" \
          -H "Authorization: Bearer $(gcloud auth print-access-token)" \
          --data-binary @/tmp/attestation.json \
          "https://containeranalysis.googleapis.com/v1/projects/${ATTESTATION_PROJECT_ID}/occurrences/"
      

Crie uma atestação com o Cloud KMS

Para criar uma atestação com o Cloud Key Management Service:

  1. Crie variáveis de ambiente:

    KMS_KEY_PROJECT_ID=KMS_KEY_PROJECT_ID
    KMS_KEY_LOCATION=KMS_KEY_LOCATION
    KMS_KEYRING_NAME=KMS_KEYRING_NAME
    KMS_KEY_NAME=KMS_KEY_NAME
    KMS_KEY_VERSION=KMS_KEY_VERSION
    

    Substitua o seguinte:

    • KMS_KEY_PROJECT_ID: o ID do projeto onde as suas chaves do Cloud Key Management Service estão armazenadas
    • KMS_KEY_LOCATION: a localização da chave (global é a predefinição)
    • KMS_KEYRING_NAME: o nome do conjunto de chaves
    • KMS_KEY_NAME: o nome da chave
    • KMS_KEY_VERSION: a versão da chave
  2. Assine e crie a atestação:

    gcloud

    Introduza o seguinte comando:

    gcloud beta container binauthz attestations sign-and-create \
        --project="${ATTESTATION_PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="${ATTESTOR_NAME}" \
        --attestor-project="${ATTESTOR_PROJECT_ID}" \
        --keyversion-project="${KMS_KEY_PROJECT_ID}" \
        --keyversion-location="${KMS_KEY_LOCATION}" \
        --keyversion-keyring="${KMS_KEYRING_NAME}" \
        --keyversion-key="${KMS_KEY_NAME}" \
        --keyversion="${KMS_KEY_VERSION}"
    

    API REST

    1. Crie um ficheiro de carga útil com o nome /tmp/generated_payload.json usando as variáveis de ambiente que definiu acima:

      cat > /tmp/generated_payload.json << EOM
      {
        "critical": {
          "identity": {
            "docker-reference": "${IMAGE_PATH}"
          },
          "image": {
            "docker-manifest-digest": "${IMAGE_DIGEST}"
          },
          "type": "Google cloud binauthz container signature"
        }
      }
      EOM
      
    2. Assine o ficheiro de conteúdo útil:

      curl \
        --header "Content-Type: application/json" \
        --header "Authorization: Bearer $(gcloud auth print-access-token)" \
        --header "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
        --data '{"digest":  {"DIGEST_ALGORITHM": "'$(openssl dgst -sha256 -binary /tmp/generated_payload.json | openssl base64)'" }}' \
      https://cloudkms.googleapis.com/v1/projects/${KMS_KEY_PROJECT_ID}/locations/${KMS_KEY_LOCATION}/keyRings/${KMS_KEYRING_NAME}/cryptoKeys/${KMS_KEY_NAME}/cryptoKeyVersions/${KMS_KEY_VERSION}:asymmetricSign?alt=json
      

      Substitua DIGEST_ALGORITHM pelo algoritmo para processar a entrada. Os exemplos neste guia usam um resumo sha256. Pode usar sha256, sha384 ou sha512.

      Neste exemplo, o resultado tem um aspeto semelhante ao seguinte:

      {
        "signature": "<var>SIGNATURE</var>": "996305066",
        "name": "projects/<var>KMS_KEY_PROJECT_ID</var>/locations/<var>KMS_KEY_LOCATION</var>/keyRings/<var>KMS_KEYRING_NAME</var>/cryptoKeys/<var>KMS_KEY_NAME</var>/cryptoKeyVersions/<var>KMS_KEY_VERSION</var>"
      }
      

      Neste resultado, SIGNATURE é a assinatura codificada em base64 do ficheiro de conteúdo.

    3. Armazene a assinatura numa variável de ambiente:

      PAYLOAD_SIGNATURE=PAYLOAD_SIGNATURE
      
    4. Obtenha o atestador em nome do qual está a assinar a atestação e extraia o ID da chave pública armazenado e o ID da nota:

      curl \
          -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
          -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
          "https://binaryauthorization.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/attestors/"
      

      A autorização binária devolve um objeto JSON semelhante ao seguinte:

      {
        "name": "projects/example-project/attestors/test-attestor",
        "userOwnedGrafeasNote": {
          "noteReference": "projects/example-project/notes/test-attestor",
          "publicKeys": [
            {
              "id": "ni:///sha-256;EwVxs8fNUAHq9FI2AMfh8WNIXVBuuTMeGtPH72U-I70",
              "pkixPublicKey": {
                "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXnpuYEfvLl1kj4fjxViFRwY1a+zC\n5qzlf9LJIK+rnjq42tiKGyyXMbnZKJiYPPdMDGyltnkrABnztg2jJ48aYQ==\n-----END PUBLIC KEY-----\n",
                "signatureAlgorithm": "ECDSA_P256_SHA256"
              }
            }
          ],
          "delegationServiceAccountEmail": "service-363451293945@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
        },
        "updateTime": "2019-06-26T16:58:33.977438Z"
      }
      

      Pode encontrar o ID da chave pública no campo id e o ID da nota no campo noteReference.

    5. Armazene o ID da chave pública numa variável de ambiente:

      PUBLIC_KEY_ID="PUBLIC_KEY_ID"
      NOTE_URI="NOTE_URI"
      

      Substitua o seguinte:

      • PUBLIC_KEY_ID: o ID da chave pública do atestador.
      • NOTE_URI: o URI da nota de análise de artefactos associada ao atestador.
    6. Crie um ficheiro JSON em /tmp/attestation.json que descreva a atestação:

      cat > /tmp/attestation.json << EOM
      {
        "resourceUri": "${IMAGE_TO_ATTEST}",
        "note_name": "${NOTE_URI}",
        "attestation": {
           "serialized_payload": "$(base64 --wrap=0 /tmp/generated_payload.json)",
           "signatures": [
               {
                   "public_key_id": "${PUBLIC_KEY_ID}",
                   "signature": "${PAYLOAD_SIGNATURE}"
               }
           ]
        }
      }
      EOM
      
    7. Crie a atestação:

      curl -X POST \
          -H "Content-Type: application/json" \
          -H "X-Goog-User-Project: ${ATTESTATION_PROJECT_ID}" \
          -H "Authorization: Bearer $(gcloud auth print-access-token)" \
          --data-binary @/tmp/attestation.json \
      "https://containeranalysis.googleapis.com/v1/projects/${ATTESTATION_PROJECT_ID}/occurrences/"
      

Criou a atestação.

Confirme se a atestação foi criada

Para verificar se a atestação foi criada, pode listar as atestações associadas à imagem.

gcloud

Para obter uma lista de atestações, introduza o seguinte comando:

gcloud container binauthz attestations list\
    --project="${ATTESTATION_PROJECT_ID}"\
    --attestor="projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}"\
    --artifact-url="${IMAGE_TO_ATTEST}"

API REST

Para pedir uma lista de atestações, introduza o seguinte comando:

curl -X GET \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: ${ATTESTOR_PROJECT_ID}" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}/occurrences?filter=resourceUrl%3D%22https%3A%2F%2F$(jq -rn --arg x ${IMAGE_TO_ATTEST} '$x|@uri')%22

Se existirem muitas atestações, a resposta pode conter um nextPageToken value. Neste caso, pode obter a página seguinte de resultados repetindo o pedido e adicionando um parâmetro de consulta pageToken, da seguinte forma:

NEXT_PAGE_TOKEN=NEXT_PAGE_TOKEN
curl -X GET \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: ${ATTESTOR_PROJECT_ID}" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}/occurrences?filter=resourceUrl%3D%22https%3A%2F%2F$(jq -rn --arg x ${IMAGE_TO_ATTEST} '$x|@uri')%22&pageToken=${NEXT_PAGE_TOKEN}

Substitua NEXT_PAGE_TOKEN pelo valor de nextPageToken na resposta do pedido anterior.

Quando nextPageToken está vazio, significa que não existem mais resultados.

Elimine a atestação

Antes de eliminar a atestação, deve fazer o seguinte:

  1. Compreenda as ramificações da eliminação. A eliminação de um evento de atestação acaba por impedir a implementação de imagens de contentores associadas à atestação.

  2. Pare todos os contentores em execução associados às atestações que quer eliminar.

  3. Elimine todas as cópias das atestações onde quer que estejam localizadas, por exemplo, atestações nos repositórios do Artifact Registry e da Artifact Analysis.

  4. Certifique-se de que as imagens afetadas estão efetivamente bloqueadas para implementação tentando implementá-las novamente.

Para eliminar uma atestação, execute os seguintes comandos:

  1. Apresentar atestações:

    gcloud container binauthz attestations list \
      --attestor-project=${ATTESTOR_PROJECT_ID} \
      --attestor=${ATTESTOR_NAME}
    

    A atestação contém um ID de ocorrência. O resultado tem um aspeto semelhante ao seguinte:

    projects/ATTESTOR_PROJECT_ID/occurrences/OCCURRENCE_ID
    
  2. Guarde o ID da ocorrência.

    Guarde o ID da ocorrência da atestação que quer eliminar.

    OCCURRENCE_ID=OCCURRENCE_ID
    
  3. Elimine a atestação:

    curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -X DELETE \
      https://containeranalysis.googleapis.com/v1beta1/projects/${ATTESTATION_PROJECT_ID}/occurrences/${OCCURRENCE_ID}
    

    Verifique se as atestações foram eliminadas listando-as novamente.

O que se segue?