• Compute
  • Customers
  • Pricing
Sign In
More Blog Posts
XDiscordLinkedInYouTube

Products

  • GPUs
  • Inference
  • Studio

Developers

  • Model library
  • Documentation
  • Glossary

Company

  • About Us
  • Blog
  • Events
  • Partnership
  • Scale
  • Career
  • Ambassador program
  • Mission & Vision

Popular models

    Stay in the loop

    By submitting, you acknowledge that we may collect and use the information you provide, which may include personal information.

    XDiscordLinkedInYouTube

    Copyright ©2026 All rights reserved.

    Privacy PolicyTerms of UseLegal Documentation
    More Blog Posts
    Engineering

    MCP Server Security: Why API Keys in Config Files Are a Liability

    MCP servers can expose sensitive credentials when API keys are stored in configuration files accessible to AI agents. This article explains the security risks, how OAuth 2.1 and scoped tools reduce them, and the practices teams should use to build safer MCP integrations.

    October 01, 2026

    A developer describing their setup on a public forum put it plainly: every MCP server they had configured placed credentials in config files that the assistant could read, including API keys, OAuth tokens, and database passwords, all in plaintext. That is not a misconfiguration. It is the documented default for most MCP servers, and Trend Micro’s review found that nearly half of the servers examined recommend storing credentials in a plaintext .env or JSON file rather than pulling them from a secrets manager. What makes this different from the ordinary problem of secrets on disk is the reader: the file sits inside the agent’s reachable environment, which means a single prompt injection that persuades the agent to read its own configuration exfiltrates every credential at once.

    • The MCP specification does not mandate authentication. It supports OAuth 2.1 and other methods, but implementation is optional, and the NSA’s May 2026 advisory states this directly. The default for a new server in most frameworks is no auth at all.

    • Config files aggregate credentials. A typical local setup holds tokens for several services in one file: a Stripe key, a GitHub PAT, a database connection string, a cloud access key. A compromise of the machine or of any process that can read that file is a compromise of all of them simultaneously.

    • GMI Cloud’s MCP server uses a one-time browser sign-in rather than an API key, which means no long-lived secret is written to disk on any machine that connects, and access is revoked server-side rather than by editing files.

    • Three documented incidents make the risk concrete. A critical remote code execution flaw in mcp-remote, an npm package with over 558,000 downloads. CVE-2025-54136, which allowed an attacker to repoint an already-trusted config entry at a malicious command. And a sandbox escape in a filesystem MCP server via symlink containment bypass.

    • Token passthrough is explicitly forbidden by the authorization specification. A server must not forward a client’s token to a downstream service, because the downstream service has no way to validate that the token’s scope covers the action being taken.

    • Scoped tools are the second half of the fix. OAuth gives you identity. Per-tool permission scopes give you least privilege, and without them an agent that authenticates successfully still has access to every tool the server exposes.

    Why This Is Worse Than an Ordinary Plaintext Secret

    Plaintext credentials on disk are a familiar problem with familiar mitigations. MCP configuration files are a specific case that is worse in three ways.

    The agent can read the file. This is the property that changes the risk profile entirely. An MCP client runs with the user’s permissions and frequently has file system access through its own tools. A prompt injection that instructs the agent to read ~/.cursor/mcp.json or the equivalent, then include the contents in a tool call to an external endpoint, exfiltrates every credential in the file without triggering any alert that a normal secret leak would produce.

    Conventional secret hygiene assumes the attacker needs to reach the machine. Here the attacker only needs to reach the agent’s context, which is a far larger surface: a retrieved document, a web page the agent browses, or a tool result from a third-party service.

    Credentials aggregate into a single file. A developer with five MCP servers configured has five services’ credentials in one place. The file becomes a concentrated target with the blast radius of every service it touches. Losing it is not one incident, it is five.

    These files are shared routinely. Config files get committed to dotfiles repositories, synced across machines, pasted into chat threads when someone asks for help, and attached to bug reports. The practical rule is that any credential written into one should be treated as already leaked.

    The Specification Made Authentication Optional

    The reason this situation is so widespread is structural rather than accidental.

    The MCP specification deliberately avoids mandating authentication, prioritising ease of adoption. It supports OAuth 2.1, API keys, and other mechanisms, but implementing any of them is the server author’s choice. The NSA’s May 2026 advisory on MCP states this plainly: authorization is optional in the protocol.

    The consequence is that the default for a new MCP server, in most frameworks, is no authentication. A server exposed on a network with that default has publicly callable tools.

    For stdio servers this is defensible, because the transport has no network boundary: the client launched the server as its own subprocess and there is no one else to authenticate. The problem is that the same default carries over when a server is exposed remotely, and the credential handling pattern established for stdio, environment variables read from a config file, carries over with it.

    Three Incidents Worth Knowing

    The mcp-remote remote code execution flaw. JFrog Security Research documented a critical vulnerability, rated CVSS 9.6, in mcp-remote, an npm package with over 558,000 downloads that proxied OAuth connections for MCP clients including Cursor. Operating system commands embedded in OAuth discovery fields were executed by the client.

    The root cause is instructive beyond the specific bug. The MCP client asked an untrusted server where it should send the user to log in, and then followed the answer without validation. Any trust model where a client accepts routing instructions from the server it is trying to authenticate against has this shape of problem available.

    CVE-2025-54136, known as MCPoison. An attacker with the ability to modify an already-trusted MCP configuration file could repoint the entry at a malicious command, which Cursor then executed without re-prompting the user for approval.

    The lesson is that trust in MCP clients has historically been granted to a config entry rather than to its contents. Approving a server once approved the entry, and the entry could later be changed.

    The filesystem server sandbox escape. In early 2026, researchers demonstrated arbitrary file access and code execution against Anthropic’s Filesystem MCP server through a symlink containment bypass. The vulnerability was patched, and it illustrates that even servers built by the protocol’s authors with explicit sandboxing carry a non-trivial attack surface.

    What OAuth Actually Changes

    Moving from a static API key to OAuth 2.1 changes four properties, and understanding which ones matter prevents treating OAuth as a checkbox.

    No long-lived secret on disk. The user authenticates in a browser, the client receives an access token, and the client stores it in its own secure storage rather than in a file the agent can read. The configuration file holds a URL and nothing sensitive.

    Expiry and rotation. Access tokens are short-lived. Refresh token rotation, where using a refresh token issues a new one and invalidates the old, limits the window during which a stolen token is useful. A static API key has no expiry: it is valid until someone remembers to rotate it, which in practice means indefinitely.

    Server-side revocation. Revoking a user’s access is a token revocation at the authorization server, effective immediately for every client. Revoking a static key means finding and updating every configuration file that contains it, on every machine, which is why in practice keys are rarely revoked at all.

    Explicit scope consent. During the authorization flow the user is shown a consent screen listing the scopes being requested, and must approve them. This is a meaningful control that a pasted API key does not have: the key grants whatever the account grants, with no per-connection narrowing and no user-visible statement of what is being granted.

    What OAuth does not give you. Identity, not least privilege. A user who has authenticated successfully typically gains access to every tool the server exposes. That gap is closed by scoping, not by authentication.

    Scoped Tools and the Least Privilege Gap

    When an agent connects to an MCP server, it usually receives the entire tool list. If one of those tools deletes records and the agent only needs to read them, the authentication succeeded and the authorisation failed.

    The fix is per-tool scopes. Each tool declares the permission it requires, and the token’s granted scopes determine which tools the connection can actually call. A read-oriented connection carries read scopes and cannot invoke a destructive tool even if the agent attempts it.

    A practical shape for this, drawn from production implementations:

    Tool

    Required scope

    read_file

    mcp:file:read

    write_file

    mcp:file:write

    delete_file

    mcp:file:admin

    Bind tokens to the server that issued them. RFC 8707 resource indicators tie a token to a specific MCP server URL, which prevents a token issued for one server being replayed against another. Without this, a token leaked from a low-value server can be reused against a higher-value one that shares an authorization server.

    Token passthrough is forbidden. The MCP authorization specification explicitly prohibits a server from forwarding a client’s token to a downstream service. The reason is that the downstream service cannot validate that the token’s scope covers the action being requested, and the delegation chain becomes unverifiable. A server needing downstream access should hold its own credential for that service, scoped to what it actually needs.

    The strongest version of the tool-scope argument is removal rather than restriction. A tool surface that contains no destructive operations at all cannot be manipulated into performing one. This is the reasoning behind GMI Cloud’s MCP server exposing no deletes, no account modifications, and no irreversible operations in its v1 tool set: an agent cannot misuse a capability that was never exposed.

    If You Must Use a Static Key

    Some servers do not support OAuth, and a static credential is the only option. Three practices reduce the exposure.

    Keep the key out of the file itself. Most clients support variable interpolation so the configuration holds a pointer rather than a value. Syntax varies by client: ${env:NAME} reads from an environment variable, ${input:...} prompts and stores the value in the client’s own secure storage, and ${file:/path} reads from a separate file that can have tighter permissions than the config.

    With this, the configuration file becomes safe to version-control, which removes an entire category of accidental leak.

    Use the narrowest key the service offers. Many APIs support scoped tokens with read-only or resource-limited permissions. An MCP server that only reads should hold a read-only key. This does not prevent the key from being stolen, but it bounds what a thief can do with it.

    Rotate on a schedule and treat any sharing as a leak. If the config file was pasted into a chat thread, attached to a bug report, or committed anywhere, rotate. The cost of rotating unnecessarily is low; the cost of not rotating after a real exposure is not.

    The proxy pattern as a stronger alternative. A local credential vault that acts as an MCP proxy holds the credentials encrypted at rest and injects them at request time. The client configuration contains only the proxy command and no keys. The agent sends a request, the proxy executes the call with the real credential, and the agent receives only the result. The credential never enters the agent’s readable context, which closes the prompt-injection exfiltration path specifically.

    Server-Side Responsibilities

    For teams building an MCP server rather than consuming one, five requirements follow from the incidents above.

    Implement OAuth 2.1 as a resource server. The server validates tokens; it does not issue them. It serves protected resource metadata at a well-known path and returns a correctly formed 401 with a resource_metadata link on unauthenticated requests. PKCE is mandatory for public clients under OAuth 2.1.

    Do not put session identifiers in URLs. Query-string session IDs appear in server logs, in reverse proxy logs, and in referrer headers sent to any third party the agent subsequently contacts. The 2026-07-28 protocol revision removed session state entirely, which eliminates this class of issue for servers on the current revision.

    Scope every tool and enforce scopes at invocation. Declaring a scope in a tool definition is documentation. Checking it before executing the handler is a control.

    Isolate the runtime. Run each server in a container with minimal capabilities, read-only mounts where possible, and no network access beyond what the tools require. The filesystem sandbox escape is a reminder that application-level containment can be bypassed and that the container boundary should be doing real work.

    Log tool invocations. Most MCP server implementations log nothing by default. Application logs capture errors, which means a successful but unauthorised tool call leaves no trace. Every invocation should record the authenticated identity, the tool, the parameters, and the outcome, which is also what makes the audit trail possible.

    Multi-Tenant Isolation

    Enterprise MCP deployments involve multiple teams, projects, and security zones sharing infrastructure, and the failure mode is data from one tenant appearing in another’s context.

    The Asana MCP data leak in June 2025 is the reference case for this class. The requirement is that every operation be scoped to the authenticated tenant at the data access layer rather than by the server passing a tenant identifier that the caller supplies.

    This is the same structural principle that applies to agent authorisation generally, covered in Agentic Infrastructure Governance: the control must sit outside the model’s control loop, in the layer that mediates the operation, rather than depending on the request carrying the correct scope.

    Where Identity-First Architecture Leads

    The direction the security community is pushing is away from stored credentials entirely.

    Workload identity authenticates the server itself, using cloud IAM, GitHub OIDC, or SPIFFE and SPIRE, rather than having it hold a hardcoded key. The server proves what it is, and the authorization decision follows from that proof rather than from possession of a secret.

    Secretless access extends this so that credentials are injected at runtime for the specific call rather than stored anywhere the server or agent can read. Where a destination still requires a long-lived key, it is held in a broker and injected at request time, so the application itself remains secretless while policy and auditing still apply.

    Short-lived credentials issued through workload identity replace stored ones, scoped and audited per server. This is the pattern that scales to an environment where an MCP server holds a credential for every system it connects to, and where the number of such servers grows.

    For most teams the immediate step is narrower: prefer servers that support OAuth, keep static keys out of files that the agent can read, and scope the tools rather than only the connection.

    How GMI Cloud’s MCP Server Handles This

    Three design choices in the GMI Cloud MCP server map directly to the risks above.

    A one-time browser sign-in rather than an API key. No long-lived secret is written to a configuration file on any connecting machine. The client holds a token in its own secure storage, and revocation is server-side.

    A deliberately non-destructive tool surface. The v1 tool set contains no deletes, no account modifications, and no irreversible operations. This is least privilege enforced by absence: an agent that is successfully manipulated cannot invoke a capability that does not exist.

    Every call lands in console history and billing. Tool invocations are recorded centrally rather than in a log on the user’s machine that nobody reads. This is the audit trail that a local server structurally cannot provide, and it is what makes anomaly detection on tool usage possible at all.

    The launch post, GMI MCP Server: Turn your assistant into a production studio, covers the tool surface in detail. For teams building agents that consume MCP servers, GMI Agentbox provides the runtime and deployment layer.

    Conclusion

    The credential-in-config-file pattern is the MCP ecosystem’s default, not an aberration, and it carries a risk that ordinary secret-on-disk guidance does not address: the file is inside the agent’s reachable environment, so a prompt injection is sufficient to exfiltrate it. With several servers configured, that single file holds credentials for every service the agent touches.

    OAuth 2.1 removes the long-lived secret from disk, adds expiry and server-side revocation, and puts an explicit consent step in front of scope grants. It gives you identity. It does not give you least privilege, which requires per-tool scopes enforced at invocation, tokens bound to the issuing server via resource indicators, and a prohibition on forwarding tokens downstream.

    The strongest version of the control is removal. A tool surface with no destructive operations cannot be manipulated into performing one, regardless of how well the injection is crafted. For a server exposing capabilities to autonomous agents, deciding what not to expose is the security decision that matters most.

    Build AI Without Limits

    GMI Cloud helps you architect, deploy, optimize, and scale your AI strategies

    FAQ

    Because the agent can read it. An MCP client runs with the user’s permissions and frequently has file system access through its own tools, so a prompt injection that instructs the agent to read its own configuration and include the contents in an outbound tool call exfiltrates every credential in the file. Conventional secret hygiene assumes an attacker must reach the machine; here the attacker only needs to reach the agent’s context, which includes retrieved documents, browsed web pages, and results from third-party tools. The problem compounds because a typical setup aggregates credentials for several services into one file, so the blast radius is every service at once.

    Ready to build?

    Explore powerful AI models and launch your project in just a few clicks.

    Get Started