Creating attestors using the CLI

This page explains how to create an attestor in Binary Authorization at the the command line using gcloud commands and the REST API. As an alternative, you can also perform these steps using the Google Cloud Platform Console. This task is part of setting up Binary Authorization.

Overview

An attestor is a party that is responsible for attesting that a required process has completed before a container image can be deployed. This party can be a human user or, more often, a machine process like a build and test system, or your continuous integration (CI) and deployment (CD) pipelines.

Creating an attestor requires you to:

  • Create a note in Container Analysis to store trusted metadata used in the attestation process.
  • Set up a PGP or PKIX key pair that can be used to verify the identity of the attestor. (Asymmetric key pairs generated by Cloud Key Management Service are in PKIX-compatible format.)
  • Create the attestor itself in Binary Authorization, and associate the note and public key you created.

In a single-project setup, you create your attestor in the same Google Cloud Platform project where you configure your Binary Authorization policy. In a multi-project setup, you most likely have a deployer project where your policy is configured and a separate attestor project where your attestors are stored.

Set up the environment

Set up environment variables to store your project names and numbers:

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

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

You must also get the service account names for the projects:

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"

Create a Container Analysis note

Binary Authorization uses Container Analysis to store trusted metadata used in the authorization process. For each attestor you create, you must create one Container Analysis note. Each attestation is stored as an occurrence of this note.

To create a Container Analysis note:

  1. Set up environment variables to store the note ID and a human-readable description:

    NOTE_ID=NOTE_ID
    DESCRIPTION=DESCRIPTION
    

    where:

    • NOTE_ID is the internal name of the note in alphanumeric characters with no spaces (for example, test-attestor-note)
    • DESCRIPTION is a human-readable display name for the note (for example, Test Attestor Note)
  2. In a text editor, create a JSON file in /tmp/note_payload.json that describes the Container Analysis note:

    cat > /tmp/note_payload.json << EOM
    {
      "name": "projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}",
      "attestation_authority": {
        "hint": {
          "human_readable_name": "${DESCRIPTION}"
        }
      }
    }
    EOM
    
  3. Create the note by sending an HTTP request to the Container Analysis REST API:

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

To verify that the note was created successfully:

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

Set permissions on the note

You must also set permissions on the Container Analysis note you created so that it is accessible to the attestor project service account. You do this by updating the IAM policy for the note to assign the containeranalysis.notes.occurrences.viewer role to the account.

To set the permissions:

  1. Generate a JSON file that contains the information needed to set the IAM policy on your note:

    cat > /tmp/iam_request.json << EOM
    {
      'resource': 'projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}',
      'policy': {
        'bindings': [
          {
            'role': 'roles/containeranalysis.notes.occurrences.viewer',
            'members': [
              'serviceAccount:${ATTESTOR_SERVICE_ACCOUNT}'
            ]
          }
        ]
      }
    }
    EOM
    
  2. Add the service account and requested access roles to the IAM policy for the note you created:

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

Set up cryptographic keys

Binary Authorization allows you to use PGP key pairs or PKIX keys to securely verify the identity of attestors. This ensures that only verified parties can authorize a container image.

Create a PGP key pair

A PGP key pair consists of a private key, which you use to digitally sign attestations, and a public key, which you add to the attestor as stored by the Binary Authorization service.

To generate the key pair:

  1. Install GnuPG 2.0 or later (gpgv2) for PGP key management.

  2. Set up environment variables to store the name of the attestor and an e-mail address associated with the key pair:

    ATTESTOR_NAME=ATTESTOR_NAME
    ATTESTOR_EMAIL=ATTESTOR_EMAIL
    

    where:

    • ATTESTOR_NAME is the name of the attestor (for example, test-attestor)
    • ATTESTOR_EMAIL is the e-mail address associated with the attestor (for example, attestor@example.com)
  3. Run gpg --gen-key from the command line:

    gpg --batch --gen-key <(
      cat <<- EOF
        Key-Type: RSA
        Key-Length: 2048
        Name-Real: "${ATTESTOR_NAME}"
        Name-Email: "${ATTESTOR_EMAIL}"
        %commit
    EOF
    )
    
  4. Export the public key:

    gpg --armor --export "${ATTESTOR_EMAIL}" > /tmp/generated-key.pgp
    

The exported public key is located in /tmp/generated-key.pgp. The private key is stored on the local system where you ran the gpg --gen-key command.

Create a PKIX key pair

Binary Authorization allows you to use asymmetric PKIX key pairs instead of PGP keys to verify the identity of an attestor. As with PGP keys, the key pair consists of a private key, which the attestor uses to digitally sign attestations, and a public key, which you add to the attestor as stored by the Binary Authorization service.

The asymmetric key pairs generated and stored in Cloud Key Management Service are compliant with the PKIX format. To create a Cloud Key Management Service key for use with Binary Authorization, see Creating Asymmetric Keys. Make sure that you choose Asymmetric Sign as the key purpose when you create the key.

Create the attestor

The next step is to create the attestor itself in Binary Authorization with the associated Container Analysis note. You must also add the cryptographic public key.

To create the attestor:

  1. Set up an environment variable to store the name of the attestor as defined in Binary Authorization:

    ATTESTOR=ATTESTOR
    

    where:

    • ATTESTOR is the name of the attestor you want to create (for example, build-secure or prod-qa).
  2. Create the attestor resource in Binary Authorization:

    gcloud --project="${ATTESTOR_PROJECT_ID}" \
        beta container binauthz attestors create "${ATTESTOR}" \
        --attestation-authority-note="${NOTE_ID}" \
        --attestation-authority-note-project="${ATTESTOR_PROJECT_ID}"
    
  3. Add an IAM role binding for the deployer project to the attestor. This is used by Binary Authorization when it evaluates a policy to determine whether the project has permissions to access any associated attestations.

    gcloud beta container binauthz attestors add-iam-policy-binding \
      "projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR}" \
      --member="serviceAccount:${DEPLOYER_SERVICE_ACCOUNT}" \
      --role=roles/binaryauthorization.attestorsVerifier
    
  4. Add the public key to the attestor:

    PGP

    gcloud --project="${ATTESTOR_PROJECT_ID}" \
        beta container binauthz attestors public-keys add \
        --attestor="${ATTESTOR}" \
        --public-key-file=/tmp/generated-key.pgp
    

    where /tmp/generated-key.pgp is the file to which you exported the public key above.

    PKIX/Cloud KMS

    1. Set up environment variables to store information about the key pair as managed by Cloud Key Management Service:

      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 the keys are stored
      • KMS_KEY_LOCATION is the location of the key
      • 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. Add the public key to the attestor:

      gcloud --project="${ATTESTOR_PROJECT_ID}" \
          alpha container binauthz attestors public-keys add \
          --attestor="${ATTESTOR}" \
          --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}"
      

Verify that the attestor was created

To verify that the attestor was created:

gcloud --project="${ATTESTOR_PROJECT_ID}" \
    beta container binauthz attestors list

What's next

Was this page helpful? Let us know how we did:

Send feedback about...

Binary Authorization Documentation