Creating attestations

This page explains how to create an attestation in Binary Authorization from the command line.

The instructions on this page outline the steps that an attestor needs to perform in order to authorize a container image for deployment. In a real-world scenario, you incorporate these steps into a script or automation that can be triggered by machine process or a human user, rather than enter them manually at the command line.

Overview

An attestation is a statement by an attestor that a required process in your pipeline has been completed and that a container image is authorized for deployment. The attestation itself is a digitally-signed record that contains the full path to a version of the image as stored in your container image registry, as well as the identity of the attestor.

You can create an attestation using either a PGP or PKIX signature.

Set the default project

If you have not already set your default Google Cloud Platform project:

PROJECT_ID=PROJECT_ID
gcloud config set project ${PROJECT_ID}

where PROJECT_ID is the name of your project.

Set up the environment

  1. Set up environment variables to store your project IDs:

    ATTESTOR_PROJECT_ID=ATTESTOR_PROJECT_ID
    ATTESTATION_PROJECT_ID=ATTESTATION_PROJECT_ID
    

    where:

    • ATTESTOR_PROJECT_ID is the name of the project where you are storing your attestors
    • ATTESTATION_PROJECT_ID is the name of the project where you are storing your attestations

    If your attestor and attestation projects are the same project, use the same project ID for both variables.

  2. Set up environment variables to store the name of the attestor who is making the attestation and the registry path to the image you want to deploy:

    ATTESTOR=ATTESTOR_NAME
    IMAGE_PATH=IMAGE_PATH
    IMAGE_DIGEST=IMAGE_DIGEST
    IMAGE_TO_ATTEST="${IMAGE_PATH}@${IMAGE_DIGEST}"
    

    where:

    • ATTESTOR_NAME is the name of the attestor (for example, build-secure or prod-qa)
    • IMAGE_PATH is the path in Container Registry to the image you want to deploy (for example, gcr.io/example-project/quickstart-image)
    • IMAGE_DIGEST is the SHA-256 digest of the image manifest (for example, sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4). For information on getting the image digest, see Listing the versions of an image in Container Registry

Each container image stored in Container Registry or another registry has a unique path to its location, as well as a SHA-256 digest that uniquely identifies its version. Attestations reference the full image path and digest, which allows you to authorize specific versions of an image.

The following is an example of a full registry path:

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

Create an attestation with a PGP signature

For attestations signed with a PGP public key, you do the following:

  • Create an attestation payload to send to Binary Authorization that references the registry path
  • Sign the payload and generate a PGP signature file
  • Get the public key fingerprint
  • Create the attestation with the signature file and public key fingerprint

Create an attestation payload

The attestation payload is a JSON-formatted file that references the location of the container image.

To create the payload file:

gcloud

Enter the following:

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

The payload file looks similar to the following:

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

REST

Create a payload file named /tmp/generated_payload.json using the environment variables you set above:

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

Sign the payload and generate a signature file

After you have created the payload file, you must sign it using the public cryptographic key you generated when you created the attestor using the CLI or console.

To sign the payload file:

  1. Set up an environment variable to store the e-mail of the attestor as defined when you generated the PGP key pair:

    ATTESTOR_EMAIL=ATTESTOR_EMAIL
    
  2. Sign the generated payload:

    gpg \
        --local-user "${ATTESTOR_EMAIL}" \
        --armor \
        --output /tmp/generated_signature.pgp \
        --sign /tmp/generated_payload.json
    

The output file is a digitally-signed version of the payload file you created above.

Get the public key fingerprint

You must send a public key fingerprint to Binary Authorization along with the signature file when you create an attestation.

To get the public key fingerprint:

  1. Get the key details:

    gpg --list-keys ${ATTESTOR_EMAIL}
    

    This command prints a message similar to the following:

    pub   rsa2048 2018-07-05 [SCEA]
          PUBLIC_KEY_FINGERPRINT
    uid           [ultimate] "Test Attestor" <"attestor@example.com">
    

    where PUBLIC_KEY_FINGERPRINT is the version 4, full 160-bit fingerprint, expressed as a 40 character hexadecimal string, such as ABAB2098B3F5F05FF0D12ABE45895BDDDCD17B90. See the OpenPGP RFC for more information on PGP fingerprints.

  2. Set up an environment variable to store the fingerprint:

    PUBLIC_KEY_FINGERPRINT=PUBLIC_KEY_FINGERPRINT
    

