Connect to an MCP Server Behind Google Identity-Aware Proxy
Let your agents call an MCP server that sits behind Google Identity-Aware Proxy (IAP) or an authenticated Cloud Run service. AI Gateway presents IAP or Cloud Run with a Google-signed ID token for a service account that you control. You don’t create a service account key or expose the server on a separate public endpoint.
After reading this page, you will be able to:
-
Set up Google Cloud to let AI Gateway get ID tokens as your service account
-
Grant your service account access through IAP or Cloud Run
-
Configure a self-managed or JavaScript MCP server to send a Google ID token to IAP or Cloud Run
How AI Gateway authenticates to IAP or Cloud Run
IAP and an authenticated Cloud Run service act as a gate in front of the server. The gate checks every request and admits it only if it carries a Google-signed ID token for an identity that the gate allows. To get that token, AI Gateway uses its own cloud identity to impersonate a Google service account in your project, and Google Cloud Identity and Access Management (IAM) issues the token. The service account needs no key.
The flow works like this:
-
AI Gateway’s identity: In an environment on Amazon Web Services (AWS), AI Gateway uses its own AWS IAM role. It exchanges that role’s credentials with Google’s Security Token Service through a Workload Identity Federation provider that you create. In an environment on Google Cloud, AI Gateway already has a Google service account and uses it directly.
-
The token: AI Gateway asks Google for an ID token as your service account, for the audience that you set. It reuses the token and gets a new one shortly before the old one expires.
-
The headers: AI Gateway sends the token as
Bearer <token>inProxy-Authorization, which IAP reads, or inX-Serverless-Authorization, which Cloud Run reads. The server’s own authentication, such as a static key or user-delegated OAuth, stays in its own header (Authorizationunless you set another one), and the server still checks that credential. -
Safeguards: AI Gateway never forwards a client’s
Proxy-Authorizationheader to a self-managed MCP server, so a client can’t choose the credential that the gate sees. AI Gateway also keeps the token on the server’s origin. It drops the token’s header from any redirect that leaves that origin.
You can use the Google Identity-Aware Proxy setting on two kinds of servers:
-
A self-managed MCP server that you run behind IAP or Cloud Run
-
A JavaScript MCP server whose code calls a backend behind IAP or Cloud Run
For a JavaScript MCP server, the gate protects the backend, not the JavaScript server, which runs inside AI Gateway.
Prerequisites
-
An MCP server, or the backend that your JavaScript code calls, behind IAP or a Cloud Run service that requires authentication. AI Gateway must reach it over
https://. -
The token’s audience:
-
For IAP: an OAuth client ID that IAP accepts for programmatic access, ending in
.apps.googleusercontent.com. If IAP uses the Google-managed OAuth client, use your own OAuth client ID and add it to IAP’s programmatic access allowlist, as described in Allow your OAuth client for programmatic access. -
For Cloud Run: the service URL, or a custom audience configured on the service.
-
-
The
rpk aiCLI, signed in to your environment. You need thedataplane_adp_mcpserver_createpermission, anddataplane_adp_mcpserver_updateto change an existing server. See Use the Agentic Data Plane CLI and Roles and Permissions Reference. -
The Google Cloud CLI (
gcloud), signed in with an account that can administer the project that owns IAP or the Cloud Run service. The account needs permission to create service accounts and to edit the IAM policies on the service account and on the IAP resource or Cloud Run service. For an environment on AWS, it also needs permission to enable APIs and to create workload identity pools and providers.
Create a service account for AI Gateway to use
Create a Google service account for AI Gateway to impersonate. The service account needs no roles and no key.
This configuration refers to a third-party product. Specific UI elements may not be up to date. For current syntax, see the Google Cloud documentation for gcloud iam service-accounts create.
|
gcloud iam service-accounts create iap-gate --project=<project-id>
Replace <project-id> with your Google Cloud project ID. The service account’s email is iap-gate@<project-id>.iam.gserviceaccount.com.
Get AI Gateway’s identity
Ask AI Gateway which identity it uses to get tokens, and what your project must trust. Name the MCP server that the gate protects. The server doesn’t have to exist yet, so use the name you plan to give it.
rpk ai mcp-server google-identity internal-app
Replace internal-app with your server’s name. The command prints the identity and the gcloud commands to run, with your environment’s values filled in. In an environment on AWS, the output looks like this:
This gateway mints Google ID tokens for internal-app as the AWS role aigw-d0example1cluster234 in account 123456789012, in that server's own session mcp-internal-app.
Account: 123456789012
Role: aigw-d0example1cluster234
Role ARN: arn:aws:iam::123456789012:role/aigw-d0example1cluster234
internal-app, as seen by Google (assertion.arn):
arn:aws:sts::123456789012:assumed-role/aigw-d0example1cluster234/mcp-internal-app
To trust it, in the Google Cloud project that owns your service account:
gcloud iam workload-identity-pools create redpanda --location=global --project=<project>
gcloud iam workload-identity-pools providers create-aws aigw \
--workload-identity-pool=redpanda --location=global --project=<project> \
--account-id=123456789012 \
--attribute-mapping="google.subject=assertion.arn,attribute.aws_role=assertion.arn.extract('assumed-role/{role}/')" \
--attribute-condition="attribute.aws_role == 'aigw-d0example1cluster234'"
gcloud iam service-accounts add-iam-policy-binding <service account> \
--project=<project> --role=roles/iam.workloadIdentityUser \
--member="principal://iam.googleapis.com/projects/<project number>/locations/global/workloadIdentityPools/redpanda/subject/arn:aws:sts::123456789012:assumed-role/aigw-d0example1cluster234/mcp-internal-app"
The binding trusts internal-app alone: another MCP server on this gateway that names
the same account mints in its own session, and Google refuses it. The
provider's condition admits this gateway's role and no other.
Then set the MCP server's google_identity_aware_proxy.workload_identity_provider to
//iam.googleapis.com/projects/<project number>/locations/global/workloadIdentityPools/redpanda/providers/aigw
and put the service account on the gate's allowlist: IAP's allowed members,
or roles/run.invoker on the Cloud Run service.
In an environment on Google Cloud, the output names AI Gateway’s Google service account and prints one gcloud iam service-accounts add-iam-policy-binding command.
For machine-readable output, add -o json or -o yaml.
Let AI Gateway impersonate the service account
Run the commands that rpk ai mcp-server google-identity printed in the project that owns the service account. In an environment on AWS, first enable the APIs listed in If your environment runs on AWS. In the commands, replace these placeholders:
-
<project>: Your project ID, the same value as<project-id>in this page’s other commands. -
<project number>: Your project number, whichgcloud projects describe <project-id> --format="value(projectNumber)"prints. The member identifier needs the project number, not the project ID. -
<service account>: The service account’s email.
For background, see the Google Cloud documentation on Workload Identity Federation with other clouds.
If your environment runs on AWS
If the APIs that Workload Identity Federation uses aren’t already enabled, enable them:
gcloud services enable iam.googleapis.com cloudresourcemanager.googleapis.com \
iamcredentials.googleapis.com sts.googleapis.com --project=<project-id>
The printed commands then create a workload identity pool and an AWS provider, and bind the service account to one MCP server:
-
The provider trusts your environment’s AWS account. Its attribute condition admits AI Gateway’s role and no other role in that account.
-
The binding grants
roles/iam.workloadIdentityUseron the service account to the session that AI Gateway uses for this one MCP server. If another MCP server in the same environment names the same service account, Google refuses that server’s token requests.
To let another MCP server use the same service account, run rpk ai mcp-server google-identity with that server’s name, and then run its binding command. You create the pool and the provider only for the first server.
If the output instead says that the binding trusts the whole gateway and prints a principalSet member for AI Gateway’s role, the binding covers every MCP server in the environment. In that case, read the warning in If your environment runs on Google Cloud.
Keep the provider’s full resource name for the server’s configuration:
//iam.googleapis.com/projects/<project number>/locations/global/workloadIdentityPools/redpanda/providers/aigw
If your environment runs on Google Cloud
The printed command grants roles/iam.serviceAccountOpenIdTokenCreator on the service account to AI Gateway’s Google service account. You don’t create a pool or a provider.
| This binding trusts AI Gateway as a whole, not one MCP server. Anyone who can create or edit MCP servers in the environment can then get ID tokens as the service account. Grant permission to create and update MCP servers only to people you trust to act as the service account. |
Grant the service account access at the gate
Add the service account to the identities that IAP or Cloud Run admits. For current syntax, see Google Cloud’s reference for gcloud iap web add-iam-policy-binding, and its guides to programmatic access clients and to authenticating service-to-service requests to Cloud Run.
Follow the option that matches your gate:
-
IAP: Grant the service account the IAP-secured Web App User role (
roles/iap.httpsResourceAccessor) on the IAP resource. For an IAP-secured backend service:gcloud iap web add-iam-policy-binding \ --project=<project-id> \ --resource-type=backend-services \ --service=<backend-service> \ --member=serviceAccount:iap-gate@<project-id>.iam.gserviceaccount.com \ --role=roles/iap.httpsResourceAccessorIf you enabled IAP directly on a Cloud Run service, use
--resource-type=cloud-runwith the Cloud Run service’s name, and add--region=<region>, where<region>is the service’s region. -
Cloud Run: Grant the service account the Cloud Run Invoker role (
roles/run.invoker) on the service:gcloud run services add-iam-policy-binding <service> \ --project=<project-id> \ --region=<region> \ --member=serviceAccount:iap-gate@<project-id>.iam.gserviceaccount.com \ --role=roles/run.invoker
Replace <backend-service> with the name of your IAP-secured backend service, and <service> with the name of your Cloud Run service.
Allow your OAuth client for programmatic access
If IAP uses the Google-managed OAuth client, add your own OAuth client ID to IAP’s programmatic access allowlist, and use that ID as the token’s audience. To add it with gcloud:
cat > iap-settings.yaml <<'EOF'
access_settings:
oauth_settings:
programmatic_clients: [<oauth-client-id>]
EOF
gcloud iap settings set iap-settings.yaml --project=<project-id> --resource-type=iap_web
Replace <oauth-client-id> with your OAuth client ID.
Configure the MCP server
Add the service account and the audience to the MCP server’s configuration. This setting works alongside the server’s own authentication, which you configure as usual.
Self-managed MCP server
Run rpk ai mcp-server create with the --remote.google-identity-aware-proxy.* flags:
rpk ai mcp-server create internal-app \
--enabled \
--remote.url https://internal-app.example.com/mcp \
--remote.transport streamable-http \
--remote.google-identity-aware-proxy.service-account iap-gate@my-project.iam.gserviceaccount.com \
--remote.google-identity-aware-proxy.audience 1234567890-abc123.apps.googleusercontent.com \
--remote.google-identity-aware-proxy.workload-identity-provider //iam.googleapis.com/projects/123456789/locations/global/workloadIdentityPools/redpanda/providers/aigw
Replace the server name, the URL, the service account, the audience, and the provider in the example with your own values. These flags set the following:
-
--remote.url: Sets the server’s URL, which must start withhttps://. -
--remote.google-identity-aware-proxy.service-account: Sets the service account’s email. -
--remote.google-identity-aware-proxy.audience: Sets the audience. For IAP, use the OAuth client ID. For Cloud Run, use the service URL or a custom audience. -
--remote.google-identity-aware-proxy.workload-identity-provider: Sets the provider’s full resource name. Set it in an environment on AWS, and leave it out in an environment on Google Cloud. -
--remote.google-identity-aware-proxy.header-name: Sets the header that carries the token. This flag is optional and isn’t in the example. Without it, AI Gateway usesProxy-Authorization, which IAP reads. For Cloud Run, setX-Serverless-Authorization. The token can’t share a header with the server’s own credential, so setAuthorizationonly if the server’s own authentication uses another header or the server has none.
Add the server’s own authentication flags to the same command, as described in Register a Self-Managed MCP Server. To add the setting to an existing server, pass the same flags to rpk ai mcp-server update <server-name> instead, replacing <server-name> with the server’s name.
To check the setting, run rpk ai mcp-server get internal-app. The output includes a Gate: line that names the service account, the audience, and the header.
In the UI, the server’s edit page shows the setting under Google Identity-Aware Proxy as read-only. Saving the form doesn’t change it. To change it, use rpk ai mcp-server update.
JavaScript MCP server
If your environment runs on AWS, run rpk ai mcp-server google-identity with this server’s name and complete its binding first, as described in Get AI Gateway’s identity. Each JavaScript server needs its own binding.
Then configure the setting in the Google Identity Aware Proxy section of the server’s create or edit form:
-
Set
Service AccountandAudience. -
In an environment on AWS, set
Workload Identity Providerto the provider’s full resource name. -
For Cloud Run, set
Header NametoX-Serverless-Authorization. -
Under
Google Identity Aware Proxy Hosts, click Add Google Identity Aware Proxy Hosts, and then enter a hostname behind IAP or Cloud Run, such asinternal-app.example.com. Repeat for each host.
To use the CLI instead, pass the same settings in --managed.config:
rpk ai mcp-server create internal-app-tools \
--enabled \
--managed.config "$(jq -nc --rawfile code dist/index.js '{
"@type": "JavaScriptMCP",
code: $code,
googleIdentityAwareProxy: {
serviceAccount: "iap-gate@my-project.iam.gserviceaccount.com",
audience: "1234567890-abc123.apps.googleusercontent.com",
workloadIdentityProvider: "//iam.googleapis.com/projects/123456789/locations/global/workloadIdentityPools/redpanda/providers/aigw"
},
googleIdentityAwareProxyHosts: ["internal-app.example.com"]
}')"
Replace internal-app-tools with the server’s name, dist/index.js with the path to your server’s bundle, and the other example values with your own.
AI Gateway applies these rules to Google Identity Aware Proxy Hosts:
-
AI Gateway accepts up to eight exact hostnames. Wildcards aren’t allowed.
-
Your code can fetch a listed host without adding it to
Allowed Hosts. -
AI Gateway adds the token only to HTTPS requests to a listed host on the default port. It removes the token’s header from every other request, including a redirect to another host.
-
Your code never sees the token.
-
Don’t set
Header NametoAuthorization. AI Gateway refuses that value. It strips the token’s header from requests to every other host, so it would also strip theAuthorizationheader that your code sets for those hosts. A credential that you attach with theAuthsetting keeps its own header.
Verify the connection
List the server’s tools through AI Gateway:
rpk ai mcp-server tools list internal-app
Replace internal-app with your server’s name. You need the dataplane_adp_mcpserver_tools_list permission. If the gate admits AI Gateway, the command lists the server’s tools. If not, see Troubleshooting.
Troubleshooting
AI Gateway checks the Google Identity-Aware Proxy setting when you create or update a server, and rejects values that can never work. Only Google can detect some problems, such as a missing binding. Those problems appear the first time AI Gateway requests a token, for example when you list the server’s tools. A self-managed server’s calls fail with 502 upstream_auth_error and a message that names the problem. A JavaScript server’s fetch() fails with that message.
| Symptom | Cause and fix |
|---|---|
|
The environment runs on AWS, so the setting needs a provider. Set the workload identity provider to the provider’s full resource name. Run |
|
The environment runs on Google Cloud, so the setting takes no provider. Remove the workload identity provider, and grant AI Gateway’s service account |
|
The server URL uses |
|
The token can’t share a header with the server’s own credential. Use |
|
A JavaScript server can’t send the token in |
|
A JavaScript server’s setting needs at least one host. Replace any wildcard with the exact hostname of each host. |
|
A JavaScript server lists hosts but has no Google Identity-Aware Proxy setting. Set the service account and the audience, or remove the hosts. |
|
The provider doesn’t exist, its attribute condition doesn’t admit AI Gateway’s role, or an API from If your environment runs on AWS isn’t enabled. Google’s message in the parentheses says which. Compare the provider and its condition with the output of |
|
The service account doesn’t exist, the binding from |
IAP or Cloud Run answers |
AI Gateway got the token, but the gate rejected it. Check that the service account has the role that you granted in Grant the service account access at the gate, and that the audience is the right OAuth client ID or Cloud Run audience. If a proxy or content delivery network (CDN) sits in front of IAP, confirm that it passes the |
|
AI Gateway couldn’t reach Google. Retry the request. |