id_token). SAML 2.0 is the established XML standard for proving who a user is in enterprise networks. Single Sign-On (SSO) uses SAML or OIDC; API data access uses OAuth 2.0.
- Employee SSO into your Salesforce org: Use SAML 2.0 from an enterprise Identity Provider such as Microsoft Entra ID or Okta.
- Customer "Log in with Google" on an Experience Cloud site: Use OpenID Connect (an OAuth 2.0 flow plus a signed
id_tokenproving who the customer is). - Nightly middleware job calling the Salesforce REST API: Use pure OAuth 2.0 (such as the JWT Bearer Flow or Client Credentials Flow), where an application acts without an interactive human login.
🔑 Key Points
- Authentication (AuthN) vs. Authorization (AuthZ): Authentication verifies who a person is; authorization determines what resources an application can access.
- SAML 2.0 is built for enterprise SSO: It exchanges digitally signed XML assertions between an Identity Provider (IdP) and a Service Provider (SP) through the user's browser.
- OAuth 2.0 is built for delegated API access: It issues
access_tokenandrefresh_tokenvalues so external applications can call protected APIs without ever seeing the user's password. - OpenID Connect bridges the gap: Because pure OAuth 2.0 does not standardize user identity, OIDC extends OAuth 2.0 by issuing a signed JSON Web Token (
id_token) alongside the access token. - Salesforce plays every role: Depending on your architecture, Salesforce Identity can act as a SAML Service Provider, a SAML Identity Provider, an OIDC Relying Party or Provider, and an OAuth 2.0 authorization and resource server.
🧩 Concept: Why These Three Standards Get Confused
In architecture reviews and technical interviews, SAML 2.0, OpenID Connect, and OAuth 2.0 are constantly blurred together because modern sign-in flows often combine authentication and API authorization in a single browser redirect. However, each standard was designed to solve a distinct problem.
1. SAML 2.0 (Security Assertion Markup Language)
SAML 2.0 answers the question: "Who is this user?" That makes it an authentication protocol. When an employee clicks a Salesforce tile in their corporate portal, the corporate Identity Provider (IdP) authenticates the user and generates a digitally signed XML document called a SAML assertion. The browser sends that assertion to Salesforce, which acts as the Service Provider (SP).
Salesforce validates the cryptographic signature against an X.509 certificate uploaded in Setup under Single Sign-On Settings, reads the user identifier inside the XML (NameID or a custom attribute), and establishes a browser session. SAML 2.0 is mature, heavily standardized across corporate IT departments, and remains the default choice for workforce SSO into Salesforce.
2. OAuth 2.0 (Open Authorization)
OAuth 2.0 answers a completely different question: "What is this application allowed to do?" Defined in RFC 6749, OAuth 2.0 is an authorization framework, not an authentication protocol. It lets a user or administrator grant a third-party application—or a backend integration—limited access to Salesforce data without sharing login credentials.
Instead of asserting identity to log a human into a user interface, OAuth 2.0 issues an access_token (and optionally a refresh_token) constrained by specific permissions called scopes (for example, api, web, or refresh_token). The client application attaches that access token to HTTP requests when calling Salesforce REST, SOAP, or Bulk APIs. By itself, an OAuth 2.0 access token is meant to be read by the resource server (the API), not inspected by the client app to figure out who logged in.
3. OpenID Connect (OIDC)
OpenID Connect answers the question: "Who is this user, using modern JSON and OAuth 2.0 mechanics?" Early on, developers tried to bend OAuth 2.0 into a login system by calling proprietary profile endpoints with an access token. That created security holes because access tokens are not bound to a specific client audience the way identity assertions are.
The OpenID Connect Core 1.0 specification solved this by building a formal identity layer directly on top of OAuth 2.0. When an application includes the openid scope in an OAuth 2.0 request, the authorization server returns not only an access_token for API calls, but also an id_token. This id_token is a compact, cryptographically signed JSON Web Token (JWT) containing standardized claims about the user (such as sub for subject identifier, iss for issuer, and aud for audience) plus a /userinfo endpoint. Because JSON and REST calls are much easier to parse on smartphones and single-page web apps than bulky XML assertions, OIDC is the modern standard for consumer, social, and mobile sign-on.
📊 Side-by-Side Comparison: SAML 2.0 vs. OpenID Connect vs. OAuth 2.0
Use this comparison table to quickly evaluate which protocol matches your Salesforce integration or sign-on requirement:
| Aspect | SAML 2.0 | OpenID Connect (OIDC) | OAuth 2.0 |
|---|---|---|---|
| Primary Question Answered | Who is the user? (Authentication / AuthN) | Who is the user? (Authentication / AuthN) | What can this app do? (Authorization / AuthZ) |
| Payload & Token Format | Digitally signed XML assertion | JSON / JWT id_token (plus OAuth tokens) |
access_token and refresh_token |
| Protocol Foundation | Standalone XML standard (OASIS) | Identity layer built on top of OAuth 2.0 | Standalone authorization framework (IETF) |
| Sweet Spot & Ecosystem Fit | Mature enterprise workforce portals | Mobile apps, Experience Cloud, social & modern web | REST/SOAP API integrations & middleware |
| Salesforce Setup Object | Single Sign-On Settings (SamlSsoConfig) |
Auth. Providers (AuthProvider) / Connected Apps |
Connected Apps / External Client Apps / Named Credentials |
🛠️ Worked Example: Choosing and Inspecting the Right Payload in Salesforce
To see why these protocols cannot be swapped blindly, let's walk through an illustrative multi-requirement enterprise scenario and inspect the actual payloads exchanged at each boundary. Note that the snippets below are educational excerpts illustrating protocol structure; you should validate specific endpoints, certificates, and claims in a Salesforce sandbox before deploying any identity configuration.
Imagine an enterprise running Salesforce Sales Cloud and Experience Cloud with three distinct requirements:
- Internal Sales Reps: Log in from a corporate Okta portal using SAML 2.0.
- External Partners: Log in to an Experience Cloud portal using an external OpenID Connect identity provider via Salesforce Auth. Providers.
- ERP Billing Sync: An external billing service updates
Accountrecords nightly via the Salesforce REST API using OAuth 2.0.
1. What SAML 2.0 Sends (XML Identity Assertion)
When an employee logs in via SAML 2.0, the IdP posts a Base64-encoded XML response to the Salesforce Assertion Consumer Service (ACS) URL. Decoded, the core assertion snippet looks like this excerpt:
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_a75adf55" IssueInstant="2026-10-25T08:30:00Z" Version="2.0">
<saml2:Issuer>https://idp.example.com/metadata</saml2:Issuer>
<saml2:Subject>
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">EMP-90421</saml2:NameID>
</saml2:Subject>
<saml2:Conditions NotBefore="2026-10-25T08:25:00Z" NotOnOrAfter="2026-10-25T08:35:00Z">
<saml2:AudienceRestriction>
<saml2:Audience>https://yourcompany.my.salesforce.com</saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
</saml2:Assertion>
Notice what is happening here: the XML explicitly states the issuer, the strict time window, the target Salesforce My Domain audience, and the immutable employee identifier (EMP-90421) matched against the user's Federation ID field on the Salesforce User record. No API access token is issued by this XML alone.
2. What OpenID Connect Sends (Decoded JWT id_token)
When a customer signs in through an OpenID Connect Auth. Provider in Salesforce, the external provider's token endpoint returns an OAuth access_token alongside an OIDC id_token. When you decode the payload section of that JWT id_token, you see compact JSON claims:
{
"iss": "https://accounts.example-idp.com",
"sub": "cust_8841209",
"aud": "3MVG9SemV5D80oB_client_id_example",
"exp": 1792917600,
"iat": 1792914000,
"email": "partner.user@example.com",
"email_verified": true
}
Inside Salesforce, a Registration Handler (Auth.RegistrationHandler Apex interface) can read these verified claims to match an existing User or create one on the fly. The aud (audience) claim proves this identity token was minted specifically for your Salesforce client application.
3. What Pure OAuth 2.0 Sends (API Token Response)
When the backend ERP job authenticates to Salesforce using an OAuth 2.0 headless flow (such as the OAuth 2.0 JWT Bearer Flow or Client Credentials Flow), Salesforce returns a JSON response from /services/oauth2/token:
{
"access_token": "00Dxx0000001gER!AQ8AQH0d_example_token",
"scope": "api",
"instance_url": "https://yourcompany.my.salesforce.com",
"id": "https://login.salesforce.com/id/00Dxx0000001gERAAY/005xx000001SwiUAAS",
"token_type": "Bearer"
}
The ERP system does not launch a browser session. It simply passes Authorization: Bearer <access_token> in the HTTP header of its REST API calls. To verify any of these flows in your own environment, check Setup → Identity → Identity Provider Event Log, Single Sign-On Settings (SAML Assertion Validator), and Login History.
- Treating an OAuth 2.0
access_tokenas proof of user login: An access token is like a hotel key card—it opens a specific door, but it does not have the guest's photo or name printed on it. If an app accepts any valid access token as proof of identity without checking an OIDCid_tokenand itsaudclaim, an attacker can substitute a token stolen from another application (a confused deputy attack). - Matching SSO users on mutable email addresses instead of
FederationIdentifier: When employees marry, change names, or move subsidiaries, their email addresses change. If your SAML or OIDC setup matches onUsernameor email without a stable immutable key, logins break one user at a time. Always map the IdP's immutable user ID to the Salesforce Federation ID field (which is case-sensitive). - Assuming Just-in-Time (JIT) provisioning handles offboarding: SAML JIT and OIDC Registration Handlers only run when a user logs in. They create and update user records, but they never deactivate a user who leaves the company, nor do they revoke active OAuth
refresh_tokengrants.
Rule: SAML 2.0 and OpenID Connect establish who the user is (authentication). OAuth 2.0 controls what an application may access (authorization).
Gain: A single mental model separates browser login requirements from API integration security and prevents token misuse.
Price: In real deployments the protocols often run side by side (for example, SAML assertions can be exchanged for OAuth tokens in mobile flows), so architects must understand where one handoff ends and the next begins.
Limits: SAML 2.0 relies on browser redirects and verbose XML, making it awkward for native mobile apps. OAuth 2.0 alone has no secure standard to assert identity to a client app without adding OpenID Connect.
Mirror — "We will just use OAuth for login": Common shorthand in meetings, but technically dangerous if implemented literally. Without an OIDC
id_token, there is no audience-bound signature proving who authenticated.Selection Guide: Choose SAML 2.0 for enterprise workforce SSO where Salesforce is the Service Provider. Choose OpenID Connect for Experience Cloud social/consumer login and mobile-first ecosystems. Choose OAuth 2.0 for API integrations and Connected Apps.
At Volume: Precision in identity vocabulary prevents costly rework during security reviews and architecture board sign-offs.
💬 Core Q&A and Scenario Follow-Ups
id_token. SAML 2.0 is the established XML standard for proving user identity in enterprise SSO."
A: They solve different parts of the identity and access puzzle:
- SAML 2.0 authenticates the user by exchanging digitally signed XML assertions between an Identity Provider (IdP) and a Service Provider (SP). It is older, battle-tested, and remains dominant for corporate workforce SSO into Salesforce.
- OAuth 2.0 authorizes an application to access protected APIs and resources by issuing
access_tokenandrefresh_tokenvalues. On its own, OAuth 2.0 never proves who the user is to the client application. - OpenID Connect (OIDC) closes that identity gap. It is an authentication layer built directly on top of OAuth 2.0 that adds a signed JWT
id_tokenand a standardized/userinfoendpoint. That makes OIDC lightweight, REST-friendly, and the default choice for mobile apps and consumer or social sign-on.
My decision rule is simple: SAML 2.0 and OIDC establish identity; OAuth 2.0 grants API access. Pick SAML for workforce SSO with Salesforce as the SP, pick OIDC for consumer or OAuth-native identity, and pick OAuth 2.0 whenever an application needs to call Salesforce APIs.
A: Because pure OAuth 2.0 is an authorization framework, not an authentication protocol. It hands an application an access_token to call an API, but the OAuth 2.0 specification defines no standard structure, signature verification, or audience restriction on that token for the client app to verify user identity.
- Applications that historically treated a raw OAuth
access_tokenas proof of login suffered from token-substitution vulnerabilities, where a token issued for one app was replayed to log into another app. - When a partner asks for "OAuth login," what they actually need is OpenID Connect. OIDC uses the exact same OAuth 2.0 endpoints and flows, but adds the
openidscope so the authorization server returns a cryptographically signedid_token. - In architecture discussions, I guide teams to specify OIDC whenever user login is involved, ensuring the client validates the
iss(issuer),aud(audience), andexp(expiration) claims on theid_tokenrather than inferring identity from an access token.
A: Choosing the protocol is only half the architecture; you also have to manage the user record lifecycle and active tokens across all three standards:
- Stable Identity Matching (Federation ID): Whether a login arrives via a SAML XML assertion or an OIDC
id_token, Salesforce needs a reliable key to find the rightUserrecord. Relying on email or username fails when users change their names or email addresses. Mapping an immutable employee or customer ID from the IdP to the SalesforceFederationIdentifierfield prevents broken logins over time. - Deprovisioning and OAuth Token Lifecycles: Disabling a user at the corporate IdP stops future SAML or OIDC browser logins, and Just-in-Time (JIT) provisioning only creates or updates users during login. However, if a former contractor or employee previously authorized an integration using an OAuth 2.0
refresh_token—or if their SalesforceUserrecord remains active—their integration can continue pulling data until the Salesforce user is deactivated (via SCIM / automated deprovisioning) and their OAuth tokens are explicitly revoked under Connected Apps OAuth Usage.
Q1. A contractor left in March, their corporate SSO account was disabled, yet their connected integration still pulls Salesforce data in September. What failed?
A1. Two things: First, SAML/OIDC Just-in-Time (JIT) provisioning only runs during interactive login to create or update users—it never deactivates a user when they leave. Second, disabling SSO at the IdP only blocks new browser logins; an existing OAuth 2.0
refresh_token continues minting new access tokens until the Salesforce User is deactivated (using automated SCIM deprovisioning) and active OAuth tokens are revoked.Q2. Users start failing SAML or OIDC SSO one at a time, months after a smooth go-live. What is the most likely cause?
A2. The SSO configuration is matching users on a mutable attribute like Email or Username instead of an immutable key. As employees change names, transfer departments, or update email addresses in the IdP, the assertion no longer matches their Salesforce record. Always match on the immutable Federation ID (
FederationIdentifier).
Comments
Questions, corrections and your own experience are all welcome.
Post a Comment