OAuth 2.1

OAuth 2.1 is the Internet Engineering Task Force (IETF) authorization framework that lets a user grant an application limited, revocable access to their resources at another service without handing over their credentials, and the delegation model behind most modern APIs and, through OpenID Connect, most web sign-in. It consolidates OAuth 2.0 and the security practices learned since into one specification, removing the flows that proved unsafe; it is still an Internet-Draft, but its rules can already be applied to OAuth 2.0 deployments today.

Four Roles and One Flow

OAuth separates four parties. The resource owner is usually a person. The client is the application acting for them. The authorization server authenticates the person, asks for consent and issues tokens, and the resource server is the API that accepts those tokens. Keeping the authorization server apart from every API is the point of the design: users type their password in one place, and an API never sees it.

In OAuth 2.1 a user-facing client obtains its tokens one way, through the authorization code grant. The client sends the browser to the authorization server with the scopes it wants and a Proof Key for Code Exchange (PKCE) challenge, the hash of a random secret it keeps. The user signs in and approves, and the browser returns to a registered redirect URI carrying a short-lived code. The client then trades that code for tokens in a direct call to the authorization server and proves, by presenting the original secret, that it started the request. PKCE makes a code stolen from a redirect worthless to anyone else.

End userApplicationAuthorization serverAPIDirectory usesauthenticates authorization requestaccess tokenthe same tokenattributes
OAuth 2.1 covers three hops: the request, the token that answers it, and that same token presented to an API, and not the hop where the user authenticated.

The other grants have no user in them. The client credentials grant is for a service calling an API on its own account, and the refresh token grant renews access without sending the user back through the login. Everything else is an extension, such as the device authorization grant for televisions and command-line tools, or Client-Initiated Backchannel Authentication (CIBA) for approval on a separate device.

OAuth says nothing about how the user authenticated or who they are. An access token tells an API what the client may do, not which person is present, and treating one as a login is a known way to let one application impersonate a user at another. Sign-in is the job of OpenID Connect, which adds the ID Token on top of this same flow and is what single sign-on is built on.

Public and Confidential Clients

A confidential client runs on a server and can hold a credential that users never see. A public client cannot: a single-page application ships its code to every browser, and a mobile app can be unpacked. OAuth 2.1 requires PKCE of both, with a narrow exception for confidential clients that protect the code another way. Only a confidential client authenticates to the authorization server, and the Security Best Current Practice recommends asymmetric methods for that, a signed JSON Web Token (JWT) or mutual TLS, over a shared secret that ends up copied into configuration files.

Browser applications are the hard case, because any token the page holds can be read by script injected into it. The IETF guidance for browser-based applications therefore recommends a backend-for-frontend: a small server component that is the confidential client, keeps the tokens, and gives the browser only a session cookie. Teams that choose a pure browser client accept that tokens live in the page and have to keep them short-lived.

Access Tokens and Refresh Tokens

An access token is short-lived and is sent with every API call. OAuth does not define its format; it may be an opaque reference the API looks up at the authorization server, or a signed JWT the API validates itself. Most access tokens are bearer tokens, so whoever holds one can use it until it expires. The API has to check the audience, which names the API the token was issued for, so that a token issued for one API cannot be replayed at another.

A refresh token lives longer and goes only to the authorization server. It is the more valuable credential, which is why OAuth 2.1 constrains it for public clients: it must either be bound to a key the client holds, as with Demonstrating Proof of Possession (DPoP), or be rotated on every use, so that a stolen copy is detected the moment both the thief and the legitimate client try to use it. For an organization the practical levers are token lifetimes, which set how long a leaked token is useful, and revocation, which only works for tokens the API checks back at the authorization server. A self-contained JWT stays valid until it expires however quickly the account is disabled, and the Shared Signals Framework exists partly to close that gap.

Moving From OAuth 2.0

OAuth 2.1 adds no new protocol. It rewrites OAuth 2.0 (RFC 6749 and RFC 6750) with the native-app guidance of RFC 8252 and the Security Best Current Practice (RFC 9700) folded in. It is still an Internet-Draft (draft 16, September 2026), but nothing on the wire says "2.1": a deployment that follows RFC 9700 already behaves as 2.1 describes, and the specification can be treated as the checklist for OAuth 2.0 today. The differences are few:

  • PKCE is required for the authorization code grant.
  • The implicit grant and the Resource Owner Password Credentials grant are removed.
  • Redirect URIs are compared by exact string match, with only the port allowed to vary for native apps on the loopback interface.
  • Bearer tokens may no longer be sent in a URL query string.
  • Refresh tokens for public clients are sender-constrained or single-use.

Migration is an inventory exercise at the authorization server, where each client's registration shows which grants it may use. Single-page applications on the implicit grant move to the authorization code grant with PKCE, ideally behind a backend-for-frontend. The password grant hides in legacy mobile apps, scripts and test tooling, and gives way to the authorization code flow where a user is present, client credentials where none is, and the device grant where there is no browser. Wildcard redirect URIs are registered in full, and PKCE is switched on per client and enforced once every client sends it. The result is evidence an auditor can read off the configuration: which clients exist, which grants each may use and how each authenticates.

When the Client Is Not Known in Advance

OAuth expects every client to be registered before it runs: a developer knows which authorization server protects the API, obtains a client ID there, and the authorization server's list of registered clients is what an organization reviews, audits and migrates. AI agents break that expectation: an agent reaches tool servers it discovers at runtime, has no client ID at their authorization servers, and may call dozens of them in one task. Model Context Protocol (MCP) builds on three OAuth extensions to close the gap. Each server publishes Protected Resource Metadata (RFC 9728) naming its authorization server, which the client finds from the server's first 401 response. The client names the server a token is for with a resource indicator (RFC 8707), so a token valid at one server is refused at the next. In place of registration, MCP recommends that the client use a URL as its client ID, from which the authorization server fetches the Client ID Metadata Document at that URL, an OAuth Working Group draft, to learn the client's name and redirect URIs. MCP's revision 2026-07-28 prefers this to Dynamic Client Registration (RFC 7591), which it keeps only for backward compatibility.

For the owner of the authorization server the client population stops being closed, and the review that registration used to force moves into policy: which client ID domains are accepted, what the consent screen shows so that a user can tell a genuine agent from a lookalike, and how long a consent lasts when an agent holding a refresh token keeps acting after the user has left. Whether the agent acts as the user or on the user's behalf is a distinction OAuth leaves to token exchange.

What OAuth Leaves to Other Specifications

OAuth 2.1 decides who gets a token, and the specifications around it decide what the token is worth after issuance. Step Up Authentication Challenge lets an API reject a token because the login behind it was too weak and send the client back for a stronger one. DPoP binds tokens to a client key so that a stolen token cannot be replayed. Token Exchange and Identity Chaining carry the user's identity, and an agent's beside it, when one service calls the next, which a bearer token passed along unchanged does badly. CIBA obtains an approval from a user who is not at the client's screen, which is how an agent asks before an irreversible action. Scopes stay coarse, so the decision about a specific record or amount at request time belongs to a policy decision point, which OpenID AuthZEN standardizes the interface to. GNAP addresses several of these gaps in one protocol, at the price of not being wire-compatible with OAuth.

For an organization the consequence is that OAuth 2.1 is the baseline every new integration should meet, and the extensions are chosen per risk: sender-constrained tokens where theft matters, step-up where one transaction needs more assurance than the login provided, token exchange wherever a request crosses more than one service, and, once agents are among the clients, a written policy on which unregistered clients the authorization server accepts.