Authenticate an MCP Server with Google Cloud IAM
The agent gets a short-lived identity token from Google and the MCP server verifies it against Google's public keys, so there is no key to store or rotate.
- Method
- Google Cloud IAM
- Platform
- Google Cloud
- MCP Specification
- 2026-07-28
How it works
The agent requests a Google OIDC ID token whose audience is the MCP server's URL, then sends it as Authorization: Bearer <id-token>. The server verifies the signature against Google's JWKS, checks the aud and iss claims, and reads the calling service account's email from the token. Tokens are minted from the runtime service account's ambient credentials, so no secret appears in configuration.
- Best for
- Agents that hold Google credentials, calling a server that can verify a Google token
- MCP spec
- Platform identity rather than MCP authorization; the spec does not cover it
- Works with
- Your own workloads only; no MCP client can mint these tokens
- Effort
- A day, mostly IAM bindings
The exchange
Each step in the exchange, in order.
- Your agent runtime service account
- Google metadata server
- MCP server verifies via JWKS
-
Minted from the runtime service account's ambient credentials, so nothing appears in configuration and there is no secret to rotate.
Your agent to Google
GET …/identity?audience=… Metadata-Flavor: Google -
Google to Your agent
id_token aud = https://mcp.example.com/mcp -
Your agent to MCP server
POST /mcp Authorization: Bearer <id-token> -
Verification is offline against cached JWKS. Google is never called by the server, and the audience check is what stops a token minted for another service from being replayed here.
Inside MCP server
Verify the signature against Google's JWKS -
Inside MCP server
Check aud and iss, then read the caller email = agent@project.iam.gserviceaccount.com -
MCP server to Your agent
200 OK tool result
Connect your agent
Pick your language and SDK.
When to use something else
Use this when
- The agent runs with Google credentials — usually on Google Cloud — so it can mint tokens with no stored secret. The server only has to verify them.
- You want no stored secret: tokens are short-lived and minted from ambient credentials.
- Tool calls need to be attributed to a specific workload rather than to a key.
Use something else when
- A third party has to call the server, since only a caller holding Google credentials can mint these tokens.
- An interactive MCP client needs to connect. Claude, ChatGPT and Cursor cannot produce a Google ID token and need OAuth or a signing proxy.
- The call is made on behalf of a named person and the API behind the server enforces per-user permissions.
This is platform identity rather than MCP authorization, so the specification has nothing to say about it. The trade-off is reach: it is the strongest option for your own workloads and unavailable to everything else, which is why servers that need both usually place a gateway in front to translate.
What lands on you next
Cloud IAM is strong between your own services and unusable for anything outside them. The questions that follow are all about what happens when something outside them needs in.
-
A partner's agent needs two of these tools. They have no Google account.
-
mcp-oauth-inboundThe inbound method is a policy, not server code, so the route can authenticate against the identity provider you already run instead of Google IAM. Exactly one such policy per project.
-
This service account's token works. Can it be replayed at our other MCP route?
- RFC 8707 resource indicators
No. A gateway-issued token is bound to one route's canonical resource URI, so a token minted for one MCP route is rejected at another.
-
Which service account called which tool, and how often?
-
capability_invocationEach tool call resolves to a caller and a capability with an outcome and a latency, rather than to a shared egress IP in an access log.
-
Can I forward the caller's ID token to the API behind the server?
-
mcp-token-exchange-inboundThe spec forbids passthrough with a MUST NOT. Inbound auth headers are stripped and an independent upstream credential is minted per user or per gateway.
All of these attach to one MCP route's policies.inbound — the same policy engine on the way in and on the way out.
Common questions
Why an ID token rather than an access token?
An ID token carries an audience claim that can be bound to one specific service, which is what prevents a token minted for another service from working. Access tokens address Google APIs, not your own endpoints.
Should the audience be the server URL or the /mcp path?
The service's base URL. Mint and verify the same value. Including the /mcp path in the audience is a common cause of audience-mismatch failures.
Does the token need refreshing manually?
Not if the ID token client is cached rather than the token string. The Google auth library re-mints as the roughly one-hour token approaches expiry. Caching the bearer string is what causes long-lived instances to start failing after an hour.
Can Claude or ChatGPT connect to a server protected this way?
No. No MCP client can mint a Google ID token, which is why Google's own guidance is to choose a different method when the client cannot supply the credential. Interactive clients need the spec OAuth flow or a local proxy that signs on their behalf.
Is Cloud Run IAM sufficient by itself?
It closes the ingress, which is most of the value, but it tells the application nothing. Verifying the token in the handler is what supplies the caller identity for authorization decisions and audit logs.
Does this pattern work on Lambda or Kubernetes?
The shape does, with different mechanics: AWS uses SigV4 request signing, and Kubernetes can validate projected service-account tokens against the cluster's OIDC issuer. In all three cases no MCP client can produce the credential, so the pattern stays internal.
One policy engine for APIs, AI, and MCP
Put your MCP servers behind a gateway that speaks every identity provider, filters tools per role, and logs every call.