The short version

If your MCP server calls other APIs on behalf of users or on behalf of your own agent, those credentials will eventually need to change. API keys get leaked in logs, OAuth refresh tokens expire, and a security scare forces a re-issue. The point of rotation is not to be clever; it is to keep paying customers running while you swap credentials underneath them. Below is a workflow that does that, with safe re-auth steps, planned downtime, and a rollback path you can actually use.

What “rotation” means here

In an MCP context, you are dealing with two very different kinds of credentials, and they rotate differently.

Static API keys. A long-lived string you paste into an .env file or a secrets manager. Examples: a personal access token from GitHub, an OpenAI project key, a Stripe secret key. Rotation = generate a new key, deploy it, retire the old one.

OAuth credentials. A pair: an access token (short-lived) and a refresh token (longer-lived, used to mint new access tokens). Examples: a user authorizing your MCP server to read their Google Drive, or your agent authenticating against another MCP server. Rotation here means either forcing a fresh authorization code flow, or rotating the refresh token itself if your authorization server supports refresh token rotation.

The MCP Authorization spec (2025-06-18) builds on OAuth 2.1 and requires that MCP servers validate tokens were issued for them, scope them tightly, and avoid passing received tokens through to upstream APIs. That makes rotation planning a core part of running the server, not a chore you defer.

Why rotation breaks dependent workflows

Most outages during rotation are not the rotation itself; they are the surprise. The agent keeps calling the old key, the upstream API rejects it, and the user sees a “something went wrong” instead of a “we are rotating, give us 60 seconds.” Three failure patterns show up repeatedly:

  1. Hard-coded keys in client config. A user pasted a key into a desktop client config and never comes back. When you rotate, that client silently fails until the user manually edits a file.
  2. Refresh tokens without rotation support. Your authorization server issues a refresh token once and reuses it. You delete it server-side to force re-auth, and now every concurrent user breaks at the same time.
  3. Single shared key for many tenants. Every customer is hitting the same upstream API with the same key. Rotate it, and you either do a synchronized outage or you have a small window where some traffic uses the old key and some uses the new, with no easy way to tell which.

Rotation only works if you treat it like a deployment: staged, observable, and reversible.

A pre-rotation checklist

Before touching anything, walk this list. It saves more outages than any clever script.

  • Inventory every credential your MCP server uses. Pull them from your secrets manager, your env files, and any place a developer might have hard-coded one “just for testing.” Test environments leak into production more often than people admit.
  • Classify each credential by rotation method. Static key, OAuth access+refresh, or per-user delegated auth. Each has a different cutover path.
  • Identify the blast radius. Does the key serve one user, one workspace, or every customer on your platform? The bigger the blast radius, the more you need a parallel-run window.
  • Confirm the upstream supports overlapping credentials. Most APIs allow both old and new keys to be valid for a grace period. Confirm that. If the upstream invalidates the old key immediately on issue, your only option is a hard cutover.
  • Pick a maintenance window that fits your traffic. For B2B tools, weekday late night in your customers’ time zone. For consumer-facing tools, the lowest-traffic hour you can find.
  • Prepare a rollback. Old key still valid? Ability to redeploy a previous container or revert a secrets version? If both are no, you do not have a rollback.

Rotating static API keys

The simplest case. The goal is to make the new key the active one everywhere before revoking the old one.

Step 1. Issue the new key at the upstream provider. Generate it in the provider’s dashboard. Label it with a timestamp and the deployment it belongs to, for example prod-mcp-2026-03-15-cutover. Do not reuse labels.

Step 2. Store it in your secrets manager before deploying. Add it as a new secret version. Keep the old secret version intact. Most secrets managers let you reference a specific version, which is what makes parallel run possible.

Step 3. Deploy the new version behind a flag. Your MCP server should read the credential by reference, not by literal string. A simple env var like UPSTREAM_API_KEY_VERSION=2026-03-15 lets you flip without a redeploy.

Step 4. Run dual-key for the grace period. If the upstream accepts two valid keys, configure your server to try the new key first, and fall back to the old key if the new one returns a 401 or 403. This gives you real signal before you commit.

Step 5. Watch your error logs. Look for an uptick in auth failures on the new key versus the old. A clean cutover shows the new key succeeding and the old key never being touched. If you see the old key still being used, you missed a caller.

Step 6. Revoke the old key only after the grace window. For B2B workloads, 24 to 72 hours is common. For internal tools, an hour is usually enough. Never revoke before you’ve confirmed traffic has switched.

Step 7. Remove the old secret version. Once empty. Keep a record of the rotation (who, when, which key id) for audit. Rotation events are the kind of thing a SOC 2 reviewer will eventually ask about.

