
I was working on a demo the other day that involved a Google ADK agent (Agent Development Kit) running on Cloud Run that could read and write to a Google Sheet. And I had to test this code locally first before I deployed to Cloud Run. I thought this local testing scenario would make for a good blog post.
Below I’ll explain how to test your code locally using Application Default Credentials (ADC), so you’ll have a close match between running your application code locally and running your code as a Cloud Run service.
If you read nothing else
- When you go through Google APIs (e.g. to access a Google Sheet), you need to use an Access Token with the appropriate scopes (e.g. https://www.googleapis.com/auth/spreadsheets)
- Google Cloud client libraries handle authentication automatically because they support Application Default Credentials (ADC).
- When testing locally, you need to run gcloud auth application-default login or with –impersonate-service-account
Terminology Note
You may be more familiar with the terms “assuming an identity” or “assuming the same permissions.” In Google Cloud, impersonating a service account lets an authenticated principal access whatever the service account can access. Only authenticated principals with the appropriate permissions can impersonate service accounts. You can read more here https://docs.cloud.google.com/iam/docs/service-account-overview#impersonation
Overview
Authentication for the client libraries happens automatically when deployed on Google Cloud. You can learn more in my Cloud Next ’26 presentation with my Cloud Run teammate Wietse at timestamp 23:10
Google Cloud client libraries handle authentication automatically because they support Application Default Credentials (ADC). ADC automatically finds credentials based on the application environment and uses those credentials to authenticate to Google Cloud APIs. When you deploy to Cloud Run, Google Cloud provides Service Account credentials via the metadata server.
Okay, that’s great for prod, but what about running locally?
You can use gcloud to set ADC locally via gcloud auth application-default login Running this command as-is acquires your user credentials to use for ADC.
In theory you could stop here. Your app will use your user credentials to interact with a Google Sheet (or Google APIs). Just make sure you’ve given yourself Editor access to the Google Sheet first! (Example below).
But we can do even better!
We want to simulate being in production as much as possible. Using –impersonate-service-account flag with your service account allows you to execute the code locally with the same permissions as the deployed Cloud Run service. Now you can properly test the service account permissions during local execution.
End-to-end example
Let’s say you have a service account called my_service_account@<your_project_id>.iam.gserviceaccount.com that you’ll use as your Cloud Run service identity.
First, you’ll need to give your service account access to your Google Sheet, just like you’d give access to a teammate.
Since you’re going to impersonate the service account, you need to make sure your identity has the appropriate iam.serviceAccountTokenCreator role to do so.
# your current identity as shown in `gcloud auth list`
YOUR_IDENTITY=$(gcloud config get-value account)
gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_EMAIL \
--member="user:$YOUR_IDENTITY" \
--role="roles/iam.serviceAccountTokenCreator" \
--project=$PROJECT_ID
And you need to enable the Google Sheets API. Yes even if you can create a Google Sheet, you still need to enable the API in your Google Cloud project.
gcloud auth application-default login \
--impersonate-service-account=<YOUR_SERVICE_ACCOUNT_EMAIL>
Now you can (re)start your local dev server. Now the code can run and use Google Cloud services as if deployed on Cloud Run directly, without any code changes.
Code Example
Here’s an example “hello world” where your service account can write Hello World to a Google Sheet.
import os
from fastapi import FastAPI, HTTPException
from google.auth import default
from googleapiclient.discovery import build
app = FastAPI()
# 1. Load credentials using Application Default Credentials (ADC).
# This automatically handles finding service accounts or user accounts in any environment,
# requesting the specific permission scope needed to write to Google Sheets.
creds, _ = default(scopes=['https://www.googleapis.com/auth/spreadsheets'])
# 2. Build the Google Sheets v4 resource client once at application startup.
# The build() function fetches a dynamic API description schema and compiles helper methods on the fly,
# allowing us to directly access the spreadsheets() service.
service = build('sheets', 'v4', credentials=creds).spreadsheets()
@app.post("/write")
def write_endpoint():
spreadsheet_id = os.environ.get("SPREADSHEET_ID")
if not spreadsheet_id:
raise HTTPException(status_code=400, detail="SPREADSHEET_ID env var not set")
try:
# Write "hello world" directly to Sheet1!A1
result = service.values().update(
spreadsheetId=spreadsheet_id,
range="Sheet1!A1",
valueInputOption="USER_ENTERED",
body={"values": [["hello world"]]}
).execute()
return {"status": "success", "updated_cells": result.get("updatedCells")}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
Now if you run this locally
SPREADSHEET_ID=<YOUR_SPREADSHEET_ID>
SPREADSHEET_ID=$SPREADSHEET_ID uvicorn main:app --host 0.0.0.0 --port 8080
and you curl the endpoint
curl -X POST http://localhost:8080/write
you’ll notice Hello World in your spreadsheet in the first cell.
Deploying
Now let’s deploy to Cloud Run with the service account as the identity for the service.
gcloud run deploy my-hello-world-sheets \
--source . \
--region=<YOUR_REGION> \
--set-env-vars SPREADSHEET_ID=$SPREADSHEET_ID \
--service-account <YOUR_SERVICE_ACCOUNT_EMAIL> \
--project=<YOUR_PROJECT_ID>
Before you curl the endpoint, make sure you delete the Hello World content in the cell first from your local test run!
Locally test your Cloud Run service code that writes to Google Sheets was originally published in Google Cloud – Community on Medium, where people are continuing the conversation by highlighting and responding to this story.
Source Credit: https://medium.com/google-cloud/locally-test-your-cloud-run-service-that-writes-to-google-sheets-0635afc6daf9?source=rss—-e52cf94d98af—4
