DEV Community

Cover image for How to Use Your Google Cloud Credits for Gemini Again, via Vertex AI and ADC
Bravian
Bravian

Posted on

How to Use Your Google Cloud Credits for Gemini Again, via Vertex AI and ADC

I've always pulled my Gemini API keys from AI Studio; like, I'm sure, most of you did. A few days ago I got a call from a client telling me the AI features in my app had stopped working. I logged in and confirmed it: something was wrong with my billing. So I checked my Google Cloud account to see whether the credits had run out, but there was still a big chunk left before I'd have to start paying. I created a fresh API key and tried to link it to that billing account, and it failed.

After some digging, the answer was blunt: that workflow is gone. You can no longer spend Google Cloud credits in AI Studio.

Google has split the billing worlds apart. The Gemini Developer API (the one you get keys for in AI Studio) now runs on its own billing track. The headline change that bit a lot of people: if you created your account after March 2, 2026, the $300 free "Welcome" credits can no longer be spent on Gemini API / AI Studio usage at all, and existing accounts like mine found the old credit link quietly severed too. They explicitly say those credits can still be used on other Google Cloud products in the Google Cloud console, and that's the crack in the wall we're going to walk through.

And "other Google Cloud products" includes Vertex AI, Google's managed platform for running the very same Gemini models. So the move is simple: stop using AI Studio keys and start calling Gemini through Vertex AI. Same models, different door, and that door still takes your Cloud credits.

There's one catch, and it's the thing this article is really about: Vertex AI doesn't want you using API keys. Instead it uses Application Default Credentials (ADC). The concept didn't quite make sense to me when I was doing this, so I decided to make this tutorial for the next person who might need it. Let me show you the whole thing: local dev, a real server, and Vercel.

Quick naming note: Vertex AI is in the middle of a rebrand toward "Gemini Enterprise / Agent Platform." You'll see both names in Google's own docs right now. It's the same platform, the Cloud-native home for Gemini.


What ADC actually is

Application Default Credentials is just a convention. Instead of pasting a secret key into your code, the Google client libraries go looking for credentials in a fixed list of places, in order:

  1. The GOOGLE_APPLICATION_CREDENTIALS environment variable (a path to a service-account JSON key).
  2. Credentials left behind by gcloud auth application-default login (your local user login).
  3. The credentials attached to the environment itself, e.g. the metadata server on Compute Engine, Cloud Run, GKE.

Your code never changes. The environment supplies the identity. That's the whole idea: the same app authenticates on your laptop, on a server, and in Cloud Run without a single line of credential code.


Step 0: One-time Google Cloud setup

You need a project with the Vertex AI API turned on and a billing account (with your credits) attached. If you can, keep the project outside an organization; projects under an org pull in extra IAM and policy setup that's just an unnecessary headache for this.

# Pick or create a project
gcloud projects create my-gemini-project        # or use an existing one
gcloud config set project my-gemini-project

# Make sure billing (with your credits) is linked, then enable the API
gcloud services enable aiplatform.googleapis.com
Enter fullscreen mode Exit fullscreen mode

Confirm in the console that your credits are applied to this project's billing account. This is the part that makes the credits actually pay for Vertex usage.


Step 1: Local development, just log in

On your own machine, you don't need a key file at all. You log in once and ADC handles the rest.

# Install the gcloud CLI first if you haven't:
# https://cloud.google.com/sdk/docs/install

gcloud auth application-default login
Enter fullscreen mode Exit fullscreen mode

A browser window opens, you pick your Google account, and gcloud writes credentials to a well-known location on disk (~/.config/gcloud/application_default_credentials.json). From now on, any Google client library running as you finds them automatically.

One gotcha: if you previously set GOOGLE_API_KEY or GEMINI_API_KEY in your shell, unset them: the SDK will prefer a key over ADC and you'll wonder why nothing changed.

unset GOOGLE_API_KEY
unset GEMINI_API_KEY
Enter fullscreen mode Exit fullscreen mode

Calling Gemini through Vertex with the new SDK

Google's current, unified library is google-genai. The trick is to flip it into Vertex mode. You do that either with constructor arguments or three environment variables.

npm install @google/genai
Enter fullscreen mode Exit fullscreen mode
export GOOGLE_GENAI_USE_VERTEXAI=true
export GOOGLE_CLOUD_PROJECT="my-gemini-project"
export GOOGLE_CLOUD_LOCATION="global"
Enter fullscreen mode Exit fullscreen mode
import { GoogleGenAI } from "@google/genai";

// vertexai: true tells the SDK to use the Vertex backend (ADC),
// not the AI Studio key backend.
const ai = new GoogleGenAI({
  vertexai: true,
  project: process.env.GOOGLE_CLOUD_PROJECT,
  location: process.env.GOOGLE_CLOUD_LOCATION ?? "global",
});

const response = await ai.models.generateContent({
  model: "gemini-3.1-flash-lite",
  contents: "Why is the sky blue?",
});

console.log(response.text);
Enter fullscreen mode Exit fullscreen mode

Run it. If it returns text, your credits (not a credit card) just paid for that call. Notice what's not there: no API key. The client picks up your gcloud login through ADC.

Why global? Not every model is available in every region, and trying to call one that isn't deployed in your chosen region is a classic source of 404s. The global endpoint routes your request to wherever the model actually lives, so it's the safest default while you're getting started. Once you have a reason to pin a region (data residency, latency), switch GOOGLE_CLOUD_LOCATION to something like us-central1 and confirm your model is offered there.


Step 2: A real server, the sa-key.json approach

Your laptop login won't follow you onto a production box. A server isn't "you," and you don't want to run an interactive browser login on it. The standard answer is a service account: a non-human identity that owns a downloadable JSON key.

Create the service account and key

