Salesforce OAuth 2.0 flows
Introduction
When it comes to Identity and Access Management, it’s worth understanding that this is a crucial part of any IT solution. Negligent management can lead to excessive access to private information and ultimately to data leaks or exploitation.
The basic purpose of any access management system is to verify the right user (authentication) accesses the corresponding resources (authorization). There are several essential protocols to perform these actions in a standardized way and safely with the ability to scale and integrate with other systems.
- OAuth 2.0 - protocol for authorization, controlling external client applications to gain appropriate access to the target resource system.
- SAML (Security Assertion Markup Language) — protocol for authentication, which provides an authentication access grant for a user that validated their identity by an XML-formatted assertion of whether the user is allowed to access the target system. Used mostly in single sign on (SSO).
- OpenID Connect (OIDC) - protocol for authentication, which provides an authentication access grant for a user that validated their identity by a JWT token. It’s built on top of OAuth 2.0 and used for social sign on and in some authorization flows.
In Salesforce, OAuth 2.0 is used for authorization — to grant any client applications, such as mobile or desktop applications, IoT devices, or other servers, controlled access to Salesforce REST APIs.
Basic concepts
OAuth 2.0 flows are designed to cover all the potential scenarios of secure interconnection between the client application and Salesforce. All Salesforce OAuth flows involve these core actors:
- Client — the application or device requesting access.
- Authorization Server — Salesforce’s OAuth service that issues tokens.
- Resource Server — Salesforce APIs that serve protected resources when presented with valid access tokens.
OAuth Tokens
Tokens represent the authorization context between parties and enforce access to protected resources. They are typically issued by an authorization server. In this article the next tokens will be considered.
- Authorization code - short-lived code that is obtained by the client by performing the call to an /authorize endpoint and typically used to obtain access and refresh tokens.
- Access token - a token that confirms successful user authorization and used to access protected resources.
- Refresh token - can be generated along with an access token and used to obtain a new access token after its expiration without conducting the authorization process (with auth code) once again.
- Asset token - special type of access token designed for IoT devices linking and access to Salesforce.
OAuth Scopes
Scopes determine the set of resources or functionality that the client may access during an established connection. The set of available scopes for the client is set up in the external client app in Salesforce. Clients can also further restrict access to a subset of the available set during connection establishment. To look for the full list of possible scopes, see https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_tokens_scopes.htm&type=5
OAuth Endpoints
OAuth endpoints are the URLs clients use to make a requests to Salesforce during the authorization process. Each OAuth flow defines which endpoints to use during the flow process, but the most used endpoints are listed below.
- https://hostname/services/oauth2/authorize - clients use this endpoint to authorize their application within Salesforce and obtain authorization code.
- https://hostname/services/oauth2/token - clients use this endpoint to obtain access and refresh tokens.
Worth mentioning that all OAuth endpoints require HTTPS. For the full list of available endpoints, see https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_endpoints.htm&type=5
Headless Identity Flows
Headless identity flows are Salesforce’s version of non-interactive authentication. Unlike some standard OAuth flows that depend on redirecting a user’s browser to a login page, headless identity flows let a client authenticate and authorize using the Salesforce API calls, like login, register, etc. Use these flows if you’d like to have a pure API experience during Salesforce login or registration processes, instead of redirecting the user to the salesforce login page or embedded browser.
Available Headless flows:
- Headless login using the Authorization Code and Credentials Flow
- Headless Registration Flow
- Headless Passwordless Login Flow
- Headless Guest Flow
- Headless Forgot Password Flow
OAuth 2.0 Web Server Flow
This flow uses OAuth 2.0 authorization code grant type. A client application navigates the user to the separate login page in a browser, where user logins and client obtains the authorization code. Then the client exchanges this code for an access token. The client secret parameter can be used unless the external client app doesn’t have Require Secret for Web Server Flow enabled. Salesforce recommends that this flow is used with Proof Key for Code for Exchange (PKCE).
Use web server flow with PKCE if your client doesn’t have a secure backend to store the client secret.
PKCE
PKCE (pronounced pixy) - an extension to authorization code flow that secures interactions with public clients (usually clients without a backend side, who cannot securely store secrets) like single-page applications (SPAs) and mobile apps. It prevents authorization code interception attacks by requiring a dynamically generated cryptographic secret (code verifier) to be verified by the authorization server. Use the code_challenge and code_verifier parameters to implement PKCE with the web server flow.
Instead of relying on a pre-shared symmetric client secret, PKCE uses the code_challenge and code_verifier parameters to establish a connection.
- The client creates a unique, high-entropy cryptographic string called the code_verifier. It then hashes (usually a SHA256 hash) this string and obtains a code_challenge.
- The client sends the code_challenge to the authorization server along with the authorization request (call to /authorize to obtain the authorization code).
- When exchanging the authorization code for an access token, the client sends the original code_verifier. The authorization server hashes this verifier and compares it to the original challenge to prove the request comes from the same client.
In a flow without PKCE, an attacker with a stolen authorization code can potentially obtain an access token. With PKCE, the server requires a code verifier to verify the client that started the authorization process. Since this verifier is generated locally on the client and never leaves it until the final step, an attacker who steals only the authorization code has no chance to compromise and use the verifier the same way as the authorization code.
OAuth 2.0 User-Agent Flow
This flow uses the OAuth 2.0 implicit grant type. The client navigates the user to Salesforce’s login, and upon success Salesforce returns an access token directly in the redirect URL. This is intended for public clients that cannot securely store a secret. Because the access token is encoded into the redirection URL, it can be exposed to the user and other apps on the device. If you’re using JavaScript to authenticate, call window.location.replace(); to remove the callback from the browser’s history.
It’s simpler than Web Server Flow but less secure because tokens are minted in a redirect URL fragment. Salesforce recommends to use OAuth 2.0 web server flow with PKCE instead of user-agent flow.
OAuth 2.0 Refresh Token Flow
This isn’t a standalone login flow but an extension. Applications that have previously obtained a refresh token use this flow to get a new access token when the old one expires. Can be set up as an extension for OAuth 2.0 web server flow or the OAuth 2.0 user-agent flow to generate refresh token along with access token.
OAuth 2.0 Token Exchange Flow
When Salesforce is part of a larger architecture that uses a central identity provider, the OAuth 2.0 Token Exchange flow simplifies integration. Instead of authenticating separately with Salesforce, your platform first authenticates the user with the identity provider (for example, Okta) and receives a token (access token, refresh token, JWT, ID token, or SAML assertion). That token is then exchanged with Salesforce for a Salesforce access token mapped to the correct Salesforce user. Requires an Apex Token Exchange handler in order to map identity provider token with a corresponding existing user or create a new one. For example, in a conference management platform with an identity provider, multiple service providers (such as SAP or Concur), and AWS-based microservices, all services rely on tokens issued by the central identity provider. After login, the platform exchanges the identity provider’s token for service-specific tokens to access different systems. Using the same pattern, the identity provider’s token is sent to Salesforce, validated, and exchanged for a Salesforce access token. This keeps authentication centralized while allowing secure, delegated access to Salesforce data.
This flow is supported for your org-specific My Domain login URL (for internal users, also known as employees) and your Experience Cloud sites (for external users, also known as customers and partners).
OAuth 2.0 for Hybrid Apps
Hybrid app combines elements of native mobile app and web app providing cross-platform functionality. So the OAuth 2.0 for hybrid apps flow is designed for clients that have a web-backend part along with the native mobile component. When you use this flow you use scopes to request session IDs (SID) and domain values. You then use these SIDs and domain values to set browser cookies and establish sessions for the web-backend part of your hybrid app. When you refresh your access token, you receive new SIDs and domains to reset the browser cookies. Within your app you must set the cookies every time the access token is expired or refreshed. But there are some cases when you have to use the frontdoor.jsp to bridge an existing session into the web browser - for more information, see https://help.salesforce.com/s/articleView?id=xcloud.security_frontdoorjsp.htm&type=5
OAuth 2.0 JWT Bearer Flow
This is a server-to-server flow where the client constructs a signed JWT (JSON Web Token) assertion using an asymmetric signing (certificate-based) that Salesforce consequently validates. The process of creating and signing a valid JWT consists of several steps.
- Client constructs the JWT Header object and JSON Claims Set object with required parameters, along with the username of the current user.
- Objects are encoded using Base64url encoding and the string in the format of encoded_JWT_Header + "." + encoded_JWT_Claims_Set is created.
- This string is signed using RSA SHA256 from the certificate. Which means it’s firstly hashed with SHA256 and then signed with an RSA private key. Then this signed string is encoded with Base64url.
- The final payload looks like this: existing_string + "." + base64_encoded_signature.
Afterwards, Salesforce verifies the signature using the public key and hashes the original string to compare with the received hash and check whether it was altered during the transfer.
Why is the signing process done by using a reversed asymmetric approach, i.e. signing with a private key, not the public? Because the fundamental goal of a digital signature is to provide authenticity and non-repudiation. A private key is known only to its owner. By creating a signature with this key, the signer creates a unique digital footprint that cannot be produced by anyone else. Anyone holding the corresponding public key can verify that the signature was created by that specific private key, proving the identity of the sender. In contrast with the signing approach, in the standard asymmetric encryption sender uses the public key to encrypt, but only the owner of the private key can decrypt the message, ensuring confidentiality.
No user interaction required. Refresh token issuance is supported only if your external client app policy is set to All users may self-authorize. Use this flow when a client needs to impersonate a specific user or requires stronger, asymmetric security for server-to-server communication. For example, B2B, cross-domain architectures.
OAuth 2.0 Client Credentials Flow
This is the server-to-server flow where the client exchanges the client ID and secret, obtained from Salesforce’s external client app, directly for an access token. When accessing Salesforce using this flow, the client doesn’t impersonate the specific user. But on the Salesforce side there is still a Salesforce user predefined in the external client app, on behalf of which the Salesforce is accessed.
No user interaction required. It does not support refresh tokens.
Use this flow for cases when it’s not required to do complex asymmetric (certificate-based) connection or no need to impersonate a specific user. But also make sure that client secret is stored securely on the client’s backend. For example, accessing single service-level data.
OAuth 2.0 Device Flow
This flow supports devices with limited input or display capability, such as Smart TVs, appliances, and other IoT devices. The device shows a code to the user who then enters it on a separate browser to authenticate and grant permission. Once the user authorizes, Salesforce provides tokens to the device. Supports refresh token.
Use this for IoT devices, smart appliances, or command-line tools where direct login is impossible. For example, a Bluetooth home device requests access to a user’s Salesforce data. The user enters the provided code on their phone browser to authorize, and the device eventually receives an access token.
OAuth 2.0 Asset Token Flow
This flow extends OAuth for IoT assets. An application exchanges an existing access token and an actor token (representing a specific device metadata) for an asset token. Access token is provided by a consequent call to the /authorize and /token endpoints, whereas the asset token is a JWT signature built based on the device identification metadata. Salesforce then automatically registers the asset based on unique device identifiers from the JWT.
- If the JWT claim contains an ID claim, Salesforce attempts to link to an existing asset with a matching ID.
- If the JWT claim contains a serial number claim, Salesforce attempts to link to an existing asset with a matching serial number.
- If the JWT claim contains a name claim, Salesforce creates (registers) an asset.
- Otherwise, Salesforce doesn’t link to or create an asset. You can separately link an asset later, via the API.
In order to refresh an asset token the same access token and actor token should be used for the device.
Use it when integrating IoT devices that need specific tokens tied to unique device identities and Salesforce assets. For example, smart fridge installed at customer locations need to send telemetry to Salesforce in order to track the device state and automatically create repair/maintenance cases based on the telemetry data.
OAuth 2.0 Username-Password Flow
The client sends username, password, client ID and client secret, to directly obtain an access token. This flow is strongly discouraged in production because it transmits credentials back and forth. Refresh tokens are not issued for this flow. No user interaction needed.
Not intended for use in newly developed solutions. Can be supported for legacy systems integrations.
OAuth 2.0 SAML Bearer Assertion Flow for Previously Authorized Apps
This flow uses a SAML assertion (signed XML) from an identity provider to get a Salesforce access token. Salesforce validates the SAML assertion and issues an access token. The only prerequisite is that the app should be already authorized for the client, for example, during the OAuth 2.0 authorization or preauthorized by the admin. No user interaction required. If the app has not been previously authorized, Salesforce may reject the request because the user has not granted access to that external client app.
Use when your users log in via an external SAML identity provider and you want to use that SAML assertion to obtain a Salesforce token without interactive login. For example, corporate SSO setup (like Okta) issues SAML assertions. An ERP system (client) uses a SAML assertion obtained during SSO from an identity provider to request a Salesforce access token and then calls Salesforce APIs on behalf of the user.
Below you will find a comparison table of all the OAuth 2.0 flows available.
For more information, see https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_flows.htm&type=5

