Implementing OAuth with Salesforce has three layers: configure the Connected App, pick the right OAuth flow, and implement the token exchange in your application code. The Connected App configuration is the security envelope; the flow choice fits the integration architecture; the token exchange is mostly handled by SDKs. Build with a tested OAuth library rather than rolling raw HTTP.
- Pick the OAuth flow that matches your integration
Web Server for user-facing web apps. JWT Bearer for headless server integrations. Client Credentials for service accounts. User-Agent with PKCE for mobile and SPA. Device flow for input-constrained devices. The choice constrains every other config step.
- Create a Connected App
Setup > App Manager > New Connected App. Configure OAuth settings: callback URLs, scopes, certificate (for JWT Bearer). Save and capture the Consumer Key and Consumer Secret in a secrets manager, never in source code.
- Set Permitted Users and IP Relaxation
Admin approved users (pre-authorized profiles or permission sets) is the standard for production. Enforce IP restrictions unless the integration genuinely needs to call from cloud IPs outside the trusted range.
- Implement the token exchange
Use a tested OAuth library or SDK (Salesforce ships SDKs for Node, Python, Java, .NET). Construct the authorization URL or JWT, exchange for an access token, store securely. The SDK handles retry, refresh, and error semantics.
- Make API calls with the access token
Set Authorization: Bearer ACCESS_TOKEN on every API request. The token authenticates the call. Refresh on 401 responses using the refresh token. Most SDKs handle the refresh transparently.
- Store refresh tokens securely
Refresh tokens are long-lived credentials. Store them encrypted at rest in a secrets manager, the user''s OS keychain, or an encrypted database column. Never embed in source code.
- Implement revocation handling
Build a logout flow that revokes the OAuth token via /services/oauth2/revoke. When users disconnect the integration, revoke their tokens promptly. Stale tokens after disconnect are a common audit finding.
- Monitor OAuth usage for anomalies
Setup > Connected Apps OAuth Usage. Watch for new IPs, unexpected scope grants, or unusual hours. Pair with Setup Audit Trail for change history. Set up alerts for spikes in OAuth-failure rates.
Web Server, JWT Bearer, Client Credentials, User-Agent (with PKCE), or Device. Pick based on integration architecture.
Permission flags constraining what the access token can do. Pick the minimum the integration needs to limit blast radius.
Access token typically 2 hours; refresh token lifetime configurable. Adjust based on integration security requirements.
- Refresh tokens are long-lived credentials. Storing them in source code, plain-text config files, or unencrypted databases is a security incident waiting to happen.
- Callback URLs must match exactly during OAuth handshakes. Trailing slashes, case differences, and protocol mismatches (http versus https) produce mysterious OAuth failures.
- Asking for the full scope is broader than most integrations need. Stick to api, refresh_token, and openid for typical cases. full grants administrative access and inflates blast radius if leaked.
- Mobile apps and SPAs should use PKCE, not raw client secrets. Embedded secrets in distributed code are trivially extractable from the app bundle.
- Tokens expire. Implement refresh handling for the 401 case; without it, integrations randomly fail when access tokens reach the 2-hour lifetime.