Securing Cloud Run Ingress Traffic

1. Overview

This lab shows you how to restrict access to a Cloud Run service and allow only requests from a workload running on premises or in your project's VPC. There are two layers of access control you can use: ingress settings and Identity and Access Management (IAM) policies.

5aed47d10595c878.png

Ingress settings

Ingress settings let you filter requests based on their network origin (internal or external). By default, all requests are allowed to pass through, including those from the public internet.

IAM policy

IAM policies let you filter requests based on the identity of the sender, and are commonly used to authenticate service-to-service requests.

In this lab, you'll learn how and when to use ingress settings.

On-premises hosts connect through the VPC

In this lab, we'll simulate an on-premises workload. To connect an on-premises host to Cloud Run, you would configure Private Google Access for on-premises hosts. This includes setting up a Cloud VPN gateway in the VPC network, as shown below.

31611f6a2f12fd0c.png

Simulating an on-premise workload using a jump server in the VPC

In this lab, you'll simulate sending requests from an on-premises host by sending requests from a Compute Engine virtual machine in the VPC, as shown here.

aebf22740c7a84f0.png

The Compute Engine virtual machine you'll use as a jump server has the same network origin as the Cloud VPN Gateway, which is why you are able to use this to simulate sending requests from an on-premises workload.

2. Setup and Requirements

Self-paced environment setup

  1. Sign-in to the Google Cloud Console and create a new project or reuse an existing one. If you don't already have a Gmail or Google Workspace account, you must create one.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • The Project name is the display name for this project's participants. It is a character string not used by Google APIs. You can update it at any time.
  • The Project ID must be unique across all Google Cloud projects and is immutable (cannot be changed after it has been set). The Cloud Console auto-generates a unique string; usually you don't care what it is. In most codelabs, you'll need to reference the Project ID (it is typically identified as PROJECT_ID). If you don't like the generated ID, you may generate another random one. Alternatively, you can try your own and see if it's available. It cannot be changed after this step and will remain for the duration of the project.
  • For your information, there is a third value, a Project Number which some APIs use. Learn more about all three of these values in the documentation.
  1. Next, you'll need to enable billing in the Cloud Console to use Cloud resources/APIs. Running through this codelab shouldn't cost much, if anything at all. To shut down resources so you don't incur billing beyond this tutorial, you can delete the resources you created or delete the whole project. New users of Google Cloud are eligible for the $300 USD Free Trial program.

Environment Setup

  1. Set an environment variable to the Project ID for use in later commands:
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ZONE=us-central1-a
  1. Enable the APIs required to execute this lab.
gcloud services enable \
  run.googleapis.com \
  cloudbuild.googleapis.com \
  compute.googleapis.com \
  artifactregistry.googleapis.com
  1. Clone the sample app repository and navigate to the directory
git clone https://github.com/momander/cymbal-eats.git

cd cymbal-eats/partner-registration-service
  1. Set the default region and zone for Compute Engine and Cloud Run
gcloud config set compute/region ${REGION}
gcloud config set run/region ${REGION}
gcloud config set compute/zone ${ZONE}

3. Deploy the service

You'll first deploy the service and leave it publicly accessible. After you've verified that you can send requests from your browser, we'll lock the service down and allow only requests from internal network sources.

When you run the following command, follow these instructions:

  • Source code location (...): Verify you're in the partner-registration-service directory and hit enter to accept the default
  • Service name (partner-registration-service): Hit enter to accept the default
  • Allow unauthenticated invocations to [partner-registration-service] (y/N)? Y
gcloud run deploy 

When this command completes, it lists the URL of your Cloud Run service. The output will look similar to this listing:

Service [partner-registration-service] revision [partner-registration-service-00001-haz] has been deployed and is serving 100 percent of traffic.
Service URL: https://partner-registration-service-ssssssssss-uc.a.run.app

Open the service URL in your browser. You should see this output:

Partner registration service: RUNNING

Set the service to allow only internal requests

Now, you'll use ingress settings of the Cloud Run service to only allow requests from internal sources. Internal sources include resources in VPC networks that are in the same project (or VPC Service Controls perimeter) as the Cloud Run service - which makes it perfect for our use case.

Additionally, requests from other Google Cloud products are considered internal, even if they are not part of the VPC. Those products include for example Pub/Sub and Workflows.

Requests from these sources stay within the Google network, even if they access your service at the run.app URL, and public access is forbidden.

Update the service to allow only internal requests:

gcloud run services update partner-registration-service --ingress=internal

If you open the service URL again, it'll say "Error: Forbidden - Access is forbidden"

Since your browser sends the request from an external network origin, and not from an origin internal to the Google Cloud project, this is exactly what you expect to happen. Your service is now more secure.

4. Create a Compute Engine virtual machine as a jump server

The next step is to simulate requests from an on-premises server through a Cloud VPN gateway, by creating a Compute Engine instance in the VPC to use as a jump server:

gcloud compute instances create jump-server --scopes=https://www.googleapis.com/auth/cloud-platform

The output of this command should be something similar to this:

NAME         ZONE           MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
jump-server  us-central1-a  n1-standard-1               10.128.0.10  34.170.108.8  RUNNING

Send a request from the Compute Engine instance to the service

You'll now open a terminal on the virtual machine and send a request directly from the machine in the VPC network.

If the following command prompts you to set up SSH in Cloud Shell, follow the instructions:

gcloud compute ssh jump-server

Get the URL of the Cloud Run service with this command:

gcloud run services describe partner-registration-service --region us-central1

The first few lines of the output should look like this:

✔ Service partner-registration-service in region us-central1

URL:     https://partner-registration-service-ssssssssss-uc.a.run.app
Ingress: internal

Now copy the URL and send a request from the Compute Engine instance using curl. This request should succeed, because the VM instance runs in your project's VPC network - it's an internal source.

export SERVICE_URL=https://

curl ${SERVICE_URL}

The output should say:

Partner registration service: RUNNING

5. What about IAM-based access control?

This lab showed you how and when to use ingress settings. Ingress settings are a great first step if you're connecting an on-premise workload to Cloud Run.

IAM-based access control requires more effort to implement, especially if you're calling from an on-premises host:

  • IAM requires you to manage long-lived service account credentials on the host
  • IAM requires code changes to sign requests using the service account credentials.

Google recommends a multi-layered approach to access control. Using ingress settings to restrict access to only internal hosts is a great first step, but don't stop there!

6. Congratulations!

Congratulations, you finished the codelab!

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.

Deleting the project

The easiest way to eliminate billing is to delete the project that you created for the tutorial.

Useful references

Here are additional resources that help you learn more about the two layers of access control on Cloud Run.