Crea certificaciones

En esta página, se explica cómo crear una certificación en la autorización binaria desde la línea de comandos.

.

En las instrucciones de esta página, se describen los pasos que debe seguir un firmante a fin de autorizar la implementación de una imagen de contenedor. En una situación real, incorporas estos pasos a una secuencia de comandos o automatización que un proceso automático o un usuario humano pueden activar, en lugar de ingresarlos de forma manual en la línea de comandos.

Descripción general

Una certificación es un documento firmado de forma digital, que realiza un firmante, que certifica que se completó el proceso solicitado en tu canalización y que la imagen de contenedor resultante se autorizó para la implementación en GKE. La certificación contiene la ruta completa a la versión de la imagen de contenedor almacenada en tu registro de imágenes de contenedor, además de una firma creada mediante la firma del resumen único a nivel global que identifica una compilación de imagen de contenedor específica.

Puedes crear una certificación con una firma de PKIX (recomendado) o PGP. En esta guía, se usa el formato de infraestructura de clave pública (X.509) (PKIX) para claves criptográficas y el Algoritmo de firma digital de curva elíptica (ECDSA) para firmar y crear la certificación. También puedes usar las claves de RSA o PGP para firmar. Consulta Algoritmos y propósitos de clave para obtener más información sobre los algoritmos de firma.

Configura el proyecto predeterminado

Si aún no configuraste tu proyecto predeterminado de Google Cloud, sigue estos pasos:

PROJECT_ID=PROJECT_ID
gcloud config set project ${PROJECT_ID}

En el ejemplo anterior, PROJECT_ID es el nombre del proyecto.

Configura el entorno

  1. Configura las variables de entorno para almacenar los ID del proyecto:

    ATTESTOR_PROJECT_ID=ATTESTOR_PROJECT_ID
    ATTESTATION_PROJECT_ID=ATTESTATION_PROJECT_ID
    

    En el ejemplo anterior, se ilustra lo siguiente:

    • ATTESTOR_PROJECT_ID es el nombre del proyecto en el que almacenas los certificadores.
    • ATTESTATION_PROJECT_ID es el nombre del proyecto en el que almacenas las certificaciones.

    Si tus proyectos de certificador y certificación se encuentran el mismo proyecto, usa el mismo ID del proyecto para ambas variables.

  2. Configura las variables de entorno para almacenar el nombre del certificador que verificará la certificación y la ruta de registro de la imagen que deseas implementar:

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

    En el ejemplo anterior, se ilustra lo siguiente:

    • ATTESTOR_NAME es el nombre del certificador (por ejemplo, build-secure o prod-qa).
    • IMAGE_PATH es la ruta en Container Registry a la imagen que deseas implementar (por ejemplo, gcr.io/example-project/quickstart-image).
    • PUBLIC_KEY_ID es el ID asociado con la clave pública del par de claves que generaste. La clave pública se almacena en el certificador.
    • PRIVATE_KEY_FILE es el archivo que contiene la clave privada del par de claves que generaste. La carga útil de certificación se firma con esta clave.
    • IMAGE_DIGEST es el resumen SHA-256 del manifiesto de imagen (por ejemplo, sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4). Para obtener información sobre cómo obtener el resumen de la imagen, consulta Enumera las versiones de una imagen en Container Registry.

Cada imagen de contenedor almacenada en Container Registry o en otro registro tiene una ruta única a su ubicación y un resumen SHA-256 que identifica su versión de forma única. Las certificaciones hacen referencia al resumen y a la ruta completa de la imagen, lo que te permite autorizar versiones específicas de una imagen.

El siguiente es un ejemplo de una ruta de registro completa:

gcr.io/example-project/quickstart-image@sha256:bedb3feb23e81d162e33976fd7b245adff00379f4755c0213e84405e5b1e0988

Crea una certificación con una firma de PKIX mediante una clave almacenada de forma local

Para certificaciones firmadas con una clave pública de PKIX, sigue estos pasos:

  1. Crea una carga útil de certificación para enviar a la autorización binaria que haga referencia a la ruta de registro.
  2. Firma la carga útil y genera un archivo de firma de PKIX.
  3. Obtén el ID de clave pública.
  4. Crea la certificación con el archivo de firma y el ID de clave pública.

Crea una carga útil de certificación

La carga útil de certificación es un archivo con formato JSON que hace referencia a la ubicación de la imagen de contenedor.

Para crear el archivo de carga útil, sigue estos pasos:

gcloud

Ingresa lo siguiente:

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

El archivo de carga útil es similar al siguiente:

{
  "critical": {
    "identity": {
      "docker-reference": "gcr.io/google-samples/hello-app"
    },
    "image": {
      "docker-manifest-digest": "sha256:bedb3feb23e81d162e33976fd7b245
adff00379f4755c0213e84405e5b1e0988"
    },
    "type": "Google cloud binauthz container signature"
  }
}

REST

Crea un archivo de carga útil llamado /tmp/generated_payload.json mediante las variables de entorno que configuraste antes:

cat > /tmp/generated_payload.json << EOM
{
  "critical": {
    "identity": {
      "docker-reference": "${IMAGE_PATH}"
    },
    "image": {
      "${IMAGE_DIGEST}"
    },
    "type": "Google cloud binauthz container signature"
  }
}
EOM

Firma la carga útil y genera un archivo de firma

Después de crear el archivo de carga útil, debes firmarlo mediante la clave criptográfica privada del par de claves que generaste antes. Recuerda que la clave pública correspondiente se almacenó en el certificador asociado. La clave pública en ese certificador se usará para verificar esta firma en el momento de la implementación.

