Nesta página, descrevemos as etapas para criar um atestado de autorização binária.
Use atestados para autorizar que imagens de contêiner específicas sejam implantadas em plataformas, como o Google Kubernetes Engine (GKE) e o Cloud Run. Para usar atestados, é necessário exigir atestados na regra apropriada da sua política.
Um único atestado pode autorizar imagens idênticas armazenadas em vários locais ou registros diferentes, como o Artifact Registry, o Container Registry ou um registro de contêiner externo.
No momento da implantação, a autorização binária usa atestadores para verificar atestados.
Para configurar a autorização binária no Cloud Run, no GKE, nos clusters do GKE e no Anthos Service Mesh, consulte Configuração por plataforma e selecione sua plataforma.
Usuários do GKE: para ver um tutorial completo que descreve a aplicação baseada em atestado usando a autorização binária e o Google Kubernetes Engine (GKE), consulte Introdução à ferramenta de linha de comando ou Introdução ao Console do Google Cloud.
Antes de começar
A Visão geral dos atestados apresenta etapas a serem concluídas antes de criar um atestado.
Crie atestadores usando o console do Google Cloud, a CLI do Google Cloud ou a API REST.
Configure o ambiente
Especifique os IDs do projeto:
ATTESTOR_PROJECT_ID=ATTESTOR_PROJECT_ID ATTESTATION_PROJECT_ID=ATTESTATION_PROJECT_ID
Substitua:
- ATTESTOR_PROJECT_ID: o nome do projeto em que você está armazenando seus atestadores;
- ATTESTATION_PROJECT_ID: o nome do projeto em que você está armazenando os atestados.
Se você quiser que o atestado seja criado no mesmo projeto que os atestadores, use o mesmo ID do projeto para as duas variáveis. Para ver um tutorial completo que demonstra a separação de deveres com projetos diferentes, consulte Configuração de vários projetos.
Especifique o nome do atestador e as informações da imagem:
ATTESTOR_NAME=ATTESTOR_NAME IMAGE_PATH=IMAGE_PATH IMAGE_DIGEST=IMAGE_DIGEST IMAGE_TO_ATTEST="${IMAGE_PATH}@${IMAGE_DIGEST}"
Substitua:
- ATTESTOR_NAME: o nome do atestador, por exemplo,
build-secure
ouprod-qa
; IMAGE_PATH: um URI que representa um caminho de imagem. O URI precisa ter um nome de domínio e uma imagem, mas não é necessário se referir a uma imagem real. As imagens não são acessadas durante a criação do atestado. Veja a seguir exemplos de caminhos de imagem:
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 da imagem. Por exemplo,
sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567
é o resumo da imagem associado ao caminho de imagemus-docker.pkg.dev/google-samples/containers/gke/hello-app
de exemplo. Para saber como conseguir o resumo de uma imagem no Artifact Registry, consulte Como gerenciar imagens. Para uma imagem no Container Registry, consulte Como listar versões de um imagem.
- ATTESTOR_NAME: o nome do atestador, por exemplo,
Conceder papéis de gerenciamento de identidade e acesso
Para criar atestados, é necessário conceder os seguintes papéis de gerenciamento de identidade e acesso (IAM, na sigla em inglês) à identidade que cria o atestador, da seguinte maneira:
roles/containeranalysis.notes.attacher
no recurso de nota associado ao atestador.roles/containeranalysis.occurrences.editor
no recurso de projeto de atestado.
Você criará um atestado com base em um atestador. O atestador está associado a uma nota do Artifact Analysis. Por sua vez, criar um atestado cria uma ocorrência do Artifact Analysis e a anexa à nota.
Saiba mais sobre Como conceder acesso.
Para saber como criar um atestado em um pipeline do Cloud Build, consulte Como criar atestados usando o Kritis Signer.
Criar um atestado
Criar um atestado usando uma chave armazenada localmente
Para criar um atestado assinado com uma chave local, faça o seguinte:
Crie um arquivo de payload de assinatura:
gcloud
Para criar o arquivo de payload de assinatura, digite este comando:
gcloud container binauthz create-signature-payload \ --artifact-url="${IMAGE_TO_ATTEST}" > /tmp/generated_payload.json
O arquivo de payload no formato JSON é semelhante a:
{ "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 arquivo de payload chamado
/tmp/generated_payload.json
usando as variáveis de ambiente definidas 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 o payload com a chave privada para gerar um arquivo de assinatura.
Este guia usa o algoritmo recomendado de algoritmo de assinatura digital de curva elíptica (ECDSA, na sigla em inglês) para assinatura. Também é possível usar o algoritmo RSA. Para mais informações sobre algoritmos de assinatura, consulte Finalidades de chave e algoritmos. Este guia também usa o formato de assinatura de Infraestrutura de chave pública (X.509) (PKIX, na sigla em inglês). Também é possível 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 você gerou quando criou o atestador.
Encontre o ID da chave pública.
É possível recuperar o código da chave pública no atestador inserindo o seguinte comando:
PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \ --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
Crie o atestado:
gcloud
Para criar e validar o atestado, insira 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 sinalização
validate
verifica se o atestado pode ser verificado pelo atestador que você configurou na política.Observação: o código da chave pode ser qualquer string.
API REST
Para criar o atestado:
Recupere o atestador associado ao atestado 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 retorna 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 pode ser encontrada no campo
id
.Crie um arquivo JSON em
/tmp/attestation.json
que descreva o atestado: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 o atestado:
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/"
Criar um atestado usando o Cloud KMS
Para criar um atestado usando 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:
- KMS_KEY_PROJECT_ID: o ID do projeto em que as chaves do Cloud Key Management Service estão armazenadas;
- KMS_KEY_LOCATION: o local da chave (
global
é o padrão); - KMS_KEYRING_NAME: o nome do keyring;
- KMS_KEY_NAME: o nome da chave;
- KMS_KEY_VERSION: a versão da chave.
Assine e crie o atestado:
gcloud
Digite este 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 arquivo de payload chamado
/tmp/generated_payload.json
usando as variáveis de ambiente definidas 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 arquivo de payload:
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 resumir a entrada. Os exemplos neste guia usam um resumo
sha256
. É possível usarsha256
,sha384
ousha512
.Neste exemplo, a saída é semelhante a esta:
{ "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>" }
Nesta saída, SIGNATURE é a assinatura codificada em base64 do arquivo de payload.
Armazene a assinatura em uma variável de ambiente:
PAYLOAD_SIGNATURE=PAYLOAD_SIGNATURE
Recupere o atestador em nome de quem você está assinando o atestado e extraia o ID da chave pública armazenada 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 retorna 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" }
É possível encontrar o ID da chave pública no campo
id
e o ID da nota no camponoteReference
.Armazene o código da chave pública em uma variável de ambiente:
PUBLIC_KEY_ID="PUBLIC_KEY_ID" NOTE_URI="NOTE_URI"
Substitua:
- PUBLIC_KEY_ID: o ID da chave pública do atestador.
- NOTE_URI: o URI da nota do Artifact Analysis associado ao atestador.
Crie um arquivo JSON em
/tmp/attestation.json
que descreva o atestado: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 o atestado:
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/"
Você criou o atestado.
Verificar se o atestado foi criado
Para verificar se o atestado foi criado, liste os atestados associados à imagem.
gcloud
Para recuperar uma lista de atestados, digite 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 solicitar uma lista de atestados, digite 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 houver muitos atestados, a resposta poderá conter um valor
nextPageToken
. Nesse caso, é possível recuperar a próxima página de resultados repetindo
a solicitação, adicionando um parâmetro de consulta pageToken
, da seguinte maneira:
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 nextPageToken
na
resposta da solicitação anterior.
Quando nextPageToken
está vazio, isso significa que não há mais resultados.
Excluir o atestado
Antes de excluir o atestado, faça o seguinte:
Entenda as consequências de excluí-los. A exclusão de um atestado acaba bloqueando a implantação de imagens de contêiner associadas ao atestado.
Interrompa todos os contêineres em execução associados aos atestados que você pretende excluir.
Exclua todas as cópias dos atestados onde quer que estejam, por exemplo, atestados dos repositórios do Artifact Registry e do Artifact Analysis.
Verifique se as imagens afetadas estão realmente bloqueadas para a implantação tentando reimplantá-las.
Para excluir um atestado, execute os seguintes comandos:
Liste atestados:
gcloud container binauthz attestations list \ --attestor-project=${ATTESTOR_PROJECT_ID} \ --attestor=${ATTESTOR_NAME}
O atestado contém um ID de ocorrência. A resposta será semelhante a:
projects/ATTESTOR_PROJECT_ID/occurrences/OCCURRENCE_ID
Salve o ID da ocorrência.
Salve o ID da ocorrência do atestado que você quer excluir.
OCCURRENCE_ID=OCCURRENCE_ID
Exclua o atestado:
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -X DELETE \ https://containeranalysis.googleapis.com/v1beta1/projects/${ATTESTATION_PROJECT_ID}/occurrences/${OCCURRENCE_ID}
Para verificar se os atestados foram excluídos, liste os atestados novamente.
A seguir
- Saiba mais sobre a separação de deveres e papéis de gerenciamento de identidade e acesso.
- Implemente a separação de deveres neste tutorial de configuração de vários projetos (GKE).
- Implante uma imagem de contêiner (GKE) em um cluster em que a autorização binária esteja ativada
- Implante uma imagem de contêiner (Cloud Run) em um cluster em que a autorização binária esteja ativada.