← Back to Security

OAuth 2.0 Flows

OAuth 2.0 flows for public clients, confidential clients, devices, and delegated access.

SecurityAuthorizationOAuth 2.0

OAuth 2.0 defines several grant flows because clients do not all look the same. A browser-based app, a mobile app, a server-side service, and a command-line device all have different trust boundaries. The right flow depends on whether a user is present, whether the client can keep a secret, and how the token will be used.

Authorization Code Flow with PKCE

This is the standard choice for modern user-facing applications. The client redirects the user to the authorisation server, the user authenticates and consents, and the client receives a short-lived code on its redirect URI. The client then exchanges that code for an access token, often plus a refresh token. PKCE adds a proof step so intercepted codes are not useful to an attacker. This flow is preferred because tokens are not exposed directly in the browser redirect and because it works for both server-rendered and public clients.

A good implementation also validates state, restricts redirect URIs tightly, and stores tokens according to the client's real threat model. The flow is standard, but the security posture still lives in the details.

Client Credentials Flow

This is for machine-to-machine access. There is no user, so the client authenticates as itself and receives a token representing the application. It is simple and efficient for back-office jobs, internal service calls, or daemon processes. Its limit is obvious: it cannot represent per-user consent or identity.

Device Authorisation Flow

This flow is useful on devices with limited input capability, such as TVs or embedded hardware. The device shows a code, the user completes authentication on a separate browser-enabled device, and the original device polls for completion. It keeps credentials off awkward devices while still allowing account linking.

Refresh Tokens

Strictly speaking, refresh is not a separate user-started flow, but it is part of many deployments. A refresh token lets the client obtain new access tokens without forcing the user through the full login and consent journey repeatedly. Because refresh tokens live longer, they need stronger storage and rotation policies.

Legacy Flows

The implicit flow used to be common for browser apps because it returned tokens immediately, but it exposed them more directly and complicated renewal and revocation. The resource owner password grant asked clients to collect the user's password directly, which undermines the whole delegation model. Both are widely treated as legacy options now.

The common mistake is choosing a flow based on convenience rather than client trust model. If the client cannot securely hold a secret, design for that. If a user is absent, do not force a user-centric flow. OAuth works well when the grant matches the real deployment shape, not when teams bend the protocol around shortcuts.