Skip to content

Add a conceptual guide for production OAuth authorization - #1801

Open
anneheartrecord wants to merge 1 commit into
modelcontextprotocol:mainfrom
anneheartrecord:docs/production-oauth-guide
Open

Add a conceptual guide for production OAuth authorization#1801
anneheartrecord wants to merge 1 commit into
modelcontextprotocol:mainfrom
anneheartrecord:docs/production-oauth-guide

Conversation

@anneheartrecord

Copy link
Copy Markdown

Resolves #1052

PR Summary

Adds a conceptual guide covering how to do OAuth for a real deployment, so that the answer to "how should someone building a real world MCP server go about authentication?" isn't "read the test fixture."

The core confusion in #1052 is that TestOAuthServer looks like the thing you're supposed to build. It isn't — it's an authorization server, and an MCP server is a resource server. Once that split is clear, the production configuration is mostly AddJwtBearer pointed at an identity provider you already run, plus AddMcp() for the RFC 9728 metadata. The guide leads with that and then covers the parts that actually bite in production.

What's included

  1. New conceptual guide: docs/concepts/authorization/authorization.md
  2. Registered in conceptual navigation: docs/concepts/toc.yml (under Server features, next to HTTP Context)
  3. Added to the conceptual docs landing page: docs/concepts/index.md

Guide coverage

  1. Resource server vs. authorization server, and why TestOAuthServer is a fixture rather than a template
  2. What to require of an authorization server — audience/resource indicators, discovery metadata, PKCE, and dynamic client registration (the one most often overlooked, since MCP clients aren't yours to pre-register)
  3. A production AddJwtBearer + AddMcp configuration, with audience validation tied to the advertised resource
  4. Protected resource metadata: the default well-known endpoint, path scoping, when Resource must be set explicitly, and the reverse-proxy case — the resource identifier and the resource_metadata challenge URL are both derived from the request, so forwarded headers (including X-Forwarded-Prefix, and AllowedHosts to keep them un-spoofable) matter
  5. Per-request metadata via OnResourceMetadataRequest for multi-tenant servers
  6. Enforcement at both layers: RequireAuthorization() on the endpoint, and [Authorize] / [AllowAnonymous] per primitive via AddAuthorizationFilters() — including that listings are filtered, that custom list handlers are not, and that [AllowAnonymous] doesn't combine with endpoint-level gating
  7. Scope-based policies, and why RequireClaim("scope", ...) is the wrong tool for a space-delimited claim
  8. Claim freshness relative to sessions: [Authorize] checks re-read the principal per request, while ConfigureSessionOptions is once per session
  9. A table classifying the existing samples by whether they're production-shaped, and a closing checklist

Notes

  • Docs-only; no source or test changes.
  • Every API claim was checked against the source rather than inferred: McpAuthenticationHandler, McpAuthenticationOptions, ProtectedResourceMetadata, AuthorizationFilterSetup, HttpMcpServerBuilderExtensions, and AuthorizeAttributeTests.
  • I couldn't run make generate-docs locally (no .NET SDK on this machine), so the DocFX build is unverified. The three <xref:> API targets and the xref:identity / xref:stateless / xref:httpcontext links were checked by hand against the source and the sibling docs' uids, and the uid: authorization is unique. Worth a second look from CI.
  • Happy to split any of this out, drop sections, or turn it into a sample instead if that's the more useful shape.
  • [Documentation request] Authentication architecture suggestions #1494 asks for authentication architecture guidance and overlaps with this; it may be closeable by the same doc, or worth a follow-up section.

Documents how to protect an MCP server with OAuth 2.0 against an existing
identity provider, rather than standing up an authorization server the way
the TestOAuthServer fixture does.

Covers the resource server / authorization server split, what to require of
an authorization server, JwtBearer plus AddMcp configuration, protected
resource metadata behind a reverse proxy, per-request metadata for
multi-tenant servers, endpoint and per-primitive enforcement with
AddAuthorizationFilters, scope-based policies, and how claims are refreshed
relative to sessions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Practical OAuth implementation for production

1 participant