Criar atestadores usando a API REST

Nesta página, explicamos como criar um atestador na autorização binária usando a API REST. Como alternativa, você também pode executar estas etapas usando a ferramenta de linha de comando gcloud ou o Console do Google Cloud. Esta tarefa faz parte da configuração da autorização binária.

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 Container Analysis para armazenar metadados de confiança usados no processo de atestado.
  • Configure um par de chaves 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.

Defina 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 Container Analysis

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

Para criar uma nota do Container 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 Container Analysis:

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

    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 Container 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 do 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 solicite papéis de acesso à política do IAM para a observação 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, na sigla em inglês) 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.

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}
    

Criar o atestador

A próxima etapa é criar o próprio atestador na autorização binária com a nota do Container 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 (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}"
      

    PKIX (Cloud KMS)

    1. Configure variáveis de ambiente para armazenar informações sobre o par de chaves, conforme gerenciado pelo Cloud KMS.

      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_TYPE=KMS_KEY_TYPE
      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}"
      

      Substitua:

      • KMS_KEY_PROJECT_ID é o ID do projeto em que as chaves são armazenadas;
      • KMS_KEY_LOCATION é o local da chave (por exemplo, global);
      • KMS_KEYRING_NAME é o nome do keyring;
      • KMS_KEY_NAME é o nome da chave;
      • KMS_KEY_VERSION é a versão da chave;
      • KMS_KEY_TYPE é o tipo de criptografia da chave (por exemplo, ECDSA_P256_SHA256).
    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_TYPE}",
                      "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}"
      
  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/v1/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