Criar atestadores usando a API REST

Nesta página, explicamos como criar um atestador personalizado na autorização binária usando a API REST.

Como alternativa, você também pode seguir essas etapas na Google Cloud CLI ou no console do Google Cloud. Essa tarefa faz parte da configuração da autorização binária.

Usuários do Cloud Build: é possível usar o atestador built-by-cloud-build para implantar apenas imagens criadas pelo Cloud Build.

Visão geral

Um atestador é um recurso do Google Cloud que a autorização binária usa para verificar um atestado. Para saber mais sobre atestados, consulte a Visão geral da autorização binária.

Para criar um atestador, você precisa fazer o seguinte:

  • Crie uma nota no Artifact Analysis para armazenar metadados de confiança usados no processo de atestado.
  • Configure um par de chaves de infraestrutura de chave pública (X.509) (PKIX) que possa ser usado para verificar a identidade do atestador. Os pares de chaves assimétricas gerados pelo Cloud Key Management Service (Cloud KMS) estão no formato compatível com PKIX. Também é possível usar pares de chaves PGP em vez de chaves PKIX.
  • Crie o próprio atestador na autorização binária e associe a nota e a chave pública que você criou.

Em uma configuração de projeto único, crie o atestador no mesmo projeto do Google Cloud em que você configura a política de autorização binária. Em um configuração de vários projetos, é provável que você tenha projeto do implantador com a política configurada e um recurso Projeto de atestador onde seus atestadores são armazenados.

Antes de começar

  1. Ativar autorização binária.

  2. Configurar a autorização binária para sua plataforma.

Definir o projeto padrão

Defina o projeto padrão do Google Cloud se ainda não tiver feito isso:

PROJECT_ID=PROJECT_ID
gcloud config set project ${PROJECT_ID}

Configure o ambiente

Configure variáveis de ambiente para armazenar os nomes e números dos seus projetos:

DEPLOYER_PROJECT_ID=${PROJECT_ID}
DEPLOYER_PROJECT_NUMBER="$(
    gcloud projects describe "${DEPLOYER_PROJECT_ID}" \
      --format="value(projectNumber)"
)"
ATTESTOR_PROJECT_ID=${PROJECT_ID}
ATTESTOR_PROJECT_NUMBER="$(
    gcloud projects describe "${ATTESTOR_PROJECT_ID}" \
    --format="value(projectNumber)"
)"

Se o projeto de atestador e implantador forem o mesmo, use o mesmo código do projeto para as duas variáveis.

Você também precisa receber os nomes das contas de serviço dos projetos:

DEPLOYER_SERVICE_ACCOUNT="service-${DEPLOYER_PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
ATTESTOR_SERVICE_ACCOUNT="service-${ATTESTOR_PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"

Criar uma nota do Artifact Analysis

A autorização binária usa o Artifact Analysis para armazenar metadados confiáveis usados no processo de autorização. Para cada atestador criado, você precisa criar uma nota do Artifact Analysis. Cada atestado é armazenado como uma ocorrência dessa nota.

Para criar uma nota do Artifact Analysis:

  1. Configure variáveis de ambiente para armazenar o código da nota e uma descrição legível:

    NOTE_ID=NOTE_ID
    NOTE_URI="projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}"
    DESCRIPTION=DESCRIPTION
    

    Substitua:

    • NOTE_ID é o nome interno da nota em caracteres alfanuméricos sem espaços (por exemplo, test-attestor-note);
    • NOTE_URI é o caminho totalmente qualificado para o recurso de nota;
    • DESCRIPTION é um nome de exibição legível para a observação (por exemplo, Test Attestor Note).
  2. Em um editor de texto, crie um arquivo JSON em /tmp/note_payload.json que descreva a nota do Artifact Analysis:

    cat > /tmp/note_payload.json << EOM
    {
      "name": "${NOTE_URI}",
      "attestation": {
        "hint": {
          "human_readable_name": "${DESCRIPTION}"
        }
      }
    }
    EOM
    
  3. Envie uma solicitação HTTP para a API REST do Artifact Analysis para criar a nota:

    curl -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
        -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
        --data-binary @/tmp/note_payload.json  \
        "https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/?noteId=${NOTE_ID}"
    

Para verificar se a nota foi criada com sucesso, execute o seguinte comando:

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

Definir permissões na nota

Também é necessário definir permissões na nota do Artifact Analysis que você criou para que ela possa ser acessada pela conta de serviço do projeto do atestador. Para fazer isso, atualize a política de IAM da nota para atribuir o papel containeranalysis.notes.occurrences.viewer à conta.

