Skip to main content

One in Five MCP Access Policies Is Broken or Missing: The Audit to Run Before Agents Touch Your Deploy Pipeline

12 min readDora NodaDora Noda
Share
On this page

Roughly one in five MCP access policies is broken or missing. That is the headline finding from a September 2026 Zotpaper report synthesizing research into Model Context Protocol integrations across customer and prospect environments: over 20 percent of the access policies reviewed were non-functional or absent, leaving internal systems open to unauthorized agent access.

Two companion numbers make it worse. Across the ecosystem, 88 percent of MCP servers require credentials to function, but only 8.5 percent actually use OAuth — and over half run on static API keys or personal access tokens that are rarely rotated. Then there is the concrete case: Splunk's own MCP Server app logged session and authorization tokens in cleartext until version 1.0.3, tracked as CVE-2026-20205 — a CVSS 7.2 flaw with a boring, load-bearing lesson.

Now consider where you are about to point this protocol. Deploy and rollback tools are the highest-blast-radius tools a platform can expose: a single authorized call can replace what production serves, roll back a security fix, or delete the environment entirely. Being average — one policy in five broken — is an acceptable statistic for a calendar integration. It is not acceptable for the tool that ships your code. This post works through what "insecure by default" means concretely, what the CVE and the July 2026 spec rewrite teach, and then delivers the artifact everything else builds toward: a ten-check access-policy audit to run before an agent's first deploy call ever reaches production infrastructure.

What "insecure by default" looks like in practice

The phrase gets thrown around until it means nothing, so here is what it cashes out to in the MCP ecosystem, in three specific failure modes.

First, policies that exist on paper but not in enforcement. The one-in-five finding is not "one in five servers has no auth page in the docs." The researchers reviewed MCP-related access policies in real environments and found over 20 percent non-functional or absent — rules that were never wired up, checks that fail open, policies nobody tested. A March 2026 AgentsID audit of 100 MCP server packages — including the reference implementations maintained by Anthropic and Microsoft — found that every vendor-maintained server exposing tools received a failing grade. And a Censys scan in late April found 12,520 MCP services exposed to the public internet on a protocol that requires no authentication by default. The default really is open.

Second, scopes that default to everything. A recurring failure mode in the research: servers that need only read-only access request read, write, and admin permissions — because that is what the tutorial used. Over-scoping is not a theoretical hygiene complaint; it determines what a hijacked agent session can do. When the tool is deploy_to_production and the token it carries also authorizes delete_environment, a prompt-injection success anywhere upstream becomes a production incident. Scope sprawl is the quiet multiplier on every other MCP vulnerability.

Third, static credentials that never rotate. Over half of MCP servers in the wild authenticate with static API keys or personal access tokens, and close to half of enterprise AI activity runs through personal accounts rather than service accounts. GitGuardian's State of Secrets Sprawl 2026 found 24,008 secrets in public MCP configuration files, 2,117 of them still valid. A standing key committed to a config file is a deploy credential with no expiry date and no audit trail — exactly the kind of credential a compliance review flags and an attacker loves.

CVE-2026-20205: the boring log line that leaks live deploy credentials

On April 15, 2026, Splunk disclosed SVD-2026-0407: in Splunk MCP Server app versions below 1.0.3, any user holding a role with access to the _internal index — or the high-privilege mcp_tool_admin capability — could view users' session and authorization tokens in clear text. Classified as CWE-532 (information exposure through log files), CVSS 7.2, fixed in 1.0.3.

Nothing about this vulnerability is exotic, which is precisely why it matters. Nobody broke the cryptography. The server authenticated callers correctly and then wrote the resulting tokens into the standard log pipeline, where any operator with routine index access could harvest live agent credentials with an ordinary query and replay them. As the OWASP AISVS research notes, even when an agent runtime keeps secrets out of the model's context, downstream log sinks routinely undo that discipline.

