Skip to content
Start with Identity
Standard · stable

OAuth 2.0

RFC 6749 (+ RFC 6750)IETFRFC 6749 (2012); hardened by RFC 9700 Security BCP (2025)Official spec ↗

What it is

OAuth 2.0 (RFC 6749) is the authorization framework behind "Connect your account" buttons, API access for third-party apps, and most machine-to-machine API calls. It lets a user grant an application limited, scoped access to their resources at another service without sharing a password. OAuth is about authorization, not authentication: it answers "what may this app do," not "who is this user." Using an access token as proof of login is the classic OAuth mistake, which is what OpenID Connect exists to fix.

RFC 6749 was published in October 2012, edited by Dick Hardt, and obsoleted OAuth 1.0 (RFC 5849). Its companion RFC 6750 defines how bearer tokens are sent to APIs.

Status (November 2026)

Document What it is Status
RFC 6749 The framework: roles, grants, endpoints Proposed Standard (October 2012)
RFC 6750 Bearer token usage Proposed Standard
RFC 9700 OAuth 2.0 Security Best Current Practice, BCP 240 Published January 2025; updates RFC 6749, 6750 and 6819
OAuth 2.1 Consolidation into one document IETF draft -17 (31 October 2026)

The datatracker record for RFC 6749 lists three updating documents: RFC 8252 (native apps), RFC 8996 (deprecating TLS 1.0 and 1.1) and RFC 9700. In practice "OAuth 2.0" in 2026 means RFC 6749 as amended by RFC 9700. The 2012 text alone still permits patterns the working group now forbids.

The four roles and four grants

RFC 6749 defines four roles: the resource owner (usually the user), the client (the app), the authorization server (issues tokens) and the resource server (the API). It defines four grants:

Grant Use in 2026
Authorization code The default for anything with a user, always with PKCE
Client credentials Machine-to-machine, where the client acts as itself (client credentials)
Implicit Do not use. RFC 9700 says clients should not use it; OAuth 2.1 removes it
Resource owner password credentials Do not use. RFC 9700: it "MUST NOT be used"

Later RFCs add grants: the device authorization grant (RFC 8628) for TVs and CLIs, token exchange (RFC 8693), and JWT bearer assertions (RFC 7523).

How the authorization code flow works

Section 4.1 of RFC 6749, with the PKCE and RFC 9700 requirements folded in:

  1. The client creates a random code_verifier and derives code_challenge with S256.
  2. The client redirects the user's browser to the authorization endpoint with response_type=code, client_id, redirect_uri, scope, state and code_challenge.
  3. The authorization server authenticates the user and asks for consent to the requested scopes.
  4. The server redirects back to the exactly registered redirect_uri with an authorization code and state (and, per RFC 9207, an iss parameter that defends against mix-up attacks).
  5. The client checks state (and iss), then sends the code and code_verifier to the token endpoint, authenticating itself if confidential.
  6. The server verifies the code, the client and the PKCE verifier, then returns an access token and optionally a refresh token.
  7. The client calls the API with Authorization: Bearer <token>. The resource server validates the token locally (a JWT access token per RFC 9068) or via introspection (RFC 7662).

What RFC 9700 changed

RFC 9700, by Torsten Lodderstedt, John Bradley, Andrey Labunets and Daniel Fett, is the most important OAuth document since 2012. Its section 2 summary, in short:

  • Exact string matching of redirect URIs is a MUST, with one exception for the port of native-app localhost URIs.
  • PKCE is a MUST for public clients and RECOMMENDED for confidential clients. Authorization servers must support it and must prevent PKCE downgrade. Only S256 qualifies as a method that does not expose the verifier.
  • No open redirectors, at the client or the authorization server.
  • CSRF protection is a MUST, via PKCE, or state / nonce where PKCE is not supported.
  • Mix-up defense is a MUST for clients that talk to more than one authorization server.
  • Sender-constrained access tokens SHOULD be used, via mutual TLS (RFC 8705) or DPoP (RFC 9449). Public-client refresh tokens MUST be sender-constrained or rotated.
  • Least privilege and audience restriction for access tokens, for example with resource indicators (RFC 8707).
  • Asymmetric client authentication (such as private_key_jwt or mTLS) is RECOMMENDED, and authorization server metadata (RFC 8414) publication is RECOMMENDED.

Common implementation mistakes and attacks

RFC 9700 section 4 catalogs 17 attack classes. The ones that recur in our breach and CVE catalogs:

