Zero-Trust Authorization and Discovery for Enterprise MCP
Organizations: PayPal Inc. USA
Abstract
LLM agents translate natural-language context, which may include attacker-controlled text, into privileged tool calls, so authorization must remain effective even when an agent is prompt-injected or adversarially steered. The Model Context Protocol (MCP) has become a widely adopted interface for this boundary, yet its official SDKs' authentication and authorization primitives fall short of enterprise zero-trust requirements, most acutely a dual-persona model in which one server must serve human users (corporate SSO) and automated agents (service-account credentials on a different header). We conduct a systematic gap analysis of six surveyed MCP SDKs (Python, TypeScript, Go, Rust, C#, Swift) and identify three structural shortcomings: credential extraction bound to a single Authorization header, complicating dual-persona deployment without custom middleware; the absence of pre-authentication tool discovery; and the lack of fine-grained per-tool authorization in the base SDKs. We close these gaps with composable extensions to FastMCP: cross-header credential normalization for enterprise deployments serving both human and service-account callers, cached token verification across heterogeneous IdPs, an unauthenticated metadata endpoint for credential-free registry discovery, and permission-filtered tool visibility kept consistent with per-tool invocation enforcement by a single declarative annotation, all without modifying the protocol or SDK internals. Across four frontier LLMs over 2160 attempts, an in-body-check-only server still exposes forbidden tools (152/720, 21.1%), whereas permission-aware visibility drives the rate to 0/720; visibility-only filtering remained bypassable by scripted clients, while models referenced the hidden tool by name in up to 94% of settings when inferable from the prompt, confirming that discovery controls cannot replace invocation-time enforcement.
Figures & tables
| Capability | Py † | TS | Go | Rust | C# | Swift |
|---|---|---|---|---|---|---|
| Pluggable auth backend | P | P | P | Y | Y | Y |
| Pre-auth discovery (schema+auth) | N | N | N | N | N | N |
| Permission-based filtering | Y | N | N | N | N | N |
| Vendor-API token verif. (beyond RFC 7662) | N | N | N | N | N | N |
| Declarative per-tool permissions | Y | N | N | N | N | N |
| list_tools | call_tool | |||
|---|---|---|---|---|
| Configuration | p50 | p95 | p50 | p95 |
| vanilla MCP | 1.71 | 1.98 | 2.15 | 2.41 |
| +auth | 1.78 | 2.07 | 2.18 | 2.58 |
| +auth+filter | 1.70 | 2.08 | 2.21 | 2.59 |
| +auth+filter+decorator | 1.67 | 1.92 | 2.18 | 2.49 |
| Goal | Defender | Attack scenario | Result |
|---|---|---|---|
| G1 Tool misuse | C4 (filter + decorator) | Section 4.3.1 Prompt injection | (4 LLMs) |
| G2 Header confusion | C1 (deterministic merge) | Section 4.3.2 , multi-header matrix | no wider scope |
| G3 Auth bypass | C1 (OR composition) | Section 4.3.2 , same matrix | all-fail error |
| G4 Stale credential | C2 (bounded TTL) | Section 4.3.3 Revoke + reuse | TTL (300 s default) |
| Baseline (per attack class) | Baseline | Filter-only | With-ext. | ||||
|---|---|---|---|---|---|---|---|
| Model | DI | II | RP | CO | overall | overall | overall |
| claude-sonnet-4-6 | |||||||
| claude-opus-4-7 | |||||||
| gpt-5 | |||||||
| gemini-2.5-pro | |||||||
| Total | |||||||
| Bearer | Custom | Backend outcome | Scopes |
|---|---|---|---|
| yes | no | Bearer succeeds | Bearer |
| no | yes | Custom succeeds | Custom |
| yes | yes | Both succeed | Union |
| no | no | All return None | Error |
| Configuration | Listed | Direct call execs | Blocked by |
|---|---|---|---|
| Baseline | yes | no | in-body check |
| Filter only | no | yes | — (bypass) |
| With-extensions | no | no | @require_perm |
| Pre-auth schema | Per-tool authz | Cross-header creds | Discovery-coupled | |
|---|---|---|---|---|
| Envoy / Istio ( Li et al., 2019 ) | — | — | part. | — |
| OPA / Cedar ( Open Policy Agent, 2024 ; Amazon Web Services, 2023 ) | — | yes | — | — |
| SPIFFE/SPIRE ( SPIFFE Project / CNCF, 2022 ) | — | — | — | — |
| FastMCP auth= ( Lowin, 2026 ) | — | yes | part. | part. |
| Cerbos–FastMCP ( Cerbos, 2025 ) | — | yes | — | part. |
| Gateway ( Kumar et al., 2026 ) | n/r | n/r | yes | n/r |
Appendix figures & tables1 asset
Supplementary material from the paper’s appendix.
Appendix
| Language | Version | Released |
|---|---|---|
| Python | v1.27.0 (+ fastmcp v3.4.0) | 2026 |
| TypeScript | v1.26.0 | 2026-02-04 |
| Go | v1.3.0 | 2026-02-09 |
| Rust | rmcp v1.2.0 | 2026-03-11 |
| C# | v1.1.0 | 2026 |
| Swift | 0.10.2 | 2025-09-23 |
MCP Security
Model Context Protocol (MCP) security studies how to protect AI agents, tool servers, and data flows from attacks and misuse.
See all 41 papers