Skip to main content

Cloud Run access & networking

Exam guide§2.1

Two independent layers guard a Cloud Run service, and you can stack them:

  • IAM authentication - who may invoke the service (identity + role).
  • Network ingress - where requests may come from (internet, VPC, load balancer).

The generic IAM model (policies bind members to roles, a policy is attached to a resource) is the same here - this section is a quick refresher, then the rest of the page is what is Cloud Run-specific.

How access works: IAM

Google Cloud is a collection of APIs. Anything you do - deploy a revision, publish to Pub/Sub - is an API call, whether made from the console, the gcloud CLI, Terraform, or client libraries in your app.

Google CloudYougcloud CLI$: gcloud run deployCloud Run Management APIhttps://run.googleapis.comRun programAPI call
Every Cloud Run action is an API call: gcloud run deploy on your machine calls the Cloud Run Management API at run.googleapis.com.

IAM (Identity and Access Management) sits in front of every API. It verifies the caller's identity and checks whether they have permission for the call; if the check fails, it rejects the call. This is identical whether you deploy a revision or your application publishes a message.

YouCloud RunYour applicationIAMGoogle Cloud APIsAPI callsAPI callsPerforms authorization
IAM sits in front of every Google Cloud API: it authorizes each API call - whether from you or from your Cloud Run application - before the call reaches the API.

To decide, IAM reads the IAM policy attached to the target resource.

IAMChecks authorizationIAM PolicyAttached toCloud resource (Pub/Sub topic)
To authorize an action, IAM checks the IAM policy attached to the target resource - here a Pub/Sub topic.

A policy is a list of policy bindings; each binding grants a member a role, and the role carries the permissions that allow specific actions. A member can appear in multiple bindings to hold multiple roles.

IAM PolicyContains policy bindingsPolicy bindingMemberMember IDRolePub/Sub PublisherPermissionspubsub.topics.publishA policy binding grants a role to a member.A member can have more than one role with multiple policy bindings.
An IAM policy contains policy bindings; each binding grants a member a role, and the role carries the permissions - here Pub/Sub Publisher grants pubsub.topics.publish.

For the full model - deny policies, IAM conditions, org policies, the five member types - see Members & Policies and Roles.

Invoking a service (IAM)

By default, only identities with the Owner or Editor basic roles can create, update, delete, or invoke Cloud Run services and jobs. Owners and holders of Cloud Run Admin (roles/run.admin) can also modify the IAM policy on the project or an individual service/job.

To let a specific identity invoke a service, grant it the Cloud Run Invoker role (roles/run.invoker) on that service - this also covers service-to-service calls.

To call an authenticated service (one that is not public), the request needs a Google-signed identity token in an Authorization: Bearer header:

CommandsCall an authenticated service or function
# Fetch the service's HTTPS URL
URL=$(gcloud run services describe my-service --region $REGION --format 'value(status.url)')
 
# Invoke it with your identity token
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" "$URL"

Making a service public

Applying that same policy-binding model to a Cloud Run service: grant roles/run.invoker to the allUsers member and any caller can invoke it without authenticating.

Unauthenticated service invocationAuthorizationPolicy bindingMemberallUsersRoleCloud Run InvokerPublic userIAM PolicyCloud resource(Cloud Run service)Member ofPart ofAttached togcloud run services add-iam-policy-binding my-service --member="allUsers" --role="roles/run.invoker"
Granting the Cloud Run Invoker role to allUsers on a service authorizes unauthenticated invocation - the same policy-binding model, applied to a Cloud Run service.

Grant roles/run.invoker to the allUsers member to allow unauthenticated invocations:

CommandsMake a service publicly invocable
gcloud run services add-iam-policy-binding my-service \
--member="allUsers" --role="roles/run.invoker"

The --allow-unauthenticated flag on gcloud run deploy does the same thing at deploy time. You can also make a service public from the console, a YAML config, or Terraform.

GotchaallUsers = the entire internet

allUsers on run.invoker opens the service to anyone, no credentials. To assign it you need the permission included in the project Owner and Cloud Run Admin roles. (allUsers vs allAuthenticatedUsers: Members & Policies.)