Create the attestation

To create the attestation:

gcloud

Enter the following:

gcloud beta container binauthz attestations create \
    --project="${ATTESTATION_PROJECT_ID}" \
    --artifact-url="${IMAGE_TO_ATTEST}" \
    --attestor="projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR}" \
    --signature-file=/tmp/generated_signature.pgp \
    --public-key-id="${PUBLIC_KEY_FINGERPRINT}"

REST

  1. Retrieve the attestor on whose behalf you are are signing the attestation and extract stored public key ID:

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

    Binary Authorization returns a JSON object similar to the following:

    {
      "name": "projects/axgillies-binauthz-rest/attestors/axgillies-test-attestor-2",
      "userOwnedGrafeasNote": {
        "noteReference": "projects/axgillies-binauthz-rest/notes/axgillies-test-attestor-2",
        "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. In a text editor, create a JSON file in /tmp/attestation.json that describes the attestation:

    cat > /tmp/attestation.json << EOM
    {
      "resource": {
        "uri": "${IMAGE_TO_ATTEST}"
      },
      "note_name": "${NOTE_URI}",
      "attestation": {
        "attestation": {
          "generic_signed_attestation": {
            "content_type": "SIMPLE_SIGNING_JSON",
            "serialized_payload": "$(base64 --wrap=0 /tmp/generated_payload.json)",
            "signatures": [
                {
                "public_key_id": "KEY_ID",
                    "signature": "$(base64 --wrap=0 /tmp/generated_signature.pgp)"
                }
            ]
          }
        }
      }
    }
    EOM
    

    where KEY_ID is the public key ID returned in the previous step.

  3. Create the attestation:

    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/v1beta1/projects/${ATTESTATION_PROJECT_ID}/occurrences/"
    

Create an attestation with a PKIX signature

To create an attestation with PKIX signature:

  1. Set up environment variables to store information about the projects where your attestations, attestors and Cloud Key Management Service keys are stored, as well as information about your PKIX key pair:

    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
    

    where:

    • KMS_KEY_PROJECT_ID is the ID of the project where your Cloud Key Management Service keys are stored
    • KMS_KEY_LOCATION is the location of the key (global is the default)
    • KMS_KEYRING_NAME is the name of the key ring
    • KMS_KEY_NAME is the name of the key
    • KMS_KEY_VERSION is the key version
  2. Sign and create the attestation:

    gcloud

    Enter the following at the command line:

    gcloud alpha container binauthz attestations sign-and-create \
        --project="${ATTESTATION_PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="${ATTESTOR}" \
        --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. Create a payload file named /tmp/generated_payload.json using the environment variables you set above:

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

      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
      

      where DIGEST_ALGORITHM is one of sha256, sha384, or sha512. This is the digest algorithm of the key version you are using for signing.

      This commands outputs a file named /tmp/generated_payload.json.sig that contains the digital signature.

    3. Retrieve the attestor on whose behalf you are are signing the attestation and extract stored public key ID:

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

      Binary Authorization returns a JSON object similar to the following:

      {
        "name": "projects/axgillies-binauthz-rest/attestors/axgillies-test-attestor-2",
        "userOwnedGrafeasNote": {
          "noteReference": "projects/axgillies-binauthz-rest/notes/axgillies-test-attestor-2",
          "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. In a text editor, create a JSON file in /tmp/attestation.json that describes the attestation:

      cat > /tmp/attestation.json << EOM
      {
        "resource": {
          "uri": "${IMAGE_TO_ATTEST}"
        },
        "note_name": "${NOTE_URI}",
        "attestation": {
          "attestation": {
            "generic_signed_attestation": {
              "content_type": "SIMPLE_SIGNING_JSON",
              "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
      

      where KEY_ID is public key ID returned in the previous step.

    5. Create the attestation:

      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/v1beta1/projects/${ATTESTATION_PROJECT_ID}/occurrences/"
      

Verify that the attestation was created

To verify that the attestation was created:

gcloud

Enter the following at the command line:

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

REST

Retrieve a list of attestations:

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/v1beta1/projects/${ATTESTATION_PROJECT_ID}/occurrences/"

What's next

Оцените, насколько информация на этой странице была вам полезна:

Оставить отзыв о...

Текущей странице
Binary Authorization Documentation