Skip to content

Enhancing Cloud Run Security with Binary Authorization in GCP Single Project

Scenario

  • Use the Binary Authorization feature in CloudRun to enhance security control
  • Using Binary Authorization policy can check if the revision complies with policy requirements before each CloudRun service deployment
  • If you want to force deployment in non-compliant situations, you can bypass it using the breakglass feature
  • Policy does not retroactively apply to already deployed and running CloudRun services

Enable API

Projects using CloudRun or GKE need to access this, click here to enable Binary Authorization API

Click NEXT

Enable API-1

Click Enable

Enable API-2

(Optional) Confirm org settings

You can click here to check the project or org application status and settings

Enter “Allowed Binary Authorization Policies (Cloud Run)” as the filter condition to view. If adjustments are needed, follow the instructions to configure

As shown in the image below, the project inherits organizational rules

Org Policy

Set Disallow All Images Policy

Click here to set policy

Disallow Images Policy

Set default rules

  • Use default block all images and exempt image
  • If you want to enable Dry-run mode, you can check and enable it here
  • For Exempt image settings, refer to this article
    • You can specify a single image, such as: gcr.io/example-project/helloworld
      • Specify tag: gcr.io/example-project/helloworld:latest
      • Specify all versions gcr.io/example-project/helloworld:*
    • Specify a project gcr.io/example-project/*
      • Including subfolders under the project gcr.io/example-project/**
  • Save after completion

Setup Binary Authorization Policy

Enable Binary Authorization on new CloudRun service

Use Policy-compliant image

Create CloudRun service

Creating a new Cloud Run service

Use exempt image

Selecting an exempt image

Check to use binary authorization and then create

Enabling Binary Authorization

Service can be created normally

Service created successfully

Use non-Policy-compliant image

Same as the previous steps, but choose a different image

Selecting non-compliant image

A message appears indicating inability to deploy, you can click BREAKGLASS

Deployment blocked message

Enter the reason, then click BREAKGLASS again

Breakglass justification

After BREAKGLASS, it can operate normally

Service deployed after Breakglass

Audit log information

Default disallow using non-allowed image

You can go to Log Explorer to query, enter the following filter conditions to view records

1
resource.type="cloud_run_revision"
2
logName:"cloudaudit.googleapis.com%2Fsystem_event"
3
protoPayload.response.status.conditions.reason="ContainerImageUnauthorized"

The following record will appear

Audit log for blocked deployment

Using Dry run audit log

1
resource.type="cloud_run_revision"
2
logName:"cloudaudit.googleapis.com%2Fsystem_event"
3
"dry run"

Dry run audit log

Breakglass audit log

For breakglass records, you can use the following filter conditions to search

1
protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog"
2
"run.googleapis.com/binary-authorization-breakglass"

The red box shows the reason entered

Breakglass audit log

SCC integration

Currently, SCC supports the following events, but it’s still in the Preview stage

SCC supported events

Data source

SCC data source

Data source

Set Attestations Policy

Since using attestations requires preliminary steps to create attestor and PKIX key, this case uses KMS to create PKIX, and finally sign the image with attestations.

The creation process is as follows:

  1. Create KMS Key in GCP
  2. Set up attestor
  3. Set binary authorization policy
  4. Use attestations

Set up KMS

Enable KMS API

First-time use requires enabling the KMS API

Enable KMS API - Step 1

Enable KMS API - Step 2

Enter in the search bar

Cloud Key Management Service (KMS) API

Search for KMS API

Click to enter

Select KMS API

Enable

Enable KMS API

Create Key

Create Key Rings

Create Key Rings

Perform the following actions as needed

  1. Name
  2. Region
  3. Create

Configure Key Ring

After completion, create Key, enter name, select software for protection level, choose Asymmetric sign for purpose, and select Elliptic Curve P-256 - SHA256 Digest for algorithm

Create Key

After completion, click create

Finish Key Creation

After creation, click to enter

Enter Key Details

Copy the Key resource name for later use

Copy Key Resource Name

Set up Attestor

Enable Attestor API

As with the steps to enable the KMS API, search for containeranalysis.googleapis.com and enable the API

Enable Container Analysis API

Enable binaryauthorization.googleapis.com API

Enable Binary Authorization API

Add Attestor

Add New Attestor

  1. Create name
  2. Expand
  3. Paste the Key resource name copied earlier
  4. Complete

Configure Attestor

After pasting, SUBMIT

Submit Attestor Configuration

  1. Click DONE
  2. Confirm that Automatically generate a Container Analysis note is checked
  3. Click CREATE

Create Public Key

Set Binary Authorization Policy

Binary Authorization Policy Setup

Add the recently created Attestor

  1. Choose Require attestations
  2. Add attestor
  3. Save settings

Edit Binary Authorization Policy

Add attestors

  1. Select name
  2. Add

Add Attestor

Using Attestation

Attest image

Currently, only gcloud commands are supported for implementation

Set the following environment variables and execute

Terminal window
1
ATTESTOR_PROJECT_ID="YOUR_PROJECT_ID"
2
ATTESTATION_PROJECT_ID="YOUR_PROJECT_ID"
3
ATTESTOR_NAME="demo-attstor"
4
IMAGE_PATH="asia-east1-docker.pkg.dev/YOUR_PROJECT_ID/allow-repo/nginx"
5
IMAGE_DIGEST="sha256:YOUR_IMG_DIGEST"
6
IMAGE_TO_ATTEST="${IMAGE_PATH}@${IMAGE_DIGEST}"
7
KMS_KEY_PROJECT_ID="YOUR_PROJECT_ID"
8
KMS_KEY_LOCATION="global"
9
KMS_KEYRING_NAME="image-keys"
10
KMS_KEY_NAME="binary-auth-key"
11
KMS_KEY_VERSION=1
12
13
gcloud beta container binauthz attestations sign-and-create \
14
--project="${ATTESTATION_PROJECT_ID}" \
15
--artifact-url="${IMAGE_TO_ATTEST}" \
16
--attestor="${ATTESTOR_NAME}" \
17
--attestor-project="${ATTESTOR_PROJECT_ID}" \
18
--keyversion-project="${KMS_KEY_PROJECT_ID}" \
19
--keyversion-location="${KMS_KEY_LOCATION}" \
20
--keyversion-keyring="${KMS_KEYRING_NAME}" \
21
--keyversion-key="${KMS_KEY_NAME}" \
22
--keyversion="${KMS_KEY_VERSION}"

Confirm if the execution was successful, list existing Attestations

Terminal window
1
gcloud container binauthz attestations list \
2
--attestor-project=${ATTESTOR_PROJECT_ID} \
3
--attestor=${ATTESTOR_NAME}

Expected result

1
---
2
attestation:
3
serializedPayload: xxxxxxxxx
4
signatures:
5
- publicKeyId: //cloudkms.googleapis.com/v1/projects/YOUR_PROJECT_ID/locations/global/keyRings/image-keys/cryptoKeys/binary-auth-key/cryptoKeyVersions/1
6
signature: MEUCIDdfSyE-2SNAXVxzh4FzfEtwgnBEFs9sY4BFAqH3fZLdAiEAmfk6Ov-TUGwyx2qWVQTIni_fYvWi-ye6ObmCVr6i4AU=
7
createTime: '2023-07-27T06:21:02.953969Z'
8
kind: ATTESTATION
9
name: projects/YOUR_PROJECT_ID/occurrences/32524935-0c65-4d7e-b9e6-2c7b1fceadcd
10
noteName: projects/YOUR_PROJECT_ID/notes/demo-attstor-note
11
resourceUri: asia-east1-docker.pkg.dev/YOUR_PROJECT_ID/allow-repo/nginx@sha256:YOUR_IMG_DIGEST
12
updateTime: '2023-07-27T06:21:02.953969Z'

Test Policy

The testing method is the same as Enable Binary Authorization on new CloudRun service, but this method mainly judges the sha value of the image. After testing, if two images are in different repos but have the same sha, they can still be deployed normally.

Delete attestation

List existing Attestations

Terminal window
1
gcloud container binauthz attestations list \
2
--attestor-project=${ATTESTOR_PROJECT_ID} \
3
--attestor=${ATTESTOR_NAME}

Copy the id after occurrences

1
---
2
...
3
kind: ATTESTATION
4
name: projects/YOUR_PROJECT_ID/occurrences/32524935-xxxx-xxxx-xxxx-2c7b1fceadcd
5
...

Enter the following command to delete

Terminal window
1
OCCURRENCE_ID="32524935-xxxx-xxxx-xxxx-2c7b1fceadcd"
2
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -X DELETE https://containeranalysis.googleapis.com/v1beta1/projects/${ATTESTATION_PROJECT_ID}/occurrences/${OCCURRENCE_ID}