OAuth 2.1: A Practical Guide to the Next Step in Delegated Authorization
by Sanona Admin · 05. September 2026
OAuth 2.0 has quietly powered "Sign in with..." buttons and API access flows across the web since 2012. But in that time, the base specification (RFC 6749) stayed frozen while the security community kept patching it with a growing pile of side documents: PKCE, the Security Best Current Practice (BCP), guidance for native apps, and guidance for browser-based apps. Developers were left to track down and combine all of these separately to build something actually secure.
OAuth 2.1 is the IETF's answer to that sprawl. Rather than a redesign, it is a consolidation effort that folds the accumulated best practices into a single, cleaner specification, removes the flows that have proven dangerous in practice, and gives implementers one document to follow instead of five.
Why Consolidate Now
The OAuth Working Group's current draft, draft-ietf-oauth-v2-1-13, frames the problem plainly: OAuth 2.0's core mechanics were fine, but years of real-world deployment exposed weaknesses that later RFCs patched piecemeal. OAuth 2.1 "consolidates the information in all of these documents and removes features that have been found to be insecure" in the OAuth Security BCP (RFC 9700). It is intended as a Standards Track specification that will formally replace and obsolete RFC 6749 (the core framework) and RFC 6750 (bearer token usage) once finalized.
As of the latest draft, published in May 2025 by authors Dick Hardt, Aaron Parecki, and Torsten Lodderstedt, the document is still an Internet-Draft, expiring periodically and subject to revision. It has not yet been published as a final RFC, but its content is already stable enough that major identity providers and libraries are aligning their implementations with it ahead of ratification.
What Changed From OAuth 2.0
The changes are best understood as a set of removals and tightenings rather than new features. According to the official oauth.net summary, the major differences are:
PKCE (Proof Key for Code Exchange) is now required for every client using the authorization code flow, not just public or mobile clients.
Redirect URIs must be validated with exact string matching; no wildcards or partial matches are permitted.
The Implicit grant (
response_type=token) has been removed entirely from the specification.The Resource Owner Password Credentials (ROPC) grant has been removed entirely.
Bearer tokens must no longer be passed in the query string of a URI.
Refresh tokens issued to public clients must either be sender-constrained or rotated on each use.
The definitions of "public" and "confidential" clients have been simplified to depend solely on whether the client holds credentials, rather than on deployment context.
PKCE Becomes Mandatory Everywhere
PKCE was originally designed to protect native and mobile apps from authorization code interception. Under OAuth 2.1, every client — including traditional server-side confidential clients — must use it. The flow is simple: the client generates a random code_verifier, derives a code_challenge from it (typically via SHA-256), and sends the challenge with the initial authorization request. When exchanging the authorization code for a token, the client must present the original verifier, and the authorization server checks that it matches. This ties the eventual token issuance to the same client instance that started the flow, closing off a class of interception attacks that plagued OAuth 2.0 deployments.
The Implicit Flow Is Gone
The implicit flow returned access tokens directly in the URL fragment, skipping the authorization code exchange step. It was convenient for early single-page apps, but it also meant tokens could leak into browser history, referrer headers, and server logs. With modern browsers offering solid CORS and fetch() support, there is no longer a technical reason to avoid the authorization code flow, so OAuth 2.1 drops implicit grant support altogether. SPAs are now expected to use authorization code plus PKCE, the same as any other client.
Password Grant (ROPC) Is Deprecated
The Resource Owner Password Credentials grant let an application collect a user's username and password directly and exchange them for a token. It reintroduced exactly the problem OAuth was designed to eliminate: applications handling raw user credentials. This grant type has long been discouraged in practice and is now formally excluded from the spec. The recommended replacements are the Device Authorization Flow for headless or input-constrained devices, and Authorization Code plus PKCE for anything with a browser.
Exact-Match Redirect URIs
Under OAuth 2.0, some implementations tolerated wildcard or prefix-matched redirect URIs, which opened the door to open-redirect attacks and misrouted authorization codes or tokens. OAuth 2.1 requires that the registered redirect URI and the one presented in the authorization request match exactly, character for character. The IETF draft goes further, requiring the full URI — including its path — to be pre-registered, with a narrow exception for loopback interface redirects on native apps, where only the port number is allowed to vary.
Refresh Tokens: Rotation or Binding
Refresh tokens for public clients (like SPAs or mobile apps that cannot securely hold a client secret) must now be protected in one of two ways: sender-constraining them to a specific client instance (via mechanisms like DPoP or mutual TLS), or rotating them on every use, so each refresh issues both a new access token and a brand-new refresh token while invalidating the old one. If a rotated refresh token is ever replayed, the authorization server can detect the reuse and revoke the session. This closes a gap where a leaked long-lived refresh token could otherwise be used indefinitely.
Bearer Tokens Remain, But With Guardrails
OAuth 2.1 does not deprecate bearer tokens, the plain "possession equals access" tokens that make up the bulk of real-world OAuth deployments today. What changes is the handling around them. The framework explicitly states that access tokens must be kept confidential in transit and storage, that authorization servers must ensure tokens cannot be guessed or forged, and that bearer tokens must no longer travel in URI query strings, where they are prone to leaking through logs and browser history. The spec also formally acknowledges sender-constrained tokens — via DPoP (Demonstration of Proof-of-Possession) or mutual TLS — as stronger alternatives for high-risk use cases such as financial or healthcare APIs, without making them mandatory for every deployment.
OAuth 2.0 vs. OAuth 2.1 at a Glance
Aspect | OAuth 2.0 | OAuth 2.1 |
|---|---|---|
PKCE | Optional, recommended for public clients | Mandatory for all clients |
Implicit flow | Supported ( | Removed |
Password grant (ROPC) | Allowed but discouraged | Removed |
Redirect URI matching | Loose matching, wildcards common | Exact string match required |
Refresh tokens (public clients) | Implementation-specific, often unrestricted | Must be rotated or sender-constrained |
Bearer tokens in URLs | Permitted in some implementations | Explicitly disallowed |
Client type definitions | Varied by deployment context | Simplified: based only on whether credentials exist |
Spec structure | Core RFC plus many separate BCPs and extensions | Single consolidated specification |
What Stays the Same
It's worth stressing that OAuth 2.1 is not a break with OAuth 2.0's core model. The four roles — resource owner, client, authorization server, resource server — are unchanged, and the fundamental protocol flow of requesting a grant, exchanging it for a token, and presenting that token to a resource server remains intact. The three grant types the draft explicitly defines are authorization code, refresh token, and client credentials, plus an extensibility mechanism for others. Scopes, access token abstractions, and the separation between authentication (which OAuth deliberately does not handle — that's OpenID Connect's job) and authorization are all preserved from OAuth 2.0.
The specification also leaves some operational details, such as client registration mechanics, authorization server metadata discovery, and token introspection, to companion documents like RFC 8414, RFC 7591, and RFC 7662, rather than folding every extension into the core text.
Migrating an Existing Implementation
For teams running OAuth 2.0 today, moving toward 2.1 compliance is realistically a checklist rather than a rewrite:
Add PKCE to every client type, including confidential server-side apps, and stop accepting
code_challenge_method=plainunless a legacy client truly requires it.Remove any code paths still using the implicit grant (
response_type=token) and migrate SPAs to authorization code plus PKCE.Retire the password grant in favor of authorization code flows or the device flow for non-browser clients.
Switch redirect URI validation to exact string matching and pre-register full URIs, including paths.
Implement refresh token rotation for public clients, with reuse detection that revokes the whole token family if an old refresh token is replayed.
Store tokens only in secure, HTTP-only cookies or memory — never in
localStorage, which is exposed to XSS.Narrow token scopes to the minimum needed and keep access token lifetimes short.
Evaluate DPoP or mutual TLS for sensitive services where bearer-token theft would be especially damaging.
Where This Leaves Implementers
Because OAuth 2.1 is still a draft, it isn't something you "switch on" — there's no version flag in most SDKs. In practice, it functions as a checklist of security-hardening measures that any serious OAuth deployment should already be pursuing, whether or not the surrounding library or identity provider has explicitly branded itself as "2.1 compliant." Given that major identity platforms are already converging on these defaults, treating the draft as the de facto target for new implementations — PKCE everywhere, no implicit flow, exact redirect matching, rotated or bound refresh tokens — is a reasonable and low-risk way to future-proof an authorization setup ahead of formal ratification