Sample code on Service-to-Service Authentication in Google Cloud Run for Production and Local environments

RMAG news

When using Google Cloud Run, securing communications between services is crucial. If your system architecture utilizes multiple services, it’s likely that these services will need to communicate with each other either synchronously or asynchronously. Some of these services may be private and require authentication credentials for access.

It’s often not easy to find sample code for setting it up for production and local environments and working with both scenarios with a good developer experience. The goal of this blog post is to provide sample code for the aforementioned scenarios for Python and Node/Javascript.

Javascript

set up libraries and functions:

import { execSync } from “child_process”;
import { GoogleAuth } from “google-auth-library”;

function exec(command: string): string {
return execSync(command).toString().trim();
}

get id token for local env:

function getLocalIdToken(): string {
return exec(“gcloud auth print-identity-token”);
}

get id token for production:

async function getProductionIdToken(url: string) {
const auth = new GoogleAuth();
const targetAudience = `https://${url}`;
const client = await auth.getIdTokenClient(targetAudience);
return await client.idTokenProvider.fetchIdToken(targetAudience);
}

suggested approach to use an env variable to switch it:

const idToken = process.env.NODE_ENV === “production” ?
await getProductionIdToken(url)) : getLocalIdToken();
// add your additional logic here that uses the idToken in the Rest or GRPC call.

Python

set up libraries and functions:

import google.auth.transport.requests
import google.oauth2.id_token
from google import auth

get id token for local env:

def get_local_id_token() -> str:
creds, _ = auth.default(
scopes=[“https://www.googleapis.com/auth/cloud-platform”],
)
request = google.auth.transport.requests.Request()
creds.refresh(request)
return creds.id_token

get id token for production:

def get_production_id_token(url: str) -> str:
auth_request = google.auth.transport.requests.Request()
audience = f”https://{url}”
return google.oauth2.id_token.fetch_id_token(auth_request, audience=audience)

suggested approach to use an env variable to switch it:

def get_id_token(url: str, env: str) -> str:
if env == “production”:
return get_production_id_token(url)

return get_local_id_token()

// add your additional logic here that uses the idToken in the Rest or GRPC call.

At the time of writing this blog post, it was not yet possible to use the exact same code for both strategies. Therefore, I recommend switching the presented logic using an environment or configuration variable. I hope this helps!

Leave a Reply

Your email address will not be published. Required fields are marked *