Controlling access to services and jobs

CommandsGrant / revoke invoke access
# Per-service (or per-job): add a principal to a role
gcloud run services add-iam-policy-binding my-service \
--member=serviceAccount:sa_email --role=roles/run.invoker
 
# Per-job: remove a principal from a role
gcloud run jobs remove-iam-policy-binding my-job \
--member=MEMBER_TYPE --role=role
 
# Project-wide: applies to ALL services and jobs in the project
gcloud projects add-iam-policy-binding my-project-id \
--member=MEMBER_TYPE --role=role

MEMBER_TYPE is a prefixed member like user:alice@example.com or serviceAccount:sa@proj.iam.gserviceaccount.com. Use project-level IAM to grant access across every service and job at once; use per-service/job bindings to scope tightly.

Controlling network access (ingress)

Ingress settings are set per service and are independent of IAM - combine both for a layered defense. Three settings, least to most restrictive:

AllInternalInternal and Cloud Load Balancinghttps:// *.run.app https://your.domainCloud Run serviceLeast restrictivePublic internet access allowed.VPC SCInternal HTTP(S) Load BalancerVPCCloud Run serviceMost restrictive+External HTTP(S) Load BalancerCloud Run serviceRequests are not allowed directly from the internet.
Three Cloud Run ingress settings, least to most restrictive. All lets the public internet in; Internal admits only the internal load balancer and VPC SC resources; Internal + Cloud Load Balancing adds an external load balancer while still blocking direct internet.
FactsIngress settings
  • All (default) - least restrictive. Any request, including directly from the internet, reaches the default run.app URL or a custom domain.
  • Internal - most restrictive. Only:
    • the internal HTTP(S) load balancer;
    • resources allowed by a VPC Service Controls perimeter containing the service (both run.app and custom domains are subject to VPC SC);
    • VPC networks in the same project or VPC SC perimeter;
    • Cloud Tasks, Eventarc, Pub/Sub, Workflows in the same project / perimeter.
    • Requests from any other source (including the internet) cannot reach the service.
  • Internal and Cloud Load Balancing - everything Internal allows, plus an external HTTP(S) load balancer (but not directly from the internet).
GotchaVPC Service Controls guards data exfiltration

Internal ingress leans on VPC Service Controls - a secure perimeter around the service. Both the default run.app URL and custom domains stay subject to that perimeter, so a leaked URL alone doesn't grant access.

Connecting to a VPC network

A VPC network is a virtualized physical network in Google's production network - a global resource made of regional subnets, all connected by a global WAN.

Use Serverless VPC Access to connect a Cloud Run service or job directly to a VPC network so it can reach VM instances, Memorystore instances, and other resources at their internal IP addresses. Traffic uses internal DNS and internal IPs and never crosses the internet.

Cloud Run service/jobServerless VPC Access connectorVPC
Serverless VPC Access routes traffic from a Cloud Run service or job through a connector into your VPC network, so it reaches internal-IP resources without touching the internet.

A Serverless VPC Access connector is the resource that handles traffic between the service/job and the VPC network.

NumbersServerless VPC Access connector facts
  • The connector's region must match the service/job deployment region.
  • Configure it with an unused /28 subnet or non-overlapping /28 CIDR range, used exclusively by the connector.
  • Create it via console, gcloud CLI, or Terraform - then attach the service/job to it.
  • For an internal Cloud Run service, route all egress through the VPC connector.
  • Restrict what the connector can reach with firewall rules.
CommandsConfigure a service to use a connector
# 1. Enable the Serverless VPC Access API, then create a connector
# attached to a VPC network + region.
# 2. Point the service at it:
gcloud run deploy my-service --image my-image \
--vpc-connector my-connector

Recap

DECISIONHow do I control access to a Cloud Run service?
Let anyone on the internet invoke itrun.invoker to allUsers / --allow-unauthenticated
Let one app/user invoke itrun.invoker to that member
Block the public internetIngress = Internal (or Internal + LB)
Reach a VM / Memorystore by internal IPServerless VPC Access connector
Pick this when: IAM decides WHO can invoke; ingress decides WHERE from; VPC Access decides what the service can reach inward