Para definir as permissões:

  1. Gere um arquivo JSON que contenha as informações necessárias para definir a política do IAM na sua nota:

    cat > /tmp/iam_request.json << EOM
    {
      'resource': '${NOTE_URI}',
      'policy': {
        'bindings': [
          {
            'role': 'roles/containeranalysis.notes.occurrences.viewer',
            'members': [
              'serviceAccount:${ATTESTOR_SERVICE_ACCOUNT}'
            ]
          }
        ]
      }
    }
    EOM
    
  2. Adicione a conta de serviço e os papéis de acesso solicitados à política do IAM para a nota que você criou:

    curl -X POST  \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
        --data-binary @/tmp/iam_request.json \
        "https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"
    

Configurar chaves criptográficas

A autorização binária permite que você use chaves PKIX para verificar com segurança a identidade do signer que criou um atestado. Isso garante que apenas as partes verificadas possam autorizar uma imagem de contêiner. Como alternativa ao PKIX, você também pode usar chaves PGP.

Criar um par de chaves PKIX

A autorização binária permite que você use pares de chaves PKIX assimétricas para verificar um atestado. O par de chaves consiste em uma chave privada, que o signatário usa para assinar atestados digitalmente e uma chave pública, que você adiciona ao atestador. Posteriormente, o aplicador de autorização binária usa a chave pública no atestador para verificar se o atestado foi criado pelo signatário.

Neste guia, o algoritmo de assinatura digital de curva elíptica (ECDSA) recomendado é usado para gerar um par de chaves PKIX. Também é possível usar chaves RSA ou PGP para assinatura. Consulte Finalidades de chave e algoritmos para mais informações sobre algoritmos de assinatura.

Os pares de chaves assimétricas gerados e armazenados no Cloud KMS são compatíveis com o formato PKIX. Para criar uma chave do Cloud KMS para uso com autorização binária, consulte Como criar chaves assimétricas. Escolha a Assinatura assimétrica como a finalidade da chave ao criá-la.

PKIX (Cloud KMS)

Para criar o par de chaves no Cloud KMS, faça o seguinte:

  1. Para configurar as variáveis de ambiente necessárias para criar o par de chaves, execute os seguintes comandos:

    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
    KMS_KEY_PURPOSE=asymmetric-signing
    KMS_KEY_ALGORITHM=KMS_KEY_ALGORITHM
    KMS_PROTECTION_LEVEL=KMS_PROTECTION_LEVEL
    

    Substitua:

    • KMS_KEY_PROJECT_ID: o ID do projeto em que as chaves são armazenadas.
    • KMS_KEY_LOCATION: a localização da chave;
    • KMS_KEYRING_NAME: o nome do keyring;
    • KMS_KEY_NAME: o nome da chave;
    • KMS_KEY_VERSION: a versão da chave.
    • KMS_KEY_ALGORITHM: o algoritmo; o ec-sign-p256-sha256 é recomendado.
    • KMS_PROTECTION_LEVEL: o nível de proteção, por exemplo, software.
  2. Para criar o keyring, execute o seguinte comando:

    gcloud kms keyrings create ${KMS_KEYRING_NAME} \
        --location ${KMS_KEY_LOCATION}
    
  3. Para criar a chave, execute o seguinte comando:

    gcloud kms keys create ${KMS_KEY_NAME} \
        --location ${KMS_KEY_LOCATION} \
        --keyring ${KMS_KEYRING_NAME}  \
        --purpose ${KMS_KEY_PURPOSE} \
        --default-algorithm ${KMS_KEY_ALGORITHM} \
        --protection-level ${KMS_PROTECTION_LEVEL}
    

PKIX (chave local)

Para gerar um novo par de chaves PKIX assimétrica e armazená-lo em um arquivo:

  1. Gerar a chave

    PRIVATE_KEY_FILE="/tmp/ec_private.pem"
    openssl ecparam -genkey -name prime256v1 -noout -out ${PRIVATE_KEY_FILE}
    
  2. Como esse arquivo contém uma chave pública e uma privada, você precisa extrair a chave pública em um arquivo separado para adicioná-la ao atestador:

    PUBLIC_KEY_FILE="/tmp/ec_public.pem"
    openssl ec -in ${PRIVATE_KEY_FILE} -pubout -out ${PUBLIC_KEY_FILE}
    

Crie o atestador

A próxima etapa é criar o próprio atestador na autorização binária com a nota do Artifact Analysis associada. Também é necessário adicionar a chave pública criptográfica.