Para revisar cómo crear un certificador, consulta Crea certificadores mediante la CLI o Crea certificadores mediante Console.

Para ver un ejemplo de extremo a extremo que incluya todos estos pasos, consulta Comienza a usar la CLI o Comienza a usar Console.

Para firmar el archivo de carga útil, sigue estos pasos:

  1. Firma la carga útil con tu clave privada de PKIX local y genera un archivo de firma:

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

    El archivo de firma es una versión con firma digital del archivo JSON de carga útil que creaste antes.

Obtén el ID de clave pública.

Cuando crees una certificación, debes enviar un ID de clave pública a la autorización binaria junto con el archivo de firma.

Para obtener el ID de clave pública, sigue estos pasos:

  1. Guarda el ID de clave pública

    Para ver el ID de clave pública del certificador más tarde, usa gcloud container binauthz attestors describe ${ATTESTOR_NAME}:

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
      --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
    

Crea la certificación

gcloud

Para crear la certificación, ingresa lo siguiente:

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}"

Como alternativa, para crear y validar que el certificador provisto pueda verificar la certificación, ejecuta el siguiente comando:

gcloud alpha 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

Nota: El ID de clave puede ser una string.

REST

Para crear la certificación, sigue estos pasos:

  1. Recupera el certificador asociado con la certificación y extrae el ID de clave pública almacenada:

    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/"
    

    La autorización binaria muestra un objeto JSON similar al siguiente:

    {
      "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"
    }
    
  2. En un editor de texto, crea un archivo JSON en /tmp/attestation.json en el que se describa la certificación:

    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": "KEY_ID",
             "signature": "$(base64 --wrap=0 /tmp/ec_signature)"
             }
         ]
      }
     }
    EOM
    

    En el ejemplo anterior, KEY_ID es el ID de clave pública que se mostró en el paso previo.

  3. Crea la certificación:

    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/"
    

Crea una certificación con una firma de PKIX basada en Cloud Key Management Service

Para crear una certificación con una firma de PKIX basada en Cloud Key Management Service, sigue estos pasos:

  1. Configura variables de entorno para almacenar información sobre los proyectos en los que se almacenan las certificaciones, los certificadores y las claves de Cloud Key Management Service y la información sobre el par de claves de PKIX:

    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
    

    En el ejemplo anterior, se ilustra lo siguiente:

    • KMS_KEY_PROJECT_ID es el ID del proyecto en el que se almacenan las claves de Cloud Key Management Service.
    • KMS_KEY_LOCATION es la ubicación de la clave (global es la configuración predeterminada).
    • KMS_KEYRING_NAME es el nombre del llavero de claves.
    • KMS_KEY_NAME es el nombre de la clave.
    • KMS_KEY_VERSION es la versión de la clave.
  2. Firma y crea la certificación:

    gcloud

    Ingresa lo siguiente en la línea de comandos:

    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}"
    

    REST

    1. Crea un archivo de carga útil llamado /tmp/generated_payload.json mediante las variables de entorno que configuraste antes:

      cat > /tmp/generated_payload.json << EOM
      {
        "critical": {
          "identity": {
            "docker-reference": "${IMAGE_PATH}"
          },
          "image": {
            "${IMAGE_DIGEST}"
          },
          "type": "Google cloud binauthz container signature"
        }
      }
      EOM
      
    2. Firma el archivo de carga útil:

      gcloud --project="${KMS_KEY_PROJECT_ID}"  \
          alpha kms asymmetric-sign \
          --location="${KMS_KEY_LOCATION}" \
          --keyring="${KMS_KEYRING_NAME}" \
          --key="${KMS_KEY_NAME}" \
          --version="${KMS_KEY_VERSION}" \
          --digest-algorithm="DIGEST_ALGORITHM" \
          --input-file=/tmp/generated_payload.json \
          --signature-file=/tmp/generated_payload.json.sig
      

      En el ejemplo anterior, DIGEST_ALGORITHM es sha256, sha384 o sha512. Este es el algoritmo de resumen de la versión de la clave que usas para firmar.

      Con este comando, se genera un archivo llamado /tmp/generated_payload.json.sig que contiene la firma digital.

    3. Recupera el certificador en cuyo nombre firmas la certificación y extrae el ID de clave pública almacenado:

      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/"
      

      La autorización binaria muestra un objeto JSON similar al siguiente:

      {
        "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"
      }
      
    4. En un editor de texto, crea un archivo JSON en /tmp/attestation.json en el que se describa la certificación:

      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": "KEY_ID",
                   "signature": "$(base64 --wrap=0 /tmp/generated_payload.json.sig)"
               }
           ]
        }
      
      }
      EOM
      

      En el ejemplo anterior, KEY_ID es el ID de clave pública que se mostró en el paso previo.

    5. Crea la certificación:

      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/"
      

Verifica que se haya creado la certificación

Ejecuta el siguiente comando para verificar que se haya creado la certificación:

gcloud

Ingresa lo siguiente en la línea de comandos:

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

REST

Recupera una lista de certificaciones:

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

Si existen varias certificaciones, se puede mostrar un valor nextPageToken en la respuesta. En este caso, la solicitud debe repetirse, pero con el parámetro de consulta pageToken configurado con este valor de nextPageToken para recuperar más certificaciones. Cuando el valor nextPageToken está vacío, significa que no hay más resultados.

curl -X GET \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: ${ATTESTATION_PROJECT_ID}" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${ATTESTATION_PROJECT_ID}/occurrences/?pageToken=${NEXT_PAGE_TOKEN}"

Próximos pasos