# Retire shared API keys

> Give every client, partner, and agent its own credentials and only the access it needs, instead of one shared key that every integration depends on.

One API key shared by every client is easy to start with and hard to live with. When it leaks, you cannot tell which caller caused the incident, and rotating it breaks every integration at once. As more partners and agents connect, each of them also reaches every tool behind the gateway, because one key cannot express what each caller is allowed to do.

## What you can do

- Issue a separate API key for each client or partner so that revoking or rotating one key leaves every other integration working.

- Keep Microsoft Entra, Okta, or another OIDC provider as the source of truth so that callers present tokens your identity provider issued, with no second identity store to maintain.

- Accept tokens from internal callers and API keys from partners on the same surface so that both groups reach one managed agent through one configuration.

- Give each agent a stable DID derived from its identity provider record so that every request is attributable to a known agent, even after its token rotates.

- Show each agent only the MCP tools it needs so that privileged tools stay hidden from callers that should not use them.

- Gate access on token claims such as group or tenant membership so that a change in your identity provider changes what an agent may reach, with no change on the gateway.

## How it works

Authentication is set on a surface’s Caller Context element rather than built into each client. One Caller Context can hold several methods, so internal agents and partners can call the same surface: JWT Bearer for tokens from your identity provider and API Key (provider) for partners, each reading its own header. The gateway verifies each request with the method whose credential it carries. A request carrying credentials for both fails caller authentication, so a caller can’t choose the identity the gateway asserts.

With the API Key (provider) method, you create keys on the Secrets page’s API Keys tab with New API Key, choosing the Surface and a Client ID such as the partner’s name. Each key can be revoked or rotated on its own from the same list. Rotating issues a new secret under the same key ID and stops the old secret working immediately, so agree the hand-over with that client first.

For callers from your own organisation, the JWT Bearer method checks each token against a strategy on the Credentials page’s JWT Verification tab, which pins the Expected Issuer and the provider’s signing keys. Entra, Okta, or any standard OIDC issuer stays the authority on who a caller is. For agents that already hold a DID of their own, the DID Auth method authenticates the caller by that DID instead.

Once a caller is authenticated, OPA policies at gateway and surface level decide what it may reach. A policy reads the method that verified the caller as input.source_auth.method, jwt_bearer or api_key, so internal callers and partners can follow different rules on one surface, alongside token claims such as group or tenant membership. On an MCP surface, the MCP Tool Gating element adds allow and deny gates matched by tool-name patterns, each optionally conditioned on a policy, and applies them to both tools/list and tools/call. A deny gate conditioned on input.source_auth.method == "api_key" removes a tool from partners without affecting internal callers, and a gate whose condition cannot be evaluated fails closed.

Separate surfaces in front of the same tools remain an option in two cases:

- The groups need tool sets you prefer to keep apart by surface rather than by gates and policy.

- Internal agents need a stable DID from the Identity element’s From JWT Claims type, by default from the Entra oid object identifier, so the same agent keeps the same DID across token rotation. From JWT Claims needs every Caller Context method on the surface to be JWT Bearer, so give those agents a surface of their own.

A request with a missing, invalid, or revoked credential is refused with 401 Unauthorized before it reaches the target, because new surfaces are closed by default. On a surface with Public access on, the request reaches the policy layer as a failed authentication instead, so keep a policy there that requires a valid authentication method.

## Related

- [Accept JWTs and API keys on one surface](/products/affinidi-trust-fabric/agent-gateway/how-to-guides/access/accept-jwts-and-api-keys-on-one-surface.md): Add an API key method beside JWT Bearer so both groups call one surface.

- [Restrict surface access with API key authentication](/products/affinidi-trust-fabric/agent-gateway/how-to-guides/access/restrict-surface-access-with-api-key.md): Step-by-step guide to issuing per-client API keys for a surface.

- [Validate bearer tokens on a surface](/products/affinidi-trust-fabric/agent-gateway/how-to-guides/access/validate-bearer-tokens-on-a-surface.md): Point a verification strategy at your OIDC provider’s issuer and signing keys.

- [Enable authorization server discovery for MCP clients](/products/affinidi-trust-fabric/agent-gateway/how-to-guides/access/enable-authorization-server-discovery-for-mcp-clients.md): Let MCP clients sign users in at your IdP and fetch tokens for an MCP surface.

- [Use JWT claims to control access to a surface](/products/affinidi-trust-fabric/agent-gateway/how-to-guides/policies/use-jwt-claims-to-control-access-to-a-surface.md): Write policy that gates access on group, tenant, or other token claims.

- [Control MCP tool access with per-tool policies](/products/affinidi-trust-fabric/agent-gateway/how-to-guides/policies/control-mcp-tool-access-with-per-tool-policies.md): Bind individual tools to policies and gate whole families by pattern.

- [Agent identity and DIDs](/products/affinidi-trust-fabric/agent-gateway/concepts/identity.md): How a stable agent DID is derived from a JWT claim, an API key, or the request payload.
