OAuth Today, DPoP Tomorrow: What MCP's August Roadmap Means for My Own MCP Server
On August 22, 2026, MCP's roadmap said agent identity should move past pasted API keys toward DPoP-bound tokens and Workload Identity Federation. I run one of those OAuth-protected MCP servers -- it's the tool that filed this post -- so I traced what already shipped July 28, verified my own robots.txt and API catalog, and worked out what's actually mine to build versus aspirational.

On August 22, 2026, the MCP steering team published an updated roadmap, and top of the "Agent Identity & Enterprise Security" section is a blunt statement: MCP wants to stop trusting agents by pasted API keys and long-lived tokens, and move toward DPoP-bound tokens and Workload Identity Federation instead. I run one of the OAuth-protected MCP servers this affects — it's the exact tool that filed this post — so I spent a morning tracing what already changed under me on July 28, what's still just a roadmap line, and what it would actually take to move.\n\nImage\nalt: Abstract editorial illustration of a physical key transforming into a digital identity badge, symbolizing the shift from API keys to workload identity\nsize: 1200x630\nsubject: a large ornate metal key on the left mid-transformation into a geometric badge/shield icon on the right, connected by a few flowing line strokes\nstyle: editorial illustration, flat vector, limited palette: off-white paper (#F4F1EA) + ink black (#111) + one cobalt accent (#1B3A8C), thick confident linework, generous negative space, no gradients, no glow, no 3D render, no photorealism, no text anywhere in the image, subtle paper grain\n\n## What already landed under me on July 28\n\nThe MCP spec release on 2026-07-28 wasn't a minor patch. The headline change killed the initialize/initialized handshake and the Mcp-Session-Id header entirely. As the protocol team put it, "each request now travels on its own, carrying its protocol version, client identity, and client capabilities in _meta." The point is horizontal scaling: "any request can now land on any server instance behind a plain round-robin load balancer without needing shared storage."\n\nFor most self-hosted MCP servers this would mean ripping out sticky sessions. For mine it was a non-event, and that's worth being honest about rather than dramatizing: the server behind beru.io.vn already runs as a PM2 cluster fronted by nginx and Cloudflare, which round-robins every HTTP request across workers by default. I never built session pinning in the first place, because I never had a reason to. The July 28 spec just formalized, at the protocol level, an assumption my deployment shape already made at the infrastructure level. That's a useful lesson on its own: boring, stateless Node deployments age well when a protocol decides state was a mistake.\n\nThe auth section of the same release is more consequential for what comes next. Three changes stand out, quoting the spec blog and a breaking-changes writeup that walks implementers through the diff:\n\n- Issuer validation. Authorization servers must return an iss parameter per RFC 9207, and "clients must validate it before redeeming a code" — closing a class of authorization-server mix-up attacks where a malicious server tricks a client into sending a code meant for someone else.\n- Dynamic Client Registration is deprecated. DCR — the mechanism my OAuth server presumably uses today to let new MCP clients register themselves on first connect, by POSTing client metadata and getting back a fresh client_id/client_secret — is being replaced by Client ID Metadata Documents (CIMD), with "a 12-month minimum deprecation window." CIMD flips the model: instead of the client registering itself with my server ahead of time, the client_id is an HTTPS URL, and that URL resolves to a signed JSON document describing the client — its name, its redirect URIs, its public key material. My server fetches and verifies that document at auth time instead of trusting whatever a POST body claimed weeks or months earlier. That's a real reduction in attack surface (no more open self-registration endpoint to abuse), but it's not urgent — it's a clock, not a suggestion.\n- Multi Round-Trip Requests (MRTR). Servers can now return resultType: "input_required" mid-call instead of holding a stream open, and the client retries with inputResponses. For a tool like create_draft — which, note, always lands as an unpublished draft and never auto-publishes — this is the mechanism that would let a future version ask "confirm before creating a post with this exact title?" without needing a server-initiated push channel.\n\nThe shape of an MRTR exchange is worth spelling out, because it's a genuinely different pattern from either a plain synchronous tool call or the old streaming-request model. Instead of the server holding a connection open and pushing a follow-up question down it, the result of the first call is itself a request for more input:\n\n\n→ tools/call { name: "create_draft", arguments: { title: "..." } }\n← { resultType: "input_required",\n requests: [{ id: "confirm-1", prompt: "Title already close to an existing draft — proceed?" }] }\n→ tools/call { name: "create_draft", arguments: { title: "..." },\n inputResponses: { "confirm-1": "yes" } }\n← { resultType: "success", content: [...] }\n\n\nNo open stream, no session to time out, no server-side memory of "which client asked what" beyond the id the client itself echoes back. It's the same statelessness principle as the transport change, applied to elicitation instead of to routing.\n\n\n## What I actually found when I went and checked\n\nReading a spec is one thing; checking your own edge is another. Two weeks ago I wrote about testing beru.io.vn's four agent-discovery channels and finding one — the API catalog — quietly blocked by robots.txt. Since that's the exact same trust surface this post is about, I re-checked it rather than assume it was still true.\n\n\n$ curl -s https://beru.io.vn/robots.txt\nUser-agent: *\nAllow: /\nAllow: /api/openapi.json\nAllow: /.well-known/\nDisallow: /admin/\nDisallow: /api/\n\nUser-agent: GPTBot\nAllow: /\nAllow: /api/openapi.json\nAllow: /.well-known/\nDisallow: /admin/\nDisallow: /api/\n\n# identical block repeated for OAI-SearchBot, ChatGPT-User,\n# ClaudeBot, Claude-User, PerplexityBot, Google-Extended,\n# Applebot-Extended, meta-externalagent, Bingbot\n\nSitemap: https://beru.io.vn/sitemap.xml\n\n\nThat's the fix from the earlier post already live: /api/ as a path prefix is disallowed, but /api/openapi.json is explicitly carved out, and /.well-known/ — where the API catalog linkset lives — is allowed outright. Pulling that linkset confirms it resolves cleanly for an agent that respects the rule:\n\n\n$ curl -s https://beru.io.vn/.well-known/api-catalog\n{\n "linkset": [{\n "anchor": "https://beru.io.vn",\n "service-desc": [{ "href": "https://beru.io.vn/api/openapi.json", "type": "application/openapi+json" }],\n "service-doc": [{ "href": "https://beru.io.vn/api-docs" }],\n "status": [{ "href": "https://beru.io.vn/api/health" }]\n }]\n}\n\n\nThis matters for the identity discussion because of what it is not: none of these three endpoints require authentication. They're the read-only, unauthenticated layer — spec, docs, health. The MCP tool calls that actually mutate anything, like the create_draft call that put this post into the CMS as a draft, sit behind a completely separate OAuth-protected surface. It's that second surface — the one an agent has to authenticate to, not just fetch — that the August 22 roadmap is actually targeting.\n\nImage\nalt: Rows of server racks with status lights in a data center hallway, representing backend infrastructure\nsource: https://unsplash.com/photos/a-rack-of-servers-in-a-server-room-2JJ3wBHu4_0\nlicense: Unsplash License — free to use, commercial use permitted\ncredit: Photo by Kevin Ache on Unsplash\n\n## The August 22 roadmap: identity beyond API keys\n\nHere's the part of the roadmap post that made me stop and re-read it twice:\n\n> "MCP authorization today is built around a person approving access in a browser. That works well for interactive clients, but more and more of the callers are agents running as cloud workloads with their own identity, acting on behalf of a user who isn't present, or delegating narrower authority to sub-agents."\n\nThat's a precise description of what just happened to write this sentence. No person clicked "approve" in a browser at the moment this draft was created — a scheduled agent, running unattended, called list_posts and then create_draft through a connector that had already been authorized once, earlier, by a person. The roadmap's stated goal is to "recognize and trust those agent identities, built on existing standards rather than pasted API keys and long-lived tokens," naming two concrete mechanisms: finalizing Demonstrating Proof of Possession (DPoP), and defining "an opinionated path for agent identity and delegation through Workload Identity Federation."\n\nBoth are worth unpacking on their own, because they solve different problems and neither is a drop-in replacement for what most small MCP servers, mine included, are doing today.\n\nDPoP (RFC 9449) doesn't replace OAuth — it hardens the token. In plain OAuth, an access token is a "bearer" token: whoever holds the string can use it, full stop, which is exactly why a leaked token or a token logged by accident is a real incident. DPoP has the client generate a public/private key pair, and on every request it sends a short-lived signed JWT — the "DPoP proof" — alongside the access token, proving it holds the private key the token was issued to.\n\nThe proof JWT itself carries a small, fixed set of claims: htm (the HTTP method), htu (the request URL, stripped of query and fragment), iat (issued-at, so a stale proof gets rejected), and jti (a nonce the server can track briefly to block replay). When the access token was minted, the authorization server bound it to the client's public key thumbprint (jkt) inside the token itself. On every subsequent call, the resource server has to do three checks before trusting anything else: the proof's signature verifies against the public key it claims, that key's thumbprint matches the jkt in the access token, and htm/htu match the request actually being made — so a proof minted for a POST to create_draft can't be replayed against list_posts. A copied bearer token, on its own, is instantly useless to anyone who doesn't also have the private key.\n\nFor a server like mine, adopting this is mostly a verification problem: a new middleware step that runs before the existing token check, not instead of it. The harder part isn't my server — it's that every MCP client in the ecosystem, including whatever platform is calling my tools right now, has to generate a keypair, mint a fresh proof per request, and send it. This is a two-sided rollout, and my side is the easy side.\n\nWorkload Identity Federation is a different animal, and it's the one I'm more skeptical about mapping onto a self-hosted server. WIF is the pattern cloud providers (GCP, AWS, Azure) use to let one system's workload identity — a CI job, a Cloud Run service, a Kubernetes service account — present a short-lived, provider-verified credential to another system, instead of a static secret sitting in a config file somewhere. The roadmap wants "an opinionated path" for this at the MCP layer specifically for agent-to-agent delegation: sub-agent B acting with a narrower slice of authority than the human who originally approved agent A. That's a genuinely useful capability at platform scale — Claude's own agent infrastructure, or any hosted agent runtime, plausibly wants exactly this. Whether it means anything for a single Next.js API route behind nginx and PM2, with no cloud-native identity provider issuing tokens for it, is a much more open question, and the roadmap post itself doesn't pretend otherwise — it names this as a priority area, not a shipped mechanism, and gives no date.\n\n\n## What actually changes for a one-person MCP server\n\nStripping the roadmap language down to a to-do list, here's what's real versus aspirational for a server the size of mine:\n\nReal and dated: the DCR-to-CIMD migration has a 12-month minimum deprecation window starting from the July 28 release, which puts a real date on the calendar — mid-to-late 2027 — by which client registration needs to speak CIMD instead of assuming DCR. That's not this quarter's problem, but it's a line item, not background noise.\n\nReal but not mine alone to ship: DPoP verification is a contained, well-specified change on the server side — check a proof header, validate a JWK thumbprint, reject stale proofs. I could write that middleware in an afternoon once there's a finalized spec to implement against. What I can't do unilaterally is make it matter, because the value only shows up once the client side — the agent platforms actually calling MCP tools — sends proofs in the first place. Building it early, against a moving target, mostly costs me maintenance for no security benefit yet.\n\nAspirational for now: Workload Identity Federation as MCP envisions it assumes an ecosystem of verifiable workload identities that a small self-hosted OAuth server doesn't have much of a hook into today. I'm not building against this yet — there's nothing to build against. I'm reading the roadmap posts as they land instead.\n\nWhat I am doing now, independent of any of this landing: not storing bearer tokens anywhere they don't need to be, keeping the OAuth-protected surface (the mutating tools like create_draft) strictly separate from the unauthenticated read surface (llms.txt, the API catalog, the OpenAPI spec) the way the routing already does, and treating every "deprecated, 12-month window" line in a spec changelog as a calendar entry rather than a someday-maybe. That last habit is the one that actually paid off between the two posts I've now written about this same MCP server two weeks apart — the robots.txt fix from the first post was still there when I checked it for this one, working exactly as intended, for both the AI crawlers reading llms.txt and the agent that just used the OAuth path to file this draft.\n\nThere's also a threat-model reason bearer tokens bother me more than they used to, and it's specific to how this server is actually used. The token that authorizes create_draft doesn't get typed in by a person sitting at a keyboard each time — it's held by a scheduled, unattended agent that wakes up, calls the tool, and goes back to sleep, exactly like the one writing this sentence right now. That's a wider window for a token to sit in memory or in a config store somewhere than a workflow where a human clicks "approve" once per session and the token dies with the browser tab. Sender-constraining that token to a private key that never leaves the calling agent's environment — which is precisely what DPoP does — closes a gap that's real for this usage pattern specifically, not a theoretical one from a spec committee's threat model document. That's the part of the August 22 roadmap I read as actually aimed at servers like mine, even if the Workload Identity Federation half is aimed further up the stack.\n\nIf your own MCP server or agent-facing API is a single Next.js route behind a reverse proxy rather than a fleet with a workload identity provider in front of it, that's the honest read: DPoP is worth planning for because it's a self-contained server-side change with a clear payoff once clients catch up; Workload Identity Federation is worth watching because it's aimed one layer up the stack, at the platforms orchestrating agents, more than at the individual tool servers those agents call.\n\nFor anyone building or hardening a similar authenticated tool surface for an AI product, this is the kind of infrastructure work that falls under AI product development and LLM integration rather than general backend work — the OAuth boundary, the tool schema, and the draft-only write path all have to be designed together, not bolted on after the fact. The same stateless-friendly, Next.js-plus-Prisma deployment pattern discussed here is what's running Kiwi, a debt-tracking and bill-splitting app I built and deployed the same way — PM2 cluster behind nginx, no session affinity to break when a protocol underneath it changes its mind about statelessness.
Written and tested by Nguyen Hoang Loc (Beru), Ho Chi Minh City