Translate this to a deploy-tools server and the blast radius sharpens. A harvested session token for a calendar MCP server reads someone's meetings. A harvested token for a deploy MCP server ships code as you — redeploys, rolls back, promotes to production — with your identity attached, through the front door, past every check that only inspects whether the token is valid rather than whether it was stolen. Three lessons fall out:

  1. Audit the log and telemetry pipeline, not just the auth flow. Token redaction in logs, scrubbed error payloads, and minimal retention are access-policy controls, not observability nice-to-haves. The exfiltration path nobody audits is the observability pipeline.
  2. Short token lifetimes are the backstop. A token that lives for minutes is a token a log leak can barely exploit. The CVE's exploitable asset was a standing credential; short TTLs would have rendered the harvested values nearly worthless.
  3. Least privilege bounds the replay. A stolen read-only token used against a least-privilege deploy server can list releases. A stolen admin-default token can ship them. Scope discipline from the previous section is what contains this CVE class when — not if — a sink leaks.

The July 28, 2026 spec rewrite: your server is now an OAuth 2.1 resource server

On July 28, 2026, the MCP maintainers shipped a specification revision built almost entirely around authorization — widely read as an admission that the original trust model did not survive contact with production. If you are building a deploy-tools server today, this revision is your requirements document. Here is what it concretely demands.

Every remote server is now a formal OAuth 2.1 resource server. No bring-your-own-token escape hatch: the server publishes RFC 9728 protected-resource metadata at /.well-known/oauth-protected-resource, challenges unauthenticated requests with WWW-Authenticate, and validates bearer tokens — audience, expiry, scope — itself. Issuing tokens remains someone else's job (your authorization server); enforcing them is yours. A deploy server that accepts a static header and calls it a day is not "pre-spec," it is non-compliant.

Issuer validation is mandatory where present. Authorization servers should include the iss parameter in authorization responses (RFC 9207), and MCP clients must validate a present iss against the recorded issuer before redeeming the code. On the server side, the mirror rule: verify authorization-server metadata issuer matches where you fetched it. Mixed-endpoint metadata — a legitimate authorization endpoint paired with an attacker's token endpoint — is a disclosed credential-theft class, and deploy infrastructure is exactly the high-value target it aims at.

Client credentials are bound to their issuer, and registration moved to documents. The revision deprecates Dynamic Client Registration in favor of Client ID Metadata Documents (CIMD): the client publishes its metadata at an HTTPS URL and uses that URL as its client_id, so there is no registration handshake for an attacker to interpose on. Credentials must never be reused across issuers — each issuer gets its own keyed credential — closing the token-mixing risk in multi-server agent setups.

Tokens are audience-pinned and requests are stateless. Resource indicators (RFC 8707) bind every token's audience to the MCP resource server that will accept it, so a token minted for server A cannot be replayed against your deploy server B. And SEP-2567 removes the Mcp-Session-Id header and protocol-level sessions entirely: each request carries its own version, client info, and capabilities. The session-as-identity bug class — "this connection authenticated once, so everything on it is trusted" — is gone at the spec level.

Step-up authorization accumulates scope. When a token lacks the scope an operation needs, the server challenges with a 403 naming only the scopes the current operation requires, and the client re-authorizes with the union of existing and challenged scopes. For deploy tools this is the mechanism that lets a read-scoped session escalate to deploy:staging for one action without minting an everything-token upfront.

That is the posture the ecosystem is converging on. The audit below turns it into checks.

The access-policy audit: ten checks before the first agent deploy

Run these in order. Each check names what to verify and why a deploy-tools server specifically needs it. If any check fails, the endpoint does not open to agents yet.

