Getting started using the Console

You can set up Binary Authorization in your environment in a single-project configuration or a multi-project configuration. A single-project configuration is mostly useful for testing or experimenting with the service.

This tutorial shows how to configure and test a policy in Binary Authorization where all deployment resources are located in a single project. In this tutorial, the policy requires an attestation from an attestor in order for a container image to be deployed.

The steps below describe tasks that you perform from Google Cloud Platform Console, as well as some tasks you perform using gcloud commands. To perform these steps using gcloud, see Getting Started Using the CLI.

Objectives

In this tutorial, you learn how to:

  • Create a Google Kubernetes Engine (GKE) cluster with Binary Authorization enabled
  • Create an attestor that is responsible for attesting that a required process has been completed
  • Configure a policy that requires an attestation
  • Create an attestation on behalf of the attestor
  • Test the policy by deploying a container image to Google Kubernetes Engine

Costs

This tutorial uses billable components of Cloud Platform, including:

  • Container Registry
  • GKE

Use the Pricing Calculator to generate a cost estimate based on your projected usage. New Cloud Platform users might be eligible for a free trial.

Before you begin

  1. Sign in to your Google Account.

    If you don't already have one, sign up for a new account.

  2. In the GCP Console, go to the Manage resources page and select or create a project.

    Go to the Manage resources page

  3. Make sure that billing is enabled for your Google Cloud Platform project.

    Learn how to enable billing

  4. Enable the Container Registry, Container Analysis and Binary Authorization APIs.

    Enable the APIs

  5. Install and initialize the Cloud SDK.
  6. Install kubectl.
  7. Install GnuPG 2.0 or later (gpgv2) for PGP key management.

Set the default project

The first step is to set the default Google Cloud Platform project used by the gcloud command:

PROJECT_ID=PROJECT_ID
gcloud config set project ${PROJECT_ID}

where PROJECT_ID is the name of your project.

Create a cluster with Binary Authorization enabled

Create the cluster

Now you can create a GKE cluster with Binary Authorization enabled. Here, you create a cluster named test-cluster in the GKE zone us-central1-a.

To create the cluster:

  1. Visit the GKE menu in GCP Console.

    Visit the GKE menu

  2. Click Create Cluster.

  3. Enter test-cluster in the Name field.

  4. Select Zonal in the Location Type options.

  5. Select us-central1-a from the Zone drop-down list.

  6. Click Advanced Options.

  7. In the Security section, select Enable Binary Authorization.

    Enable Binary Authorization option

  8. Click Create.

Configure kubectl

You must also update the local kubeconfig file for your kubectl installation. This provides the credentials and endpoint information required to access the cluster in GKE.

To update the local kubeconfig file:

gcloud container clusters get-credentials \
    --zone us-central1-a \
    test-cluster

View the default policy

A policy in Binary Authorization is a set of rules that govern the deployment of container images. You can have one policy per project. By default, the policy is configured to allow all container images to be deployed.

To view the default policy:

  1. Go to the Binary Authorization page in the Google Cloud Platform Console.

    Go to the Binary Authorization page

  2. In the Policy tab, click Edit Policy.

    Screenshot of policy tab showing default rule

  3. In Project Default Rule, the option Allow All Images is displayed.

    Screenshot of the option to choose a default rule type

  4. Click Cancel.

Create an attestor

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 authorization process
  • Create the attestor itself in Binary Authorization and associate the note you created

For this tutorial, you have one attestor named test-attestor and a Container Analysis note named test-attestor-note. In a real-world scenario, you can have any number of attestors, each one representing a party that participates in the authorization process for the image.

Create the Container Analysis note

  1. Set variables that store the name of your attestor and Container Analysis note:

    ATTESTOR=test-attestor
    NOTE_ID=test-attestor-note
    
  2. Create a JSON file in /tmp/note_payload.json that describes the Container Analysis note:

    cat > /tmp/note_payload.json << EOM
    {
      "name": "projects/${PROJECT_ID}/notes/${NOTE_ID}",
      "attestation_authority": {
        "hint": {
          "human_readable_name": "Attestor Note"
        }
      }
    }
    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/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
    
  4. Verify that the note was created:

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

Set up PGP keys

Binary Authorization uses cryptographic keys to securely verify the identity of attestors. This ensures that only verified parties can participate in the authorization of a container image. 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.

In this tutorial, you use PGP cryptographic keys. However, you can also use PKIX keys as an alternative. The asymmetric keys generated and stored by Cloud Key Management Service (Cloud KMS) are PKIX-compliant. See Creating attestors using the Console for more information on using PKIX keys and Cloud KMS.

To generate a PGP key pair:

  1. Run gpg --gen-key from the command line:

    gpg --batch --gen-key <(
      cat <<- EOF
        Key-Type: RSA
        Key-Length: 2048
        Name-Real: "Test Attestor"
        Name-Email: "test-attestor@example.com"
        %commit
    EOF
    )
    
  2. Find the fingerprint for the PGP public key:

    gpg --list-keys "test-attestor@example.com"
    

    This command prints:

    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 hexidecimal string, such as ABAB2098B3F5F05FF0D12ABE45895BDDDCD17B90. See the OpenPGP RFC for more information on PGP fingerprints.

  3. Set a variable that stores the fingerprint:

    FINGERPRINT=PUBLIC_KEY_FINGERPRINT
    
  4. Export the public key:

    gpg --armor --export ${FINGERPRINT} > /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 the attestor

