Securely Call Cloud Run Service From Anywhere
Enabling authentication for your Cloud Run application is easy ‒ a single mouse click (or parameter in your CI/CD) without writing any code. Calling this application from another is less straightforward. It may be easy when both a caller and called applications are hosted under the same identity in Google Cloud. In the rest of cases, it requires acquiring an identity token.
A problem begins with documentation. Sometimes it isn’t clear whether the described token is an identity token or access token. While the first is good for invoking endpoints of user’s applications on Google Cloud, the second is good only for calling Google APIs.
Another challenge is with examples that demonstrate getting an identity token from a metadata server available in Google Cloud VMs and other managed environments such as GKE or Cloud Run. However this method would not work anywhere else.
The following method lets you call a private Cloud Run service regardless whether the calling code runs in Google Cloud or elsewhere. This code example is in Python. Please leave a comment if you need a code snippet in another programming language.
AUDIENCE = 'https://your-cloud-run-service-url.run.app'
creds, _ = google.auth.default()
auth_req = Request()
# Handle impersonated credentials
if isinstance(creds, impersonated_credentials.Credentials):
creds = impersonated_credentials.IDTokenCredentials(
creds,
target_audience=AUDIENCE,
include_email=True
)
creds.refresh(auth_req)
return creds.token
# Handle user credentials
if hasattr(creds, "id_token") and creds.id_token:
return creds.id_token
creds.refresh(auth_req)
if hasattr(creds, "id_token") and creds.id_token:
return creds.id_token
# Fetch ID token for service account credentials or retrieve it from metadata server
return id_token.fetch_id_token(auth_req, audience)
The google.auth.default() call intelligently searches for application default credentials in the local environment.
Then the code uses found credentials to validate and, if needed, to refresh the identity token.
If the refreshing fails to get a valid identity token, the code fetches a new identity token from the metadata server which stores the credentials of the attached service account.
The last part works only when the application is deployed on Google Cloud.
The AUDIENCE constant is a Cloud Run service URL and is used to create an ID token that serves to prove identity to Cloud Run service.
The URL used for the audience should be original URL that Cloud Run creates for the service and not one used for load balancing or with custom domains.
This powerful chain of discovery works with user credentials and service account credentials. It also works with impersonated credentials that is a recommended way to make authenticated calls to Cloud Run from a development environment. The code returns the acquired identity token which you can use as a bearer token in the Authentication header of HTTP requests to a Cloud Run service. For the full end-to-end demonstration go to devrel-demos Github repository.
To try this code on your local machine, you only need to run one command:
gcloud auth application-default login
This securely stores your user credentials in a well-known location where the google.auth.default() call can find them.
This post is mirrored to Medium.