# 1. Create the service account
gcloud iam service-accounts create gemini-runner \
  --display-name="Gemini Vertex runner"

# 2. Grant it permission to call Vertex AI
gcloud projects add-iam-policy-binding my-gemini-project \
  --member="serviceAccount:gemini-runner@my-gemini-project.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"

# 3. Create and download the key
gcloud iam service-accounts keys create sa-key.json \
  --iam-account="gemini-runner@my-gemini-project.iam.gserviceaccount.com"
Enter fullscreen mode Exit fullscreen mode

The role you want is roles/aiplatform.user ("Vertex AI User"). It's enough to call models and not much else. Don't hand it Owner.

Use the key on the server

Copy sa-key.json onto the server (over SCP, a secrets manager, your deploy pipeline, not into your git repo), lock down its permissions, and point ADC at it:

chmod 600 sa-key.json
export GOOGLE_APPLICATION_CREDENTIALS="/etc/secrets/sa-key.json"
export GOOGLE_GENAI_USE_VERTEXAI=true
export GOOGLE_CLOUD_PROJECT="my-gemini-project"
export GOOGLE_CLOUD_LOCATION="global"
Enter fullscreen mode Exit fullscreen mode

Your application code does not change. The exact same new GoogleGenAI({ vertexai: true, ... }) from Step 1 now authenticates as the service account, because ADC found GOOGLE_APPLICATION_CREDENTIALS first in its lookup order.

That's the elegance of ADC: locally it's your login, on the server it's the key file, and the code is identical.

If your server is itself a Google Cloud resource (Compute Engine, Cloud Run, GKE), skip the key file entirely. Attach the service account to the resource and ADC reads credentials straight from the metadata server. No key to leak, no key to rotate. Prefer this whenever you can.

Treat that key like a password

A service-account JSON key is a long-lived secret. If it leaks, someone can burn your credits (or worse).

  • Never commit it. Add sa-key.json to .gitignore immediately.
  • chmod 600 it, store it via your platform's secret manager.
  • Rotate it periodically and delete keys you no longer use:
  gcloud iam service-accounts keys list \
    --iam-account="gemini-runner@my-gemini-project.iam.gserviceaccount.com"
Enter fullscreen mode Exit fullscreen mode

Step 3: Deploying on Vercel (and other serverless hosts)

Vercel is where people get stuck, because there's no shell to run gcloud auth login and no persistent filesystem to drop a sa-key.json onto. Serverless functions are ephemeral.

The pattern that works: don't ship a file; ship the file's contents as an environment variable, then either hand them to the SDK directly or write them to the temp directory at startup.

Option A: write the key to /tmp at boot (works on the Node.js runtime)

Put the entire JSON of your sa-key.json into a Vercel environment variable called, say, GCP_SA_KEY. Then, before you create the client:

import { writeFileSync } from "node:fs";
import { GoogleGenAI } from "@google/genai";

// Reconstruct the key file in the only writable place: /tmp
const keyPath = "/tmp/sa-key.json";
writeFileSync(keyPath, process.env.GCP_SA_KEY!);
process.env.GOOGLE_APPLICATION_CREDENTIALS = keyPath;

const ai = new GoogleGenAI({
  vertexai: true,
  project: process.env.GOOGLE_CLOUD_PROJECT,
  location: process.env.GOOGLE_CLOUD_LOCATION ?? "global",
});
Enter fullscreen mode Exit fullscreen mode

/tmp is the one writable path in most serverless runtimes, and ADC happily reads the key from there.

Option B: pass credentials in memory (better for Edge / no filesystem)

Edge runtimes are stripped-down: no fs, no Node built-ins. There, pass the parsed credentials object straight into the auth layer instead of relying on a file. If you use the Vercel AI SDK's Google Vertex provider, it's built for exactly this: you feed it the client_email, private_key, and project from your service-account JSON via env vars, and it never touches disk.

# Vercel env vars (from the fields inside your sa-key.json)
GOOGLE_VERTEX_PROJECT=my-gemini-project
GOOGLE_VERTEX_LOCATION=global
GOOGLE_CLIENT_EMAIL=gemini-runner@my-gemini-project.iam.gserviceaccount.com
GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
Enter fullscreen mode Exit fullscreen mode
import { createVertex } from "@ai-sdk/google-vertex/edge";
import { generateText } from "ai";

const vertex = createVertex({
  project: process.env.GOOGLE_VERTEX_PROJECT,
  location: process.env.GOOGLE_VERTEX_LOCATION,
  googleCredentials: {
    clientEmail: process.env.GOOGLE_CLIENT_EMAIL!,
    privateKey: process.env.GOOGLE_PRIVATE_KEY!,
  },
});

const { text } = await generateText({
  model: vertex("gemini-3.1-flash-lite"),
  prompt: "Summarize ADC in one sentence.",
});

console.log(text);
Enter fullscreen mode Exit fullscreen mode

Watch the GOOGLE_PRIVATE_KEY newlines. Pasting the multi-line PEM into a dashboard often mangles them. The usual fix is to store it with literal \n and call .replace(/\\n/g, "\n") before use.

The same two options apply to Netlify, AWS Lambda, Cloud Functions, and friends. The principle never changes: get the credentials into the environment, let ADC find them.


Bonus: it's not just Gemini

Once you're on Vertex AI, you're not limited to Gemini. The same project, the same credits, and the exact same ADC setup also get you Anthropic's Claude models, Llama, Mistral, and a pile of other open-source models through Vertex's Model Garden, billed against the same credit balance, with no change to your authentication code. You simply swap the model ID and how you call it.


Hopefully this provides some clarity if the Google docs aren't clear enough, as they weren't for me.

Top comments (1)

Collapse
 
hezronokwach profile image
Hezron Okwach

Nice work. I'll also try to implement this