{"slug": "show-hn-authplane-oauth-2-1-and-pkce-authorization-server-for-mcp", "title": "Show HN: AuthPlane – OAuth 2.1 and PKCE authorization server for MCP", "summary": "AuthPlane, an open-source OAuth 2.1 and PKCE authorization server for the Model Context Protocol (MCP), launched as a single Go binary with built-in admin UI, DPoP support, and federation with existing identity providers. The project aims to simplify securing MCP servers by providing spec-compliant token issuance, agent-to-agent delegation, and zero-config development, addressing a critical gap in the MCP ecosystem.", "body_md": "One Go binary. AGPL-3.0. MCP Authorization spec **2025-11-25**, end-to-end.\n\nAI coding agents:read[AGENTS.md]first — it has the deterministic workflow for adding Authplane to an existing MCP server, the SDK pins per stack, and the three byte-for-byte rules that cause >90% of`invalid_token`\n\nfailures. If you're an agent operating from web docs (no clone),[llms.txt]is the same link map in the[llmstxt.org]convention.\n\nBuilding an MCP server is now a one-afternoon job. Securing it isn't. You need to issue tokens, validate them, federate to your existing IdP, and let agents act on each other's behalf without losing the user behind the chain. Authplane is the one piece of infrastructure that answers all of that.\n\n**Spec-compliant access tokens** for any MCP server in any language — discovery, scopes, audience binding, refresh rotation, in token formats your existing resource servers already understand.**Federation to your existing IdP**— Google, Okta, Azure AD, Auth0, anyone OIDC-compliant. Authplane handles the OAuth side; you keep the access policy.** Agent-to-agent delegation**— one agent calls another on a user's behalf, with every hop recorded as an act-claim chain in the issued token and the audit log.**Upstream provider vaulting**— store GitHub / Google / Slack / Linear refresh tokens encrypted at rest and vend fresh access tokens via RFC 8693, with per-user / per-agent / per-resource consent enforced at every hop.**DPoP proof-of-possession**— bind tokens to a client-held key so a leaked token can't be replayed from another machine.** Built-in Admin UI**— React dashboard embedded in the same binary. No separate frontend, no extra container.** Production storage and observability**— PostgreSQL with cross-instance LISTEN/NOTIFY, OpenTelemetry traces and metrics, Prometheus, Helm chart, Vault Transit for HSM-grade signing.**Zero-config dev**— default SQLite, auto-generated signing keys, sensible defaults.\n\n(Full RFC inventory at the bottom — [Standards & Specifications](#standards--specifications).)\n\n**One docker run. A working OAuth 2.1 + MCP authorization server in under a minute.**\n\n```\nexport AUTHPLANE_ADMIN_API_KEY=\"$(openssl rand -hex 32)\"\nexport AUTHPLANE_SESSION_SECRET=\"$(openssl rand -hex 32)\"\necho \"Save this — it's your Admin UI login: $AUTHPLANE_ADMIN_API_KEY\"\n\ndocker run -p 9000:9000 -p 9001:9001 \\\n  -e AUTHPLANE_ADMIN_API_KEY \\\n  -e AUTHPLANE_SESSION_SECRET \\\n  -e AUTHPLANE_CLIENT_CREDENTIALS_ENABLED=true \\\n  -e AUTHPLANE_DPOP_ENABLED=true \\\n  -e AUTHPLANE_TOKEN_EXCHANGE_ENABLED=true \\\n  -v authserver-data:/data \\\n  authplane/authserver:latest serve\n```\n\nOpen [http://localhost:9001/admin/ui/](http://localhost:9001/admin/ui/) and paste the printed API key. The public OAuth endpoints are on [http://localhost:9000](http://localhost:9000).\n\n**Writing an MCP server from scratch?** Start at the runnable example for your language —[Python](/AuthPlane/authserver/blob/main/examples/python/01-mcp-server-basic)·[TypeScript](/AuthPlane/authserver/blob/main/examples/typescript/01-mcp-server-basic)·[Go](/AuthPlane/authserver/blob/main/examples/go/01-mcp-server-basic). Auth in 5 lines, end-to-end smoke in`make verify`\n\n.**Adding auth to an MCP server you already have?** The retrofit example is a runnable before/after pair — same three tools in two versions, side-by-side, with a smoke-test that proves`before`\n\naccepts anything and`after`\n\nenforces auth.[Python](/AuthPlane/authserver/blob/main/examples/python/retrofit-existing-mcp-server)·[TypeScript](/AuthPlane/authserver/blob/main/examples/typescript/retrofit-existing-mcp-server)·[Go](/AuthPlane/authserver/blob/main/examples/go/retrofit-existing-mcp-server). Or read thefor the prose version.**Connect an MCP Server** guide**Already have an MCP server running elsewhere?** To point this AS at*your*server and drive the whole OAuth flow by hand with`curl`\n\n— no SDK, no compose — see[Run the AS standalone and point it at your own MCP server](/AuthPlane/authserver/blob/main/docs/guides/integrate/standalone-as-by-hand.md). It also reconciles this Quick Start's config with the`examples/`\n\n`.env`\n\nstyle.**Operator quickstart**(upstream providers, PostgreSQL, OIDC federation, Helm, multi-instance):.`docs/README.md`\n\n**Building from source**:[CONTRIBUTING.md](/AuthPlane/authserver/blob/main/CONTRIBUTING.md).\n\nManage everything from a browser. The Admin UI is embedded in the same binary; every operation is also exposed via the [Admin REST API](/AuthPlane/authserver/blob/main/docs/reference/http-api.md).\n\n**Authserver is only half the story.** The MCP server on the other side still has to validate the tokens, expose the discovery endpoint, enforce scopes per tool, handle DPoP, and decode consent errors. The Authplane SDKs do all of that in **5 lines** of integration code — measured, CI-counted, in Python / TypeScript / Go alike. The full ladder (basic MCP server → calling another resource → DPoP + per-tool scopes → fronting a Broker upstream) sits between **5 and 30 lines** of auth-specific code per tier; see [ examples/](/AuthPlane/authserver/blob/main/examples) for the numbers under each tier's banner.\n\nEvery Authplane SDK provides the same baseline:\n\n- JWT validation against the authserver JWKS, with caching\n- Scope enforcement, per route or per tool\n- The Protected Resource Metadata document at\n`/.well-known/oauth-protected-resource/<mcp-path>`\n\n(RFC 9728, suffixed per the MCP spec) - DPoP proof verification (RFC 9449)\n- A full OAuth client — Client Credentials, RFC 8693 Token Exchange, Introspection, Revocation\n- Structured\n`ConsentRequiredError`\n\ndecoding for the upstream-provider Broker flow\n\nPick the language and the framework adapter that match the stack you're already on.\n\n| Language | Repo | Integration Adapters | Docs |\n|---|---|---|---|\nGo |\n|\n\n`go-sdk/mcp`\n\n)[README](https://github.com/authplane/go-sdk#readme)**TypeScript**[authplane/ts-sdk](https://github.com/authplane/ts-sdk)`@authplane/mcp`\n\n)✓ FastMCP (\n\n`@authplane/fastmcp`\n\n)[README](https://github.com/authplane/ts-sdk#readme)**Python**[authplane/python-sdk](https://github.com/authplane/python-sdk)`authplane-mcp`\n\n)✓ FastMCP (\n\n`authplane-fastmcp`\n\n)[README](https://github.com/authplane/python-sdk#readme)**Rust*** roadmap***C#*** roadmap***Java*** roadmap*Working examples wired against authserver live under [ examples/](/AuthPlane/authserver/blob/main/examples) — Python / TypeScript / Go, with four tiers each (basic MCP server, calling another resource, DPoP + per-tool scopes, MCP server fronting a Broker). Every example's\n\n`make verify`\n\nis exercised by `make docs-smoke`\n\nand the per-tier LOC budget is CI-enforced via `tools/loccount`\n\n.Integration walkthroughs: [Auth Client](/AuthPlane/authserver/blob/main/docs/guides/integrate/sdk-auth-client.md) · [Resource Server](/AuthPlane/authserver/blob/main/docs/guides/integrate/sdk-resource-server.md).\n\nFor advanced operations and deeper reference, the [ docs/](/AuthPlane/authserver/blob/main/docs) tree is organized by audience:\n\nGet started |\n|\n\n**Configuration**[Configuration Guide](/AuthPlane/authserver/blob/main/docs/guides/deploy/configuration.md)·[Schema Reference](/AuthPlane/authserver/blob/main/docs/reference/configuration.md)**API Reference**[HTTP API (all endpoints)](/AuthPlane/authserver/blob/main/docs/reference/http-api.md)·[CLI](/AuthPlane/authserver/blob/main/docs/reference/cli.md)·[Audit Events](/AuthPlane/authserver/blob/main/docs/reference/audit-events.md)·[Metrics](/AuthPlane/authserver/blob/main/docs/reference/metrics.md)**Security**[Threat Model](/AuthPlane/authserver/blob/main/docs/concepts/threat-model.md)·[Tokens and Claims](/AuthPlane/authserver/blob/main/docs/concepts/tokens-and-claims.md)·[Key Rotation](/AuthPlane/authserver/blob/main/docs/guides/operate/key-rotation.md)·[DPoP](/AuthPlane/authserver/blob/main/docs/concepts/dpop-and-proof-of-possession.md)**Deployment**[Docker Compose](/AuthPlane/authserver/blob/main/docs/guides/deploy/docker-compose.md)·[systemd](/AuthPlane/authserver/blob/main/docs/guides/deploy/systemd.md)·[Kubernetes](/AuthPlane/authserver/blob/main/docs/guides/deploy/kubernetes.md)**Guides**[Connect an MCP Server](/AuthPlane/authserver/blob/main/docs/guides/integrate/connect-mcp-server.md)·[Admin CLI & API](/AuthPlane/authserver/blob/main/docs/guides/operate/admin-cli.md)·[OIDC Federation](/AuthPlane/authserver/blob/main/docs/guides/federation/oidc.md)·[Observability](/AuthPlane/authserver/blob/main/docs/guides/deploy/observability-prometheus-otel.md)**Grant Types**[Client Credentials](/AuthPlane/authserver/blob/main/docs/guides/integrate/client-credentials-grant.md)·[Token Exchange](/AuthPlane/authserver/blob/main/docs/guides/upstream-providers/token-exchange-grant.md)·[JWT Bearer / XAA](/AuthPlane/authserver/blob/main/docs/guides/federation/jwt-bearer-grant.md)·[Enterprise-Managed Auth](/AuthPlane/authserver/blob/main/docs/guides/federation/enterprise-managed-auth-xaa.md)**Architecture**[Architecture Overview](/AuthPlane/authserver/blob/main/docs/concepts/architecture.md)·[Authentication Flows](/AuthPlane/authserver/blob/main/docs/reference/flows.md)·[RFC Compliance](/AuthPlane/authserver/blob/main/docs/reference/compliance.md)**Full Index**[Documentation Index](/AuthPlane/authserver/blob/main/docs/README.md)Authplane implements the MCP Authorization specification (2025-11-25) and the OAuth 2.1 ecosystem standards behind it. (\"OAuth 2.1\" is an active IETF Internet-Draft, not a finalized RFC — the MCP spec itself targets it. See [Compliance](/AuthPlane/authserver/blob/main/docs/reference/compliance.md) for the full picture.) Here's what each one gives you, in operator terms:\n\n| Standard | What it provides |\n|---|---|\nMCP Authorization 2025-11-25 |\nThe contract MCP clients and servers expect: discovery endpoints, dynamic client registration, audience-bound tokens. The reason your existing MCP tooling can find and talk to authserver without custom adapters. |\nOAuth 2.1 |\nThe base authorization flow — authorize endpoint, token endpoint, refresh tokens, scopes. PKCE-S256 is mandatory; the older insecure flows aren't supported. |\nPKCE (RFC 7636) |\nPrevents stolen authorization codes from being redeemed. Critical for public clients (CLIs, desktop apps, mobile). |\nDPoP (RFC 9449) |\nBinds tokens to a client-held key. A leaked token can't be replayed from another machine. |\nResource Indicators (RFC 8707) |\nAudience-binds every token to a specific resource URI. An access token for one MCP server can't be replayed against another. |\nProtected Resource Metadata (RFC 9728) |\nMCP servers advertise where their authorization server lives. Clients discover the AS automatically. |\nDynamic Client Registration (RFC 7591) |\nClients register themselves at runtime — needed for MCP clients you don't pre-provision. Three security modes: open, approved-redirects, admin-only. |\nClient ID Metadata Documents (CIMD) |\nAuto-registration by fetching client metadata from the client's URL. The MCP-native way for agents to identify themselves without a registration round-trip. |\nOAuth AS Metadata (RFC 8414) + OIDC Discovery |\nThe `/.well-known/oauth-authorization-server` and `/.well-known/openid-configuration` documents every OAuth client knows how to fetch. |\nToken Exchange (RFC 8693) |\nDelegated identity — one client mints a narrower or differently-scoped token from an existing one. Powers the agent-to-agent delegation chain and the upstream-provider Broker flow. |\nJWT Bearer (RFC 7523) |\nTrusted external IdPs assert identity directly into Authplane. The foundation for Cross-App Access (XAA) and enterprise federation. |\nJWT Access Tokens (RFC 9068) |\nDefault token format (`at+jwt` ). Every token is a self-contained JWT your resource servers can verify offline against the JWKS. |\nToken Introspection (RFC 7662) |\nRuntime token validation endpoint for revocation-aware verification. |\nToken Revocation (RFC 7009) |\nStandard endpoint to revoke refresh tokens and their families. |\n\nAuthplane is in active development. `v0.1.x`\n\nis production-shaped — the OAuth core, MCP discovery, and audit log are spec-compliant and tested. A few things to set expectations:\n\n**Rust, C#, and Java SDKs** are on the roadmap; Go, TypeScript, and Python are released.**Upstream-provider connections**(Broker flow) require manual configuration of at-rest encryption (`aes_master`\n\nor HashiCorp Vault Transit) before they activate — covered in.`docs/guides/upstream-providers/connecting-providers.md`\n\n**Multi-tenant isolation** today means running separate instances per tenant. A first-class tenant abstraction is post-`v1.0`\n\n.**Public dynamic-registration signup UI** is not in`v0.1`\n\n; Dynamic Client Registration works over HTTP today, a hosted signup page is a follow-up.**Helm chart (** is at`charts/authplane`\n\n)`v0.1.0`\n\n; tested for single-instance and basic HA, expect tuning for large fleets.\n\nIf something here blocks your deployment, open an issue — the priority list is informed by what you're trying to ship.\n\nAGPL-3.0-or-later — see [LICENSE](/AuthPlane/authserver/blob/main/LICENSE).\n\nWe'd love to hear from you — write to [hello@authplane.ai](mailto:hello@authplane.ai) and let's find one that fits.", "url": "https://wpnews.pro/news/show-hn-authplane-oauth-2-1-and-pkce-authorization-server-for-mcp", "canonical_source": "https://github.com/authplane/authserver", "published_at": "2026-06-17 17:42:39+00:00", "updated_at": "2026-06-17 17:53:03.774913+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-infrastructure"], "entities": ["AuthPlane", "Google", "Okta", "Azure AD", "Auth0", "PostgreSQL", "Prometheus", "Vault"], "alternates": {"html": "https://wpnews.pro/news/show-hn-authplane-oauth-2-1-and-pkce-authorization-server-for-mcp", "markdown": "https://wpnews.pro/news/show-hn-authplane-oauth-2-1-and-pkce-authorization-server-for-mcp.md", "text": "https://wpnews.pro/news/show-hn-authplane-oauth-2-1-and-pkce-authorization-server-for-mcp.txt", "jsonld": "https://wpnews.pro/news/show-hn-authplane-oauth-2-1-and-pkce-authorization-server-for-mcp.jsonld"}}