Attack Mechanism In our catalog
Stolen token replay Bearer tokens work for whoever holds them Stolen OAuth tokens for Heroku and Travis CI (2022), Salesloft Drift (2025) and Gainsight apps; technique refresh token abuse
Consent phishing User is tricked into granting a malicious app real scopes Cyberhaven Chrome extension; technique OAuth consent phishing
Device code phishing Attacker starts a device flow and sends the user the code Technique device code phishing
Assertion audience ambiguity A private_key_jwt assertion is accepted by the wrong server CVE-2025-27371
Token mix-ups in client libraries Tokens for one user or resource returned for another CVE-2025-26620 (Duende)
Authorization server policy bugs Scope or client policy not enforced CVE-2025-14778 and CVE-2026-18207 (Keycloak), CVE-2025-12466 (Drupal Simple OAuth)
Proxy route matching Unauthenticated paths match more than intended CVE-2025-54576 (OAuth2-Proxy)
Scope creep in delegation Downstream calls get more authority than the user granted Technique scope escalation through delegation

The common thread in the breach rows is that the attackers held valid tokens. Nothing in the protocol failed: a bearer token works for whoever presents it. Sender-constraining, short lifetimes, narrow scopes, rotation and per-app monitoring are the controls that limit what a stolen token is worth.

OAuth 2.1 (consolidation), OpenID Connect (authentication), FAPI 2.0 (high-security profile), MCP authorization (OAuth for AI agents), OAuth Transaction Tokens (internal call chains), ID-JAG (enterprise-brokered cross-app access) and WIMSE (workload-to-workload authentication). Glossary: PAR (RFC 9126), rich authorization requests (RFC 9396), protected resource metadata (RFC 9728), dynamic client registration (RFC 7591).

Who implements it

Every OpenID Provider is also an OAuth 2.0 authorization server, so the OpenID Foundation's certified implementations list is a reasonable starting point; see OpenID Connect for the names we checked. Authorization servers come from workforce IAM (IAM vendors), CIAM platforms (CIAM vendors) and open source projects such as Keycloak and ZITADEL. When evaluating one, ask specifically about PKCE enforcement for every client type, exact redirect matching, DPoP or mTLS token binding, refresh token rotation with reuse detection, and RFC 9207 iss in responses.

How to check an implementation

  1. Request response_type=token. The server should refuse it for new clients.
  2. Send a code request without code_challenge from a public client. It must fail.
  3. Register https://app.example.com/cb and request https://app.example.com/cb/x. Rejected.
  4. Redeem the same authorization code twice. The second attempt fails, and ideally revokes tokens issued from the first.
  5. Replay a rotated refresh token. It fails and revokes the token family.
  6. Send a token in ?access_token= to your API. Refuse it.

How it works, message by message

The OAuth message-flow walkthrough annotates every request and response: authorization, code exchange, client credentials, refresh with rotation, the API call, JWT access token validation under RFC 9068, introspection and DPoP proofs, with the OAuth 2.0 and OAuth 2.1 section numbers side by side.

Glossary: OAuth, authorization server, scopes and claims, token theft. Guides: OAuth vs OIDC and the implementation guide.

Who wrote it

RFC 6749 was edited by Dick Hardt. The security guidance that hardened it since is largely the work of Torsten Lodderstedt and Daniel Fett, and Aaron Parecki maintains the documentation most developers learn it from. Hannes Tschofenig co-chaired the IETF working group that produced it. More in the experts directory.

OAuth 2.0: frequently asked questions

What is OAuth 2.0?
OAuth 2.0 is the IETF authorization framework defined in RFC 6749 (October 2012). It lets a user grant an application limited, scoped access to their resources at another service, such as a calendar or a CRM, without giving the application their password. The application receives an access token from an authorization server and presents it to the API.
Is OAuth 2.0 still secure to use in 2026?
Yes, if you follow RFC 9700, the OAuth 2.0 Security Best Current Practice published in January 2025 as BCP 240. It updates RFC 6749, RFC 6750 and RFC 6819, requires exact redirect URI matching and PKCE for public clients, forbids the resource owner password credentials grant, and says the implicit grant should not be used. Deployments built to the original 2012 text alone are not secure by current standards.
What is the difference between OAuth 2.0 and OAuth 2.1?
OAuth 2.1 is an IETF draft (draft-ietf-oauth-v2-1, revision -17 on 31 October 2026) that consolidates RFC 6749, RFC 6750, PKCE, native and browser app guidance and RFC 9700 into one document. It requires PKCE for every authorization code flow and drops the implicit and password grants. If approved it obsoletes RFC 6749 and RFC 6750.
Is OAuth 2.0 authentication?
No. OAuth 2.0 answers what an app may do, not who the user is. An access token is not proof of login, and its audience is an API, not your app. Use OpenID Connect, which adds a signed ID token on top of OAuth, when you need to authenticate a user.
What is a sender-constrained token?
A token bound to a key the client holds, so a stolen copy is useless without that key. The two IETF mechanisms are mutual TLS certificate-bound tokens (RFC 8705) and DPoP (RFC 9449). RFC 9700 says authorization and resource servers should use one of them, and that refresh tokens for public clients must be sender-constrained or rotated.
Last reviewed By SWI Community TeamSuggest a correctionHow we research
Independent, community-driven reference. Always confirm details against the official specification linked above.