---
title: "Decouple Agent Auth From Your MCP Server"
description: "Your agent's cloud identity shouldn't be wired straight into your MCP server. Put a gateway in the middle to translate auth, hand the upstream a scoped token, and enforce role-based access on every tool."
canonicalUrl: "https://zuplo.com/blog/2026/07/15/decouple-agent-auth-mcp-server"
pageType: "blog"
date: "2026-07-15"
authors: "josh"
tags: "MCP, AI Gateway"
image: "https://zuplo.com/og?text=Decouple%20Agent%20Auth%20From%20Your%20MCP%20Server"
---
Wait, you wired your agent's GCP identity straight into your MCP server? I get
it, it's the quick path. But now the server owns a slice of your cloud's IAM,
every new agent is another trust relationship, and switching clouds means
touching the server itself.

When I helped build Azure API Management at Microsoft, the lesson that stuck was
simple: auth and governance belong in a gateway, not smeared across every
backend. Agents and MCP servers are no different.

So put a gateway between the two. The agent trusts the gateway, and the gateway
becomes the access control point, with observability and an audit trail for
free.

<CalloutVideo
  variant="card"
  title="Access Control for AI Agents with Zuplo's MCP Gateway"
  description="Decouple agent auth from your MCP server, translate cloud IAM, and gate tools by role."
  videoUrl="https://youtu.be/CKKLiQRSk6w"
  thumbnailUrl="https://img.youtube.com/vi/CKKLiQRSk6w/maxresdefault.jpg"
  duration="11:14"
/>

<CalloutAudience
  variant="useIf"
  items={[
    `You run agents under a cloud service identity (GCP, AWS, or Azure IAM)`,
    `You want one place to translate auth and enforce authorization across MCP servers`,
    `You'd rather not wire agent credentials straight into each MCP server`,
  ]}
/>

## Trust the gateway, not the server

The agent authenticates to the gateway with whatever identity it already has: a
GCP or AWS service identity, an API key, an Auth0 token. The gateway validates
it, then presents its own credential to the upstream. The two sides never have
to agree on an auth scheme, and your MCP server only ever trusts one caller.

The server on the other side can be anything. Bring your own, built with FastMCP
or whatever you like, or point Zuplo at a REST API and we'll
[generate the MCP server for you](/blog/expose-internal-apis-as-mcp-tools) from
your OpenAPI spec, so there's no server to maintain. Either way, the gateway
fronts it the same.

## Translate auth, skip the secrets

The identity coming in can be one thing and the identity going out another. That
translation is the gateway's whole job. In the demo, my agent shows up with a
JWT from GCP IAM, and the gateway calls the inventory service with a short-lived
token minted for that one upstream.

The part worth stealing: it does all this without storing a single secret. Using
[Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation),
the gateway presents a Zuplo-issued OIDC token that your workload identity pool
trusts, and GCP mints a short-lived token in return.

The trust lives in your cloud's IAM, so the gateway holds no keys to leak. If you
can't leak a secret you don't have, that's one less 3am page.

The route's upstream auth policy references config, not credentials:

```json
{
  "name": "upstream-gcp-federated-auth",
  "policyType": "upstream-gcp-federated-auth-inbound",
  "handler": {
    "module": "$import(@zuplo/runtime)",
    "export": "UpstreamGcpFederatedAuthInboundPolicy",
    "options": {
      "audience": "$env(UPSTREAM_AUDIENCE)",
      "serviceAccountEmail": "$env(UPSTREAM_SA_EMAIL)",
      "workloadIdentityProvider": "$env(WORKLOAD_IDENTITY_PROVIDER)"
    }
  }
}
```

Upstream GCP federated auth is an enterprise-plan policy, free to try in
development. That token is scoped to the one service it calls, so if it ever
leaks (say a backend logs it somewhere it shouldn't) the blast radius is tiny
and it expires fast. Scoping tokens to
[a single server](/blog/bind-mcp-tokens-to-one-server) is a habit worth keeping.

## Curate tools, gate them by role

An agent discovers what a server can do by asking it for a list of tools. You
can pass that whole list straight through, but the entire point of a gateway is
that you don't have to. Curate it down to the tools you trust, and everything
else stops existing on that route.

From there, authorization is per tool. Mark a tool public and any authenticated
caller can use it. Attach a role like `admin` and the caller needs that claim to
see or invoke it.

Anything you don't grant is denied by default: a tool a caller can't reach
doesn't even show up in their list, and calling it anyway returns a clean error
instead of a leak.

Roles and groups not enough? The policy pipeline is programmable, so you write
your own authorization logic as a custom policy. _Sometimes you just really want
your own code in the path._

## Host it wherever your data lives

Because auth is federated instead of shared secrets, the gateway can run
anywhere the identity trust reaches. Our managed edge, on-premise in your data
center, connected to on-prem through a secure tunnel, or a dedicated instance
right next to your service in AWS or GCP. The access control model doesn't
change with the address.

That's the whole idea. 1/ The agent proves who it is once. 2/ The gateway
handles the translation and the authorization. 3/ Your MCP server gets out of
the identity business entirely.

Watch the [full walkthrough](https://youtu.be/CKKLiQRSk6w) for the live demo end
to end, and the
[MCP Gateway docs](https://zuplo.com/docs/mcp-gateway/introduction?utm_source=blog)
will get you set up. Have fun out there, folks. 👏