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.
Crie atestadores através da Google Cloud consola, da CLI do Google Cloud, ou da API REST.
Configure o ambiente
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.
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
ouprod-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 imagemus-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.
- ATTESTOR_NAME: o nome do atestador, por exemplo,
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:
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
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.
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)')
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:
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
.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
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:
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
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
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
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 usarsha256
,sha384
ousha512
.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.
Armazene a assinatura numa variável de ambiente:
PAYLOAD_SIGNATURE=PAYLOAD_SIGNATURE
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 camponoteReference
.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.
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
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:
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.
Pare todos os contentores em execução associados às atestações que quer eliminar.
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.
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:
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
Guarde o ID da ocorrência.
Guarde o ID da ocorrência da atestação que quer eliminar.
OCCURRENCE_ID=OCCURRENCE_ID
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?
- Saiba mais sobre a separação de funções e as funções de gestão de identidades e acessos.
- Implemente a separação de funções neste tutorial de configuração com vários projetos (GKE).
- Implemente uma imagem de contentor (GKE) num cluster onde a autorização binária está ativada.
- Implemente uma imagem de contentor (Cloud Run) num cluster onde a autorização binária está ativada.