Para criar o atestador:

  1. Configure uma variável de ambiente para armazenar o nome do atestador, conforme definido na autorização binária:

    ATTESTOR_NAME=ATTESTOR_NAME
    

    em que ATTESTOR_NAME é o nome do atestador que você quer criar (por exemplo, build-secure ou prod-qa).

  2. Crie o atestador e anexe a chave de segurança pública:

    PKIX (Cloud KMS)

    1. Configure mais variáveis de ambiente para armazenar informações sobre o par de chaves do Cloud KMS para a chamada à API Binary Authorization.

      KMS_CRYPTO_KEY_URI="projects/${KMS_KEY_PROJECT_ID}/locations/${KMS_KEY_LOCATION}/keyRings/${KMS_KEYRING_NAME}/cryptoKeys/${KMS_KEY_NAME}"
      KMS_CRYPTO_KEY_VERSION_URI="${KMS_CRYPTO_KEY_URI}/cryptoKeyVersions/${KMS_KEY_VERSION}"
      KMS_KEY_ID="//cloudkms.googleapis.com/v1/${KMS_CRYPTO_KEY_VERSION_URI}"
      
    2. Faça o download do arquivo de chave pública do Cloud KMS e salve-o em um arquivo chamado /tmp/kms_public_key.pem no sistema local.

    3. Gere um arquivo JSON que contenha as informações necessárias para criar o atestador:

      cat > /tmp/attestor.json << EOM
      {
          "userOwnedDrydockNote": {
              "noteReference": "${NOTE_URI}",
              "publicKeys": {
                  "id": "${KMS_KEY_ID}",
                  "pkixPublicKey": {
                      "signatureAlgorithm": "${KMS_KEY_ALGORITHM}",
                      "publicKeyPem": $( \
                          python < /tmp/kms_public_key.pem \
                          -c 'import json, sys; print(json.dumps(sys.stdin.read()))' \
                      )
                  }
              }
          }
      }
      EOM
      
    4. Crie o atestador:

      curl -X POST  \
          -H "Content-Type: application/json" \
          -H "Authorization: Bearer $(gcloud auth print-access-token)" \
          -H "X-Goog-User-Project: ${ATTESTOR_PROJECT_ID}" \
          --data-binary @/tmp/attestor.json \
      "https://binaryauthorization.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/attestors?attestorId=${ATTESTOR_NAME}"
      

    PKIX (chave local)

    1. Gere um arquivo JSON que contenha as informações necessárias para criar o atestador:

      cat > /tmp/attestor.json << EOM
      {
         "userOwnedGrafeasNote": {
             "noteReference": "${NOTE_URI}",
             "publicKeys": {
                 "pkixPublicKey": {
                     "signatureAlgorithm": "ecdsa_p256_sha256",
                     "publicKeyPem": $( \
                         python < ${PUBLIC_KEY_FILE} \
                         -c 'import json, sys; print(json.dumps(sys.stdin.read()))' \
                     )
                 }
             }
         }
      }
      EOM
      
    2. Crie o atestador:

      curl -X POST  \
         -H "Content-Type: application/json" \
         -H "Authorization: Bearer $(gcloud auth print-access-token)" \
         -H "X-Goog-User-Project: ${ATTESTOR_PROJECT_ID}" \
         --data-binary @/tmp/attestor.json \
      "https://binaryauthorization.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/attestors?attestorId=${ATTESTOR_NAME}"
      
  3. Adicione uma vinculação de papel do IAM para o projeto do implantador ao atestador. Isso é usado pela autorização binária quando avalia uma política para determinar se o projeto tem permissões para acessar o atestador referenciado.

    Gere um arquivo JSON que contenha as informações necessárias para definir a política do IAM no seu atestador:

    cat > /tmp/iam_request.json << EOM
    {
      'resource': 'projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}',
      'policy': {
        'bindings': [
          {
            'role': 'roles/binaryauthorization.attestorsVerifier',
            'members': [
              'serviceAccount:${DEPLOYER_SERVICE_ACCOUNT}'
            ]
          }
        ]
      }
    }
    EOM
    

    Adicione a conta de serviço e os papéis de acesso solicitados à política do IAM para a nota que você criou:

    curl -X POST  \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
        --data-binary @/tmp/iam_request.json \
        "https://binaryauthorization.googleapis.com/v1beta1/projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}:setIamPolicy"
    

Verificar se o atestador foi criado

Para verificar se o atestador foi criado, execute este comando:

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 seguir