Most remote and shared MCP servers reach their downstream APIs with one long-lived key that every user and agent ends up sharing. The MCP authorisation specification governs how clients authenticate to an MCP server; it says nothing about how the server authenticates to the database, SaaS API or cloud account behind its tools, and that is where static keys accumulate. A single key in a server's environment turns every connected agent into a user of that key, with no per-user audit trail and a blast radius as wide as the key's permissions. This guide gives a repeatable audit for finding remote and shared MCP servers that use static long-lived credentials downstream, rating them, and moving them to OAuth or short-lived tokens. It is written for platform teams that host MCP servers, NHI owners and the reviewers who approve them. Local servers on developer machines are covered in How to audit MCP servers on developer laptops.
Source note: specification and platform points summarise the sources listed at the end, as of 12 November 2026. Confirm against the official text before relying on it.
Key takeaways
- Audit the server's outbound credentials, not just its front door. A server can pass every inbound OAuth check and still call its upstream API with a shared key that never expires.
- Every tool maps to a downstream credential. Build the audit by walking from each tool to the API it calls and the credential that call uses; that map is the deliverable.
- Use the provider's own data to confirm. Key age and last-use data from AWS credential reports, Microsoft Entra unused credential recommendations and Google Cloud key authentication metrics turn a guess into evidence.
- There is a clear target state. Per-user OAuth for user data, RFC 8693 token exchange where user context must flow downstream, and platform workload identity for the server's own access.
- Migrate in rings with the old key kept disabled, not deleted, until rollback is no longer needed. Then delete it, because a disabled key that is re-enabled is still a long-lived key.
Scope: which servers and which credentials
This audit covers MCP servers reached over Streamable HTTP that more than one person or agent uses: servers your platform team hosts, servers run inside an MCP gateway, and third-party hosted servers to which you have handed a credential. It looks at the credentials those servers use to call downstream systems. Two things are out of scope: local stdio servers, which the specification says should take credentials from the environment and which are covered by the laptop audit, and the inbound token model, covered in the MCP Authorisation Specification Guide.
A credential is in scope when it is static (the same value is presented on every call), long-lived (no expiry, or an expiry measured in months) or shared (used on behalf of more than one user). API keys, personal access tokens, cloud access keys, service account key files, database passwords, client secrets used directly as bearer values and non-expiring refresh tokens all qualify.
Where static credentials hide in remote MCP servers
| Location | What to look for | How to find it (read-only) |
|---|---|---|
| Container or process environment | Variables named for keys, tokens or secrets (*_API_KEY, *_TOKEN, *_SECRET, DATABASE_URL with an embedded password) | Review deployment manifests and task definitions; list environment variable names, never values, from the orchestrator |
| Kubernetes Secrets and mounted files | Secrets mounted into MCP server pods, key files such as service account JSON | List Secrets referenced by MCP server workloads and their mount paths; check last update time |
| Secrets manager or vault paths | Static secrets read at start-up (a vault does not make a key short-lived) | Query the vault's audit log for reads by MCP server identities; check the secret's version history for rotation |
| Gateway credential stores | A gateway that injects one upstream key for all users of a server | Review gateway upstream connection configuration per server |
| Image layers and source | Keys baked into images or committed to the server's repository | Run secret scanning across the server's repository and image layers |
| Request URLs | Keys passed in query strings to the server or by the server upstream | Search gateway and proxy access logs for key-like parameters; the specification says access tokens MUST NOT be in the URI query string |
| Third-party hosted servers | Keys you pasted into a hosting provider's configuration page | Inventory from procurement and SaaS discovery; ask each owner which credential they supplied |
The audit, step by step
- List remote and shared servers. Start from the gateway configuration, the MCP Server Inventory Template and network egress logs showing Streamable HTTP endpoints. Record owner, hosting location, whether the operator is you or a third party, and who connects.
- Enumerate tools. Call
tools/listwith a read-only identity and record each tool. For every tool, note the downstream system it touches (from source code, documentation or the operator). - Trace each downstream call to its credential. For self-hosted servers, read the code path that builds the upstream client and note where the credential comes from. For third-party servers, ask the operator and check what you supplied during setup.
- Classify each credential. Record type, lifetime, whether it is shared across users, its permissions, and when it was created and last rotated (table below).
- Confirm with provider data. Check age and last use at the issuing side, so the inventory is not based only on what owners remember:
- AWS: the IAM credential report lists
access_key_1_last_rotated,access_key_1_last_used_dateandaccess_key_1_last_used_service(and the same for key 2). It can be generated once every four hours and covers only the first two keys per user; useListAccessKeysfor complete coverage. - Google Cloud: service account insights flag accounts unused for 90 days, and the Key Authentication Events metric shows when and how often a key was used.
- Microsoft Entra ID: the Remove unused credentials from applications recommendation flags app secrets and certificates unused for 30 days; credentials are listed under each app registration's Certificates & secrets.
- AWS: the IAM credential report lists
- Check for token passthrough. If a server forwards the client's inbound token downstream, record it as a critical finding: the specification says MCP servers MUST NOT accept or transit any other tokens.
- Rate and assign. Rate each finding, name an owner and a target state, and record it in the inventory so it is re-checked when the server changes.
Classifying what you find
| Credential pattern | Risk | Target state |
|---|---|---|
| Client's inbound token forwarded downstream (passthrough) | Critical: forbidden by the specification, breaks audience binding and audit | Server obtains its own downstream token |
| One broadly scoped non-expiring key shared by all users | Critical: every user acts with the key's full rights; no per-user audit downstream | Per-user OAuth or token exchange |
| Cloud access key or service account key file in the server environment | High: long-lived, often over-privileged, leak-prone | Platform workload identity |
| Narrowly scoped key, rotated on a schedule, server-only data | Medium: acceptable short term where the downstream API offers nothing better | Shorter rotation, IP restriction, vault-issued dynamic credential |
| Non-expiring refresh token held per user | Medium: per-user, but indefinite | Rotating refresh tokens with absolute lifetime |
| Per-user OAuth access tokens with short lifetime, encrypted at rest | Low | Maintain; review scopes |
Raise the rating one level for third-party hosted servers. Anything you hand to a hosting provider is visible to that host. In the Smithery.ai MCP hosting breach, researchers used a leaked deployment token to run commands on a hosted MCP server and captured a client's API key that was passed in the request URL.
Migration paths
Choose the target by asking whose authority the downstream call should carry.
| Path | Use when | How it works | Watch for |
|---|---|---|---|
| Per-user OAuth to the downstream API | Tools act on a user's own data in a SaaS service that supports OAuth | The server acts as an OAuth client to the downstream service and stores a token per user | Encrypt tokens at rest, request minimal scopes, honour revocation; proxies with a static client ID MUST implement per-client consent (MCP security best practices) |
| Token exchange (RFC 8693) | The downstream API trusts your authorisation server and user context must flow through | The server presents the inbound token as subject_token with grant type urn:ietf:params:oauth:grant-type:token-exchange and receives a new token for the downstream resource or audience; the act claim can record the server as actor | Exchange policy must narrow scope, never widen it; see the OAuth Token Exchange and Delegation Guide |
| Platform workload identity | The server needs its own access to cloud resources | The hosting platform issues short-lived credentials to the workload; no key exists to leak | Scope the workload identity to the server's tools only; one identity per server |
| Vault-issued dynamic credentials | The downstream system only accepts static secrets (databases, legacy APIs) | A secrets manager generates a credential per lease with a short time to live and revokes it on expiry | The server's own authentication to the vault must itself use workload identity; see the Secrets Management Guide |
Platform workload identity by cloud
Platforms are listed alphabetically.
- AWS: AWS IAM best practice is to require workloads to use temporary credentials with IAM roles. For workloads outside AWS, IAM Roles Anywhere issues temporary credentials against an X.509 certificate from your PKI. Where a long-term key must remain, AWS recommends using access last used information to update and remove keys safely.
- Google Cloud: Google recommends attached service accounts or Workload Identity Federation instead of keys, and provides organisation policies to disable service account key creation and upload (enforced by default for organisations created on or after 3 May 2024), plus a key expiry setting for new keys and a Service Account Key Exposure Response policy that can disable keys Google detects as leaked. See How to move GKE workloads from keys to Workload Identity Federation.
- Microsoft Azure: managed identities let applications obtain Microsoft Entra tokens without handling any credential, in system-assigned or user-assigned form, and a managed identity can act as a federated identity credential on an Entra application so the application needs no secret or certificate. See the Azure Managed Identities Security Guide.
For servers that span clouds, see Cross-cloud workload identity federation.
Rolling out the change
- Start with the critical findings. Passthrough and shared broad keys first, then cloud keys, then the rest.
- Build the new path alongside the old. Deploy the server version that uses OAuth, token exchange or workload identity in a staging environment with the same tools, and test each tool end to end.
- Pilot ring. Route a small group of users or agents to the new version through the gateway. Compare tool success rates and downstream error codes (401 and 403) with the old version.
- Cut over. Move all traffic, then disable (do not yet delete) the static key at the issuing provider. Watch downstream logs for any remaining use of the old key, which reveals a forgotten consumer.
- Rollback plan. If tools fail, route traffic back and re-enable the key for a fixed, short window with a change record. Never roll back by creating a new long-lived key.
- Delete. After a quiet period with zero use of the disabled key (two weeks is a reasonable default), delete it and record the closure in the inventory.
Decision guidance
- Self-hosted or third-party hosted: for servers you run, you control the code path and can adopt workload identity directly. For third-party hosted servers, prefer those that support per-user OAuth downstream; if a server requires you to supply a broad static key, limit the key's scope, restrict it by source IP where the downstream API allows, and set a short rotation.
- Per-user OAuth or token exchange: per-user OAuth suits SaaS APIs with their own authorisation server. Token exchange suits internal APIs that already trust your identity provider and where you want one policy point.
- When a static key is the only option: some downstream APIs offer only API keys. Accept it with conditions: one key per server, minimal permissions, stored in a vault, rotated on a schedule you can prove, never shared with other servers, and monitored for use from unexpected sources.
- Small teams: run the audit on a spreadsheet from the gateway configuration and cloud credential reports; fix passthrough and shared admin keys first.
- Large estates: make "no static downstream credential" an approval condition for new remote servers, enforce through the gateway and admission policies that reject MCP server workloads mounting key files, and track exceptions with expiry dates.
Detection and measurement
Keep monitoring after the audit so new static keys are caught. Useful signals are new environment variables or Secrets matching key patterns on MCP server workloads, downstream API calls from MCP server egress addresses that authenticate with API keys rather than OAuth tokens, use of a disabled or supposedly retired key, and secret scanning hits in MCP server repositories and images. Watching for attackers testing a leaked server key is covered in our Leaked Secret Validation Detection guide.
- Static credential coverage: percentage of remote and shared MCP servers with every downstream credential classified (target 100%).
- Servers on static downstream keys: count and percentage, tracked monthly down to an agreed exception list.
- Passthrough findings open: target 0.
- Median credential age: for remaining static keys, with a maximum agreed per risk rating.
- Exceptions past expiry: exceptions whose review date has passed (target 0).
Framework mapping
| Framework | Reference | How it applies |
|---|---|---|
| NIST SP 800-53 Rev 5 | IA-5 Authenticator Management; IA-9 Service Identification and Authentication; AC-6 Least Privilege; CM-8 System Component Inventory; SA-9 External System Services | Credential lifetime and rotation, service-to-service authentication, scoping, inventory and third-party hosting |
| NIST CSF 2.0 | PR.AA-01; PR.AA-05; ID.AM-02 | Managing service credentials, access permissions and the inventory of services |
| MITRE ATT&CK v20 | T1552.001 Credentials In Files; T1528 Steal Application Access Token; T1078.004 Cloud Accounts | How static server keys are stolen and reused |
| MITRE ATLAS | AML.T0083 Credentials from AI Agent Configuration; AML.T0098 AI Agent Tool Credential Harvesting | Agent-specific routes to the same credentials |
| OWASP MCP Top 10 (beta) | MCP01:2025 Token Mismanagement and Secret Exposure | Hard-coded and long-lived tokens in MCP deployments |
| OWASP Non-Human Identities Top 10 | NHI7 Long-Lived Secrets | See the OWASP NHI Top 10 NHI7 Long-Lived Secrets Guide |
| ISO/IEC 27001:2022 Annex A | A.5.17 Authentication information; A.8.2 Privileged access rights; A.5.19 Information security in supplier relationships | Secret handling, privileged scope and hosted server providers |
Common failure patterns
- Auditing only inbound auth. The server passes OAuth checks at its front door and the review stops there, while every tool call uses one shared admin key downstream.
- Treating a vault as rotation. Moving a key into a secrets manager hides it from the code but leaves it static; check version history, not location.
- Default or bootstrap keys left in place. MCP proxies and AI gateways often ship with a master key for initial setup. The LiteLLM MCP auth bypass shows how default master keys in an AI gateway exposed the credentials behind it.
- Keys in URLs. Keys passed as query parameters end up in access logs, proxies and the hosting provider's view, as the Smithery.ai case showed.
- Shared keys across servers. One key reused by several MCP servers means one compromised server exposes all of them and rotation breaks everything at once.
- Deleting before confirming. Deleting the old key on cut-over day leaves no rollback; disable first, watch for use, then delete.
Practitioner checklist
- Inventory every remote and shared MCP server, its operator and who connects to it.
- Map every tool to its downstream system and the credential each call uses.
- Confirm credential age and last use from AWS credential reports, Google Cloud key authentication metrics, Microsoft Entra unused credential recommendations and SaaS admin consoles.
- Record token passthrough as critical and fix it first.
- Move shared user-facing keys to per-user OAuth or RFC 8693 token exchange.
- Move the server's own cloud access to platform workload identity, one identity per server.
- For APIs that only accept keys, use one narrowly scoped, vaulted, rotated key per server with an expiring exception.
- Migrate in rings, disable before deleting, and roll back only by re-enabling for a fixed window.
- Monitor MCP server workloads for new key-pattern variables, mounted key files and use of retired keys.
Standards and references
- Model Context Protocol: Authorization (revision 2026-07-28)
- Model Context Protocol: Security Best Practices
- IETF: RFC 8693 OAuth 2.0 Token Exchange
- AWS: Security best practices in IAM
- AWS: Generate credential reports for your AWS account
- Google Cloud: Best practices for managing service account keys
- Microsoft: What are managed identities for Azure resources?
- Microsoft: Remove unused credentials from applications
Related NHI Mgmt Group resources: How to audit MCP servers on developer laptops · Remote MCP Server Hardening Guide · MCP Server Trust Assessment · OAuth Token Exchange and Delegation Guide