← Blog

Specified, Not Enforced: seven of ten MCP authorization expectations can be checked from outside

  • #MCP
  • #authorization
  • #OAuth
  • #SARIF
  • #HCAP

The MCP authorization specification is not vague. Revision 2026-07-28 requires OAuth 2.1 with PKCE, Protected Resource Metadata, audience-bound tokens and issuer validation, and forbids token passthrough and session-based authentication. Meanwhile Censys counted 12,500+ MCP services reachable from the internet in April 2026, and independent scans keep putting roughly 40% of them at no authentication at all.

It is tempting to read that as a specification failure. It is not one. The document cannot run, and between a MUST and a deployment there has to be something that looks — which for MCP does not exist yet.

So we asked a narrower question about ten expectations — the nine stated requirements, plus the enforcement property the chapter presupposes: can a prober holding nothing but a client position decide whether a deployment meets it?

Seven of ten can. Send no token, send someone else’s token, send a token minted for another resource, drop the header and keep the session. Most of a deployment’s compliance with its own authorization expectations is a morning’s work to establish — so the forty-percent figure is not telling us these things are hard to see. It is telling us nobody is looking, and the remedy for that is a tool rather than a protocol extension.

Every one of those answers is differential. A server that admits a forged credential has told you nothing on its own: a server that asks for nothing admits everything, and that is a legitimate local deployment rather than a bypassed boundary. The finding is the difference between a baseline taken from the same target in the same scan and the probe that follows it.

The tenth expectation is the one that gives the page its title most literally. Obtaining authority and applying it are different problems, and in at least one published case a tool filter was honoured by the handler that advertises and ignored by the handler that executes. The restriction was specified, deliberately, by the operator. It was announced at discovery. It was not enforced at execution — and nothing about that is visible in how the server handles tokens.

Two more expectations need the implementation’s configuration, which is a vantage-point problem rather than a property one: whether a received token is forwarded upstream is a grep, not a mystery.

And one is decidable by nothing. A token obtained after a user read every scope and a token obtained after a user clicked through are byte-identical — the authorization event happened at another party, at an earlier time, through an interface the resource never saw. That is the confused deputy stated as a measurement problem rather than an attack, and it is the premise the other nine exist to protect.

The classification ships as SARIF 2.1.0: ten rules, two taxonomies, the three undecidable ones present as notApplicable with a stated reason rather than omitted — because a tool that reports only its passes is describing its own vantage point and calling it your posture. Three rules name the module that runs them; the other seven say so by omission rather than by claiming coverage.

Read the full analysis →