#CheckWhy it matters for deploy toolsHow to verify
1Publish RFC 9728 protected-resource metadata and challenge unauthenticated calls with WWW-AuthenticateWithout discovery + challenge, clients fall back to ad-hoc auth (static headers, query tokens) — the 8.5-percent-OAuth trapcurl the /.well-known/oauth-protected-resource endpoint; confirm an unauthenticated tool call returns 401 with a WWW-Authenticate challenge, not an error page or silent success
2Validate authorization-response issuer (RFC 9207 iss) and pin AS metadata issuer to its fetch originMixed-endpoint metadata hands your token endpoint to an attacker; deploy creds are the prizeAttempt a code redemption with a mismatched iss; attempt AS metadata whose issuer differs from the fetch URL — both must be rejected
3Register clients via Client ID Metadata Documents; treat Dynamic Client Registration as deprecated compat onlyRegistration-time interposition mints rogue clients with standing credentialsConfirm production clients use HTTPS-URL client_ids resolving to metadata documents; log and alert on any DCR fallback
4Require audience-bound (RFC 8707), short-lived tokens; never reuse credentials across issuersA token for another server must not deploy your app; short TTLs neuter log-leak replay (the CVE-2026-20205 backstop)Replay a token minted for a different audience — must fail; confirm access-token lifetime is minutes-to-hours with refresh handled by the client
5Grant least-privilege per-tool scopes; use step-up scope accumulation for destructive toolsdeploy, rollback, and delete must never ride on a read-everything token; tutorial-default admin scopes are how hijacks become incidentsList every tool's required scopes; confirm deploy_to_production triggers a 403 step-up naming only its scope when called on a read-scoped token
6Separate scopes per tenant and per environmentA staging token that can promote to production collapses your environments into one blast radiusAttempt a staging-scoped token against the production deploy tool — must fail; confirm scope strings encode tenant + environment
7Gate irreversible actions behind human confirmationAuthorization answers "may this identity act"; only a human answers "should production change right now"Trigger deploy_to_production / rollback / delete_environment and confirm execution pauses for out-of-band approval with full action preview
8Prove no tokens or secrets reach logs, error payloads, or telemetryThe CVE-2026-20205 regression check: your log pipeline is part of your access policyGrep log indexes and error responses for token patterns after exercising every tool; confirm redaction at the collection layer, not just the viewer
9Review every tool description as attack surface; treat third-party content as untrusted inputThe MCPTox 2026 benchmark (45 servers, 20 models) averaged a 36.5 percent attack success rate via poisoned tool descriptions, up to 72.8 percent on the worst model — and Invariant Labs showed in May 2025 that even GitHub's MCP server could be hijacked through a poisoned public issue; a poisoned description invoking deploy executes with the token's authorityLint descriptions for instructions, URLs, and override language; confirm tool text from untrusted sources (issues, docs, chat) can never alter which tool runs or with what arguments
10Use service accounts with rotation; eliminate static keys and personal accountsStanding keys in config files (24,008 found public by GitGuardian, 2,117 still valid) are deploy credentials with no expiry and no ownerInventory every credential the server accepts; confirm each maps to a service account with an owner, an expiry, and a rotation runbook — then delete the rest

Checks 1–4 implement the July 2026 spec posture. Checks 5–7 bound what a valid token and a valid session can do. Checks 8–10 close the three exfiltration and persistence paths the research keeps finding: logs, descriptions, and standing keys.

Ship the audit before the endpoint

The through-line of all three inputs — the one-in-five audit, the Splunk CVE, the spec rewrite — is that MCP authorization failed first as a defaults problem and only second as a cryptography problem. Policies nobody tested, scopes nobody narrowed, keys nobody rotated, tokens nobody redacted: none of these required an attacker smarter than a log query. The July 2026 revision gives server builders the machinery to fix the defaults — resource-server enforcement, issuer binding, audience pinning, step-up scopes — and enterprise managed authorization going stable means SSO-backed, centrally audited agent access is becoming the expected baseline rather than the advanced option.

So the ordering question answers itself. Before your deploy tools get an MCP endpoint, they get the ten checks above, verified against a staging server with production-shaped scopes. Run check 8 against your existing log pipeline this week even if agents are months away — CVE-2026-20205 proved the leak that burns you can already be sitting in an index you query daily. Authorization is the deploy pipeline now; audit it like one.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.

Related articles

Give your agents a chain backend

Autonomous agents hit RPC endpoints very differently than people do. See what bex router handles on their behalf.

Read the agents guide