DEV Community

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

Posted on

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

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();
}
Enter fullscreen mode Exit fullscreen mode

get id token for local env:

function getLocalIdToken(): string {
  return exec("gcloud auth print-identity-token");
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

Python

set up libraries and functions:

import google.auth.transport.requests
import google.oauth2.id_token
from google import auth
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (0)