Cloud Run’s default behavior is to require authentication for all requests. Allowing public, unauthenticated access is a simple toggle, but it fundamentally changes how your service is exposed to the world, making it available to anyone on the internet without needing API keys or IAM credentials.
Let’s see this in action. Imagine a simple "hello world" Cloud Run service. By default, if you try to hit its URL without an Authorization header, you’ll get a 401 Unauthorized error.
curl https://my-hello-world-service-abcd12345-uc.a.run.app
# Output:
# <html><body><h1>401 Unauthorized</h1><p>You are not authorized to call this API.</p></body></html>
To make it public, we need to change the IAM policy for the service. Specifically, we need to grant the roles/run.invoker role to the special allUsers principal. This tells Cloud Run that any user, regardless of their identity, is allowed to invoke the service.
You can do this via the Google Cloud Console:
- Navigate to your Cloud Run service.
- Click the "Permissions" tab.
- Click "Grant Access".
- In the "New principals" field, enter
allUsers. - In the "Select a role" dropdown, choose "Cloud Run Invoker" (
roles/run.invoker). - Click "Save".
Alternatively, you can use the gcloud command-line tool:
gcloud run services add-iam-policy-binding my-hello-world-service \
--member='allUsers' \
--role='roles/run.invoker' \
--region=us-central1 \
--platform=managed
Replace my-hello-world-service with your service’s name and us-central1 with its region.
After applying this change, the same curl command will now succeed:
curl https://my-hello-world-service-abcd12345-uc.a.run.app
# Output:
# Hello World!
This change allows anyone on the internet to send requests to your Cloud Run service. This is perfect for public-facing websites, APIs that are meant to be universally accessible, or simple demo applications. It removes the overhead of authentication for end-users or client applications.
The core of this functionality lies in how Cloud Run integrates with IAM. When a request arrives, Cloud Run checks the IAM policy attached to the service. If the policy allows the allUsers principal to invoke the service, the request is passed through to your container. If not, it’s rejected with a 401. It’s a straightforward, but powerful, access control mechanism.
It’s crucial to understand that allUsers is a special identifier representing unauthenticated access. It doesn’t mean "all authenticated Google users"; it means literally anyone. If your service handles sensitive data or performs actions that should be restricted, you must not grant allUsers the invoker role. Instead, you’d use authenticated invocations, perhaps requiring authenticated users via IAM or using identity-aware proxies.
When you grant the roles/run.invoker role to allUsers, you are effectively making your service a public endpoint. This means that any traffic hitting your service’s URL, from any device, anywhere in the world, will be allowed to reach your container. This has implications for security, cost (as all requests consume resources), and potential abuse. You should always consider if your application truly needs to be public before making this change.
The allUsers principal is a global identifier that represents all possible callers, whether they are authenticated with a Google account or not. When you see allUsers in an IAM policy for a Cloud Run service, it’s a definitive signal that the service is intended to be publicly accessible without any form of authentication.
This allows for incredibly simple integration with front-end applications served from other services, or even static websites hosted elsewhere, that just need to call a backend API. The simplicity comes at the cost of requiring you to implement any necessary authorization logic within your application code if certain actions or data are still meant to be restricted.
Understanding the implications of allUsers is key. It’s not about allowing any Google user to access your service; it’s about allowing no user to be required to authenticate. This distinction is vital for security.
This makes it exceptionally easy to build public APIs. You don’t have to worry about issuing API keys or managing OAuth flows for your clients if the data or functionality is inherently public.
The next step after making a service public is often to secure it at the application level, or to integrate it with other services that might require its output.