For apps with a signed in user, use the authorization code grant with PKCE. For services acting as themselves, use client credentials. For devices with no browser, use the device authorization grant. Avoid the implicit grant and the password grant. RFC 9700 says the password grant MUST NOT be used.
The decision in four questions
Is there a human at a browser or app? Use authorization code with PKCE. This covers web apps, single page apps, and mobile and desktop apps.
Is it a backend job or service with no user? Use client credentials. The client authenticates as itself and gets a token for its own resources.
Is it a device that cannot show a browser, like a TV or a printer? Use the device authorization grant, where the user approves on a phone or laptop.
Does a service need to act for a user it received a token from? Look at token exchange, covered in delegation vs impersonation.
Authorization code with PKCE
This is the default. The user authenticates at the authorization server, the client receives a code, and it redeems the code with a PKCE verifier. Public clients must use PKCE. Confidential clients should. Details in PKCE explained.
Client credentials
RFC 6749 says the client credentials grant must be used only by confidential clients. The request carries grant_type=client_credentials and an optional scope. The response should not include a refresh token, because the client can simply authenticate again. Do not use it from a browser or mobile app, where the secret cannot be kept.
Device authorization
Defined in RFC 8628. The device shows a short code and a URL. The user approves elsewhere while the device polls. It is convenient, and it has a phishing risk, so read when to use the device grant.
What to avoid
- Implicit grant. RFC 9700 says clients SHOULD NOT use it, because tokens appear in the browser URL and are easier to leak and inject. Use code with PKCE.
- Resource owner password credentials. The client handles the user's password directly. RFC 9700 says this grant MUST NOT be used.
Summary table
| Situation | Grant |
|---|---|
| Web app, SPA, mobile app with a user | Authorization code with PKCE |
| Backend service, scheduled job | Client credentials |
| TV, console, printer, CLI without a browser | Device authorization |
| Legacy app asking for passwords | Migrate to authorization code |
Quick check
Can a single page app use client credentials?
No. A browser app cannot keep a secret, so it is a public client. Use authorization code with PKCE.
Is the implicit grant forbidden?
RFC 9700 says clients SHOULD NOT use it unless token injection is prevented and leakage is mitigated. In practice, use authorization code with PKCE instead.
Sources
- RFC 6749, The OAuth 2.0 Authorization Framework
- RFC 8628, OAuth 2.0 Device Authorization Grant
- RFC 9700, Best Current Practice for OAuth 2.0 Security
Last reviewed: 19 October 2026.