Back to playground

OAuth 2.0 Introduction

OAuth 2.0 is an authorization framework that lets an application obtain limited access to a user's account on another service — without exposing the user's credentials to that application.

What problem OAuth 2.0 solves

Before OAuth, the common pattern for third-party access was credential sharing: a user gave their username and password directly to the third-party application. The application then used those credentials to act on the user's behalf. This was fragile — revocation meant changing the password everywhere, and the third party had full access rather than limited, purposeful access.

OAuth 2.0 (defined in RFC 6749) replaces that pattern with a delegation model: the user grants a specific application a specific scope of access, and the authorization server issues a short-lived token. The application never sees the user's credentials.

The four roles

OAuth 2.0 defines four roles that participate in every flow:

Resource owner
The user (or system) that owns the data and can grant access to it.
Client
The application requesting access on behalf of the resource owner. The client is identified by a client ID registered with the authorization server.
Authorization server
The server that authenticates the resource owner and issues tokens — for example, Keycloak, Auth0, or Google's authorization endpoint.
Resource server
The API or service that holds the protected data. It accepts access tokens and enforces scopes.

Grant types

A grant type defines how the client obtains tokens. OAuth 2.0 specifies several, each suited to a different deployment context.

Authorization Code with PKCE Recommended

The standard flow for applications that act on behalf of a logged-in user. The user is redirected to the authorization server, authenticates, and the server redirects back to the client with a short-lived authorization code. The client exchanges the code for an access token at the token endpoint.

PKCE (Proof Key for Code Exchange, RFC 7636) extends the authorization code flow to protect against authorization code interception. The client generates a random code_verifier, derives a code_challenge from it, and sends the challenge with the authorization request. The token request must include the original verifier. PKCE is required for public clients and recommended for all clients.

Use this flow for: web apps, single-page apps, and native mobile apps where a user interacts directly.

Client Credentials

Machine-to-machine authentication with no user interaction. The client authenticates directly to the token endpoint using its client ID and secret (or a signed JWT assertion), and receives an access token scoped to the client itself rather than a specific user.

Use this flow for: backend services, daemons, and scheduled jobs that call protected APIs.

Device Code

Designed for devices that lack a browser or have limited input — smart TVs, CLI tools, IoT devices. The device requests a user code and a verification URL from the authorization server, displays them to the user, and polls the token endpoint while the user completes authorization on a separate device such as a phone.

Use this flow for: CLIs, embedded devices, or any environment where redirecting a browser is impractical.

CIBA (Client-Initiated Backchannel Authentication) Coming soon

A decoupled flow defined in the OpenID Connect CIBA specification where authentication happens on a separate device from the one initiating the request. The client sends a backchannel authentication request directly to the authorization server — no browser redirect — and the server contacts the user's authentication device (typically via push notification). The client then polls the token endpoint or receives a callback when the user approves.

Use this flow for: call centre applications, IoT scenarios, and any context where the user's authentication device is separate from the application initiating the request.

Implicit Deprecated

An older flow that returned access tokens directly in the redirect URL fragment, skipping the authorization code exchange. It was designed for single-page apps before PKCE existed. The implicit flow is deprecated in RFC 9700 because tokens in URL fragments are exposed to the browser history and referrer headers. Use authorization code with PKCE instead.

Resource Owner Password Credentials Deprecated

The client collects the user's username and password directly and sends them to the token endpoint to obtain an access token. This breaks the core OAuth 2.0 model — the user hands credentials to the client rather than to the authorization server — and makes phishing trivially easy. The flow is deprecated in RFC 9700 and should not be used in new systems. Use authorization code with PKCE for user-facing applications, or client credentials for machine-to-machine access.

Tokens

Access token

A credential the client presents to the resource server to prove authorization. Access tokens are intentionally short-lived — typically minutes to an hour — to limit the window of exposure if a token is leaked. RFC 6749 treats the token format as opaque to the client; in practice, many authorization servers issue JWTs (JSON Web Tokens) as self-contained access tokens, which allows resource servers to verify them locally without a network call. Others issue opaque reference tokens that the resource server must introspect against the authorization server.

Refresh token

A longer-lived credential the client uses to obtain new access tokens without re-prompting the user. Refresh tokens are stored securely by the client and are never sent to the resource server. Modern authorization servers implement refresh token rotation: each use of a refresh token invalidates it and issues a new one, so stolen refresh tokens are detected.

JWKS (JSON Web Key Set)

When an authorization server issues JWT access tokens, any service that receives them needs the server's public key to verify the signature. Rather than distributing keys manually, authorization servers publish their public keys at a well-known JWKS endpoint — a URL returning a JSON document (RFC 7517) that lists current signing keys with their IDs and algorithms.

The benefit is stateless, scalable token verification: a resource server fetches the JWKS once, caches it, and can validate every incoming JWT access token locally without calling the authorization server on each request. When the authorization server rotates its signing keys, it publishes new ones to the JWKS endpoint and resource servers pick them up automatically on the next cache refresh. For opaque tokens, resource servers instead use token introspection (RFC 7662) — a direct call to the authorization server to validate the token and retrieve its claims.

Scopes

Scopes define the boundaries of the access being requested — for example, read:profile, openid, or offline_access. The authorization server enforces scopes and may downscope the token if the requested scopes exceed what the client is permitted. Users see requested scopes on the consent screen.

OAuth 2.0 vs OpenID Connect

OAuth 2.0 is an authorization framework: it answers the question "is this client allowed to do X?" It does not define how the user is authenticated or what the user's identity is.

OpenID Connect (OIDC) is a thin identity layer built on top of OAuth 2.0. It adds an ID token — a JWT containing claims about the authenticated user — and a /userinfo endpoint. When you see scopes like openid, profile, or email in an OAuth flow, that is OpenID Connect. Most modern identity providers (Keycloak, Auth0, Google) implement both.

The practical rule: use OAuth 2.0 alone when you need delegated access to an API; use OpenID Connect when your application also needs to know who the user is.

Common configuration mistakes

Testing OAuth 2.0 flows

OAuth 2.0 Playground is a browser-based OAuth 2.0 client for testing real authorization servers — not a simulation. Configure your endpoints, run the flow, and inspect each step: the authorization request, the code exchange, token contents, refresh, revocation, and logout. It works with Keycloak, Auth0, Google, WSO2, FIWARE Keyrock, and any other RFC-compliant server.

For high-assurance APIs that require additional security constraints beyond standard OAuth 2.0, see the FAPI 2.0 guide.