Now you can create the attestor itself in Binary Authorization and associate the PGP public key that you created.

To create the attestor:

  1. Return to the Binary Authorization page in the Google Cloud Platform Console.

  2. In the Attestors tab, click Create.

    Screenshot of policy tab showing default rule

  3. Click Create New Attestor.

    Screenshot of Create Attestors page

  4. Enter test-attestor in the Attestor Name field.

  5. Enter projects/PROJECT_ID/notes/test-attestor-note in the Container Analysis Note Name field.

  6. Click Add a PGP Public Key.

    Screenshot of PGP public keys text box

  7. Open /tmp/generated-key.pgp in a text editor. This is the public key file that you created in the previous step. Copy the contents of the file to the Paste Key text box and click Done.

  8. Click Create.

Configure the policy

Now, you can configure your policy:

  1. Return to the Binary Authorization page in Google Cloud Platform Console.

  2. In the Policy tab, click Edit Policy.

  3. Select Allow Only Images That Have Been Approved By the Following Attestors.

    Screenshot of the option to choose a default rule type

  4. Click Add Attestors.

    Screenshot of the option to choose a default rule type

  5. Enter projects/PROJECT_ID/attestors/test-attestor in the Attestor Name field.

  6. Click Add 1 Attestor.

  7. Click Save Policy.

For more information, see Configuring a Policy Using the Console.

Test the policy

You can test the policy you configured above by trying to deploy a sample container image to the cluster. The policy will block deployment because the required attestation has not been made.

For this tutorial, you can use the sample image located at the path gcr.io/google-samples/hello-app in Container Registry. This is a public container image created by Google that contains a Hello, World! sample application.

To try to deploy the image:

kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080

Now, verify that the deployment was blocked by Binary Authorization:

kubectl get pods

The command prints the following message, which indicates that the image was not deployed:

No resources found.

You can get further details about the deployment:

kubectl get event --template \
'{{range.items}}{{"\033[0;36m"}}{{.reason}}:{{"\033[0m"}}\{{.message}}{{"\n"}}{{end}}'

which shows that the deployment was disallowed by the policy:

FailedCreate: Error creating: pods "hello-server-579859fb5b-hjvnr" is forbidden: image policy webhook backend denied one or more images: Denied by default admission rule. Denied by Attestation Authority. Image gcr.io/google-samples/hello-app:1.0 denied by projects/example-project/attestors/test-attestor: No attestations found

Make sure to delete the deployment so you can continue to the next step:

kubectl delete deployment hello-server

Create an attestation

An attestation is a statement by an attestor that a required process in your pipeline has been completed and that the container image in question 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 your container image registry, as well as the identity of the attestor.

In this tutorial, your attestation simply states that you authorize the image for deployment.

To create an attestation:

  1. Set variables that store the registry path and digest of the image:

    IMAGE_PATH="gcr.io/google-samples/hello-app"
    IMAGE_DIGEST="sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4"
    
  2. Generate the attestation payload:

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

    The payload JSON file has the following contents:

    {
      "critical": {
        "identity": {
          "docker-reference": "gcr.io/google-samples/hello-app"
        },
        "image": {
          "docker-manifest-digest": "sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea
    882eb722c3be4"
        },
        "type": "Google cloud binauthz container signature"
      }
    }
    
  3. Sign the payload with your PGP private key and output a signature file:

    gpg \
        --local-user "test-attestor@example.com" \
        --armor \
        --output /tmp/generated_signature.pgp \
        --sign /tmp/generated_payload.json
    

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

  4. Create the attestation:

    gcloud beta container binauthz attestations create \
        --artifact-url="${IMAGE_PATH}@${IMAGE_DIGEST}" \
        --attestor="projects/${PROJECT_ID}/attestors/${ATTESTOR}" \
        --signature-file=/tmp/generated_signature.pgp \
        --pgp-key-fingerprint="${FINGERPRINT}"
    

    where FINGERPRINT is the public key fingerprint that you found in Generate a PGP key pair above.

  5. Verify that the attestation was created:

    gcloud beta container binauthz attestations list \
        --attestor=$ATTESTOR --attestor-project=$PROJECT_ID
    

For more information on creating attestations, see Creating Attestations.

Retest the policy

Again, test the policy by deploying a sample container image to the cluster. This time, you must deploy the image using the digest rather than a tag like 1.0 or latest, as Binary Authorization will use both the image path and digest to look up attestations. Here, Binary Authorization allows the image to be deployed because the required attestation has been made.

To deploy the image:

kubectl run hello-server --image ${IMAGE_PATH}@${IMAGE_DIGEST} --port 8080

To verify that the image was deployed:

kubectl get pods

The command prints a message similar to the following, which indicates that deployment was successful:

NAME                            READY     STATUS    RESTARTS   AGE
hello-server-579859fb5b-h2k8s   1/1       Running   0          1m

Cleaning up

To avoid incurring charges to your Google Cloud Platform account for the resources used in this tutorial:

Delete the cluster you created in GKE:

gcloud container clusters delete \
    --zone=us-central1-a \
    test-cluster

What's next

Send feedback about...

Binary Authorization