This tutorial describes how to use Binary Authorization in a multi-project configuration. For a simpler single-project configuration, see Get started using the Google Cloud CLI (GKE).
To establish separation of duties, you can setup Binary Authorization in a multiple-project configuration. The purpose of each project is discussed later in this tutorial.
Objectives
In this tutorial, you perform the following tasks:Set up a different project for deployment (GKE), attestor, and attestation management, to support separation of duties.
Configure the default rule of your Binary Authorization policy to require attestations.
Create Public-Key Infrastructure (X.509) (PKIX) key pair to sign, and later verify, the attestation.
Create an attestor that the Binary Authorization enforcer uses to verify the attestation.
Sign an example image, creating an attestation.
Test the policy by deploying the example image.
You must configure each project's appropriate access control through Identity and Access Management (IAM).
For additional security, you can use VPC Service Controls to help protect the resources you create in this tutorial. For more information, see Securing with VPC Service Controls.
Costs
In this document, you use the following billable components of Google Cloud:
To generate a cost estimate based on your projected usage, use the pricing calculator.
Before you begin
Note: For this configuration, you set up three projects.- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init - Install
kubectlfor interacting with GKE.
Set up the deployer project
The deployer project manages the Google Kubernetes Engine (GKE) clusters, where you deploy images, and the Binary Authorization policy that Binary Authorization enforces at deploy time. You can have more than one deployer project, depending on the size, complexity, and other requirements of your environment.
Note: To use the same attestor with multiple deployer projects, repeat the steps below, substituting DEPLOYER_PROJECT_ID with the ID of each deployer project.To set up the deployer project:
Create the project and enable billing in Google Cloud console if you have not already done so.
Identity and Access Management note: The deployer project contains your GKE cluster. The Identity and Access Management configuration for this project should reflect that.
Set environment variables to store the Google Cloud project and number:
DEPLOYER_PROJECT_ID=DEPLOYER_PROJECT_ID
Replace DEPLOYER_PROJECT_ID with the Google Cloud project ID.
DEPLOYER_PROJECT_NUMBER=$(gcloud projects describe "${DEPLOYER_PROJECT_ID}" \ --format="value(projectNumber)")Enable APIs:
Artifact Registry
gcloud --project=${DEPLOYER_PROJECT_ID} \ services enable\ container.googleapis.com\ artifactregistry.googleapis.com\ binaryauthorization.googleapis.comGet the deployer project service account name:
DEPLOYER_SERVICE_ACCOUNT="service-${DEPLOYER_PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"You use the service account name in a later step when you configure permissions on the Artifact Analysis note associated with your attestor.
Set up the attestor project
An attestor project stores the attestors that can verify that an image is ready for deployment. Often, you have a single attestor project that acts as a centralized store for information about trusted parties in the authorization process. This allows you to centrally manage security keys required to verify the identity of attestors and to restrict access to only those parties who administer them.
To set up the attestor project:
Create the project and enable billing in Google Cloud console if you have not already done so.
Identity and Access Management note: Because the this project contains your attestors, only security personnel should have write access.
Set environment variables to store the project ID and number:
ATTESTOR_PROJECT_ID=ATTESTOR_PROJECT_ID
Replace ATTESTOR_PROJECT_ID with the attestor project ID.
ATTESTOR_PROJECT_NUMBER=$(gcloud projects describe "${ATTESTOR_PROJECT_ID}" \ --format="value(projectNumber)")Enable the Artifact Analysis and Binary Authorization APIs:
gcloud services --project=${ATTESTOR_PROJECT_ID} \ enable containeranalysis.googleapis.com \ binaryauthorization.googleapis.comGet the attestor project service account name:
ATTESTOR_SERVICE_ACCOUNT="service-${ATTESTOR_PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"You use the service account name in a later step when you configure permissions on the Artifact Analysis note associated with your attestor.
Set up the attestations project
An attestation project is one that stores attestations that attestors make when they verify an image. A separate attestation project allows you to organize and inspect statements about software readiness more easily.
Create the project and enable billing in Google Cloud console if you have not already done so.
Identity and Access Management note: All roles involved in binary authorization should have read access to the Artifact Analysis Notes and Occurrences in this project, however only attestation managers need to have write access.
Set an environment variable to store the project name:
ATTESTATION_PROJECT_ID=ATTESTATION_PROJECT_ID
Replace ATTESTATION_PROJECT_ID with the attestation project ID.
Enable the Artifact Analysis and Binary Authorization APIs:
gcloud services --project=${ATTESTATION_PROJECT_ID} \ enable containeranalysis.googleapis.com \ binaryauthorization.googleapis.com
Create a cluster
Now you can create a GKE cluster in the deployer project.
This is the cluster where you want your deployed container images to run. When
you create the cluster, you pass the --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE flag to the
gcloud container clusters create command.
To create the cluster:
gcloud --project=${DEPLOYER_PROJECT_ID} \
container clusters create \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE \
--zone us-central1-a \
test-cluster
Here, you create a cluster named test-cluster in the
GKE zone us-central1-a.
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 --project=${DEPLOYER_PROJECT_ID} \
container clusters get-credentials \
--zone us-central1-a \
test-cluster
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. You create attestors in your attestor project.
Creating an attestor requires you to:
- Create a note in Artifact Analysis to store trusted metadata used in the authorization process
- Create the attestor itself in the attestor project and associate the note you created
- Add an IAM role binding for the deployer project service account to the attestor
- Set permissions on the Artifact Analysis note
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 Artifact Analysis note
Set variables that store the name of your attestor and Artifact Analysis note:
ATTESTOR_NAME=test-attestor NOTE_ID=test-attestor-note
Replace:
- test-attestor: attestor name of your choice.
- test-attestor-note: attestor note name of your choice.
Create a JSON file in
/tmp/note_payload.jsonthat describes the Container Analysis note:cat > /tmp/note_payload.json /tmp/iam_request.json /tmp/policy.yaml /tmp/generated_payload.json
The payload JSON file has the following contents:
Artifact Registry
{ "critical": { "identity": { "docker-reference": "us-docker.pkg.dev/google-samples/containers/gke/hello-app" }, "image": { "docker-manifest-digest": "sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567" }, "type": "Google cloud binauthz container signature" } }Sign the payload.
If using local PKIX files, sign the payload with your local PKIX private key and output a signature file:
openssl dgst -sha256 -sign ${PRIVATE_KEY_FILE} /tmp/generated_payload.json > /tmp/ec_signatureThe output file is a signed version of the payload JSON file you created above.
Get the public key ID from the attestor.
You can view your public key ID at any time using the command:
gcloud container binauthz attestors describe ATTESTOR_NAME.To save your public key ID in an environment variable, enter this command:
PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \ --format='value(userOwnedGrafeasNote.publicKeys[0].id)' --project ${ATTESTOR_PROJECT_ID})Create and validate the attestation:
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}" \ --validateThe
validateflag checks that the attestation can be verified by the attestor you configured in your policy.
Verify that the attestation was created:
gcloud --project=${ATTESTATION_PROJECT_ID} \
container binauthz attestations list \
--attestor=$ATTESTOR_NAME --attestor-project=$ATTESTOR_PROJECT_ID
For more information on creating attestations, see Creating Attestations.
Retest the policy
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 uses the digest to look up
attestations. Here, Binary Authorization allows the image to be deployed because
the image has an associated attestation.
To deploy the image:
kubectl run hello-server --image ${IMAGE_TO_ATTEST} --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
Now that you have successfully deployed the container image and verified that your setup is working, you can delete the cluster you created in GKE:
gcloud --project=${DEPLOYER_PROJECT_ID} \
container clusters delete \
--zone=us-central1-a \
test-cluster
Clean up
To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.
Delete the cluster that you created in GKE:
gcloud container clusters delete \ --zone=us-central1-a \ test-clusterYou can also delete Google Cloud projects that you created for this tutorial.