Rotating OAuth refresh tokens

This is where indie developers get hurt, because OAuth has more moving parts than a static key. The MCP authorization specification expects OAuth 2.1 behavior, which includes refresh token rotation on the authorization server side when supported. That changes the playbook.

Step 1. Decide whether you are rotating the client registration or the user grant.

  • Rotating the client registration means issuing a new client id and client secret (if your MCP server is a confidential client). Existing user grants usually survive, but you must update the metadata your server publishes.
  • Rotating the user grant means forcing every user to re-consent and re-authorize. Use this only when refresh tokens are suspected compromised, not as routine maintenance.

Step 2. If you are rotating client credentials, use Dynamic Client Registration where you can. The MCP spec recommends support for RFC 7591 (Dynamic Client Registration). If your authorization server supports it, you can register the new client, deploy it, and retire the old one without touching user tokens.

Step 3. For refresh token rotation, check if your authorization server already does it. OAuth 2.1 makes refresh token rotation optional but recommends it for confidential clients. If your provider (Auth0, Okta, WorkOS, Keycloak, etc.) issues a new refresh token on every refresh, you do not need to do anything special. The rotation is continuous.

If your provider does not rotate refresh tokens, you are running long-lived bearer credentials, and you should treat refresh tokens like static keys: scheduled rotation, parallel window, audit trail.

Step 4. Force re-auth in a controlled way. The right way to force a user to re-authorize is to delete their stored refresh token in your system, then on their next call, your MCP server returns 401 with the resource_metadata pointer to the authorization server, and the client walks the user through the OAuth flow again. The wrong way is to delete tokens at the upstream provider and watch your logs burn.

Step 5. Stagger re-auth if you have many users. For a user base of any size, do not invalidate every refresh token at the same instant. Either:

  • Send a re-auth prompt to a percentage of users per day, or
  • Set refresh token expiry to a short window (7 days) and let tokens naturally roll. This is slower but operationally boring, which is exactly what you want for routine rotation.

Step 6. Validate the audience on every new token. The MCP spec requires that access tokens presented to an MCP server were issued for it. During rotation, this is also your safety net: if a user somehow presents a token meant for a different resource, you reject it instead of acting on it. Permit.io’s MCP guidance is explicit on this point: never accept or pass through tokens meant for some other upstream API.

Planning the downtime window

For static API keys, you can usually get to zero downtime if your upstream supports two valid keys. For OAuth, expect users to see a brief re-auth prompt. How brief depends on your client.

  • Hosted web clients can re-auth in a popup. Users see one consent screen. Seconds of friction.
  • Desktop or CLI MCP clients may need the user to paste a new token or re-run a login command. Minutes of friction, and a support ticket if your docs are unclear.
  • STDIO transport servers are local; you can read credentials from the environment, and the user can re-authorize interactively. Plan for a one-time prompt per affected user.

Tell customers before you rotate. Even a one-line status note the day before, with the window and a link to re-auth instructions, prevents most of the “your app is broken” tickets.

A rollback path that actually works

A rollback is not “hope the upstream is forgiving.” It is a tested sequence of steps that returns the system to its prior state in under five minutes.

For static keys:

  • Keep the previous secret version in your secrets manager for at least the full grace window.
  • Your MCP server should accept a ROLLBACK=1 flag that re-reads the previous version and ignores the new one.
  • Document the exact env var change or flag flip. Practice it once on staging.

For OAuth:

  • Keep the old client registration active until rotation is complete and observed.
  • Keep a copy of the previous authorization server metadata document. If you published a new resource_metadata URL, you can revert that URL.
  • If you invalidated refresh tokens, there is no automatic rollback; affected users must re-authorize. The rollback here is communication: tell them what happened, what to do, and why.

The GitGuardian writeup on OAuth for MCP highlights a risk worth keeping in mind: agents chain tool calls in sequences you did not pre-write, which means a rotation error can surface several steps downstream from the actual failure. Make sure your error responses are specific (“refresh token rejected, please re-authorize”) rather than generic (“something went wrong”).

Quick FAQ

How often should I rotate API keys? Quarterly is a reasonable default for indie SaaS. Rotate immediately on any confirmed leak or employee offboarding.

Do MCP servers require OAuth? No. Authorization is optional in the MCP spec. STDIO servers commonly use environment credentials. HTTP-based servers that touch user data should use OAuth 2.1.

Can I rotate without downtime? For static keys against providers that support overlapping credentials, yes. For OAuth user grants, expect a re-auth prompt and budget for it.

Where should I store the new key during rotation? In your secrets manager, as a new version. Never in code, never in .env files committed to git, and never in LLM context as plaintext.

Sources