Salesforce implements the full OAuth 2.0 spec plus a couple of platform-specific flows. Picking the right one matters — the wrong choice forces compromises on security or UX.
The decision matrix
| Flow | Best for | User present? | Stores refresh token? |
|---|---|---|---|
| Web Server (Authorization Code) | Server-side web apps with a UI | Yes | Yes |
| User-Agent (Implicit) | Older browser/mobile apps. Deprecated in favour of PKCE. | Yes | No |
| JWT Bearer | Server-to-server, no user, signed assertion | No | No (per call) |
| Client Credentials | Server-to-server, simple secret | No | No |
| Device Flow | IoT devices, CLIs, anything without a browser | Yes (on a separate device) | Yes |
| Refresh Token | Renewing access without re-prompting the user | No (used after initial flow) | — |
| SAML Bearer Assertion | SSO-integrated server-to-server | No | No |
Web Server Flow — the default
The user clicks “Connect to Salesforce” in your app. You redirect to /services/oauth2/authorize, they log in, Salesforce sends back a code, you swap the code (plus your client_secret) for an access + refresh token. Use this for any app with both a server and a user.
JWT Bearer Flow — for headless server jobs
The integration server signs a JWT with a private key (cert uploaded to the Connected App). Salesforce verifies the signature with the public key, issues an access token. No client secret transmitted, no refresh token stored. This is the modern default for:
- Nightly ETL jobs
- MuleSoft / Boomi connectors
- CI/CD pipelines that need to deploy metadata
POST /services/oauth2/token
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion=<signed JWT>
Client Credentials Flow — simpler server-to-server
Added more recently. The app sends client_id + client_secret directly to /services/oauth2/token and gets an access token. Simpler than JWT, but requires the secret to live somewhere on the integration side. Pick JWT if your platform supports it; pick Client Credentials when JWT setup is genuinely impossible.
Device Flow — for things without keyboards
The device asks Salesforce for a device_code and a short user_code. It displays “Visit salesforce.com/connect and enter ABCD-1234.” The user authorizes from their phone/laptop. The device polls for a token. Used by Salesforce CLI (sf org login device).
Refresh Token Flow — not really standalone
A refresh token is the output of Web Server or User-Agent flows. The Refresh Token “flow” just describes calling /services/oauth2/token with grant_type=refresh_token&refresh_token=... to mint a new access token without bothering the user. Tokens last 2 hours by default; refresh tokens can be configured to last from a single use up to indefinitely.
Things interviewers like to probe
- Which flow would you use for MuleSoft talking to Salesforce? — JWT Bearer. No user, signed assertion, no secret on the wire.
- Why isn’t User-Agent recommended anymore? — Access token comes back in the URL fragment, leaking through browser history and referer headers. PKCE on Web Server is the modern replacement.
- Can you do OAuth without a Connected App? — No. The Connected App is what defines the client_id, scopes, and trust relationship.
Verified against: Salesforce Help — Authorize Apps with OAuth. Last reviewed 2026-05-17 for Spring ‘26 release.