SfSkills Domains Docs GitHub

Home / security / oauth-token-management

oauth-token-management

Use when work depends on how Salesforce OAuth access and refresh tokens are issued, refreshed, rotated, revoked, or introspected for a Connected App or API client—including unexpected logouts, invalid_grant after refresh, or designing token incident response. NOT for choosing which OAuth grant or Connected App flow to implement (use integration/oauth-flows-and-connected-apps), Named Credential packaging (use integration/named-credentials-setup), or broad Connected App IP and PKCE policy hardening without a token-lifecycle angle (use security/connected-app-security-policies).

Open the skill folder on GitHub


OAuth Token Management

Use this skill when the hard part is no longer “getting OAuth to work once,” but keeping tokens correct over time: refresh failures, security incidents, policy tightening, or explaining why one revocation action behaved differently than another. Salesforce ties access token lifetime to Connected App and org session settings, models refresh tokens under Connected App OAuth policies, and exposes programmatic revocation and (where licensed) introspection endpoints. Misunderstanding any of those layers produces flaky integrations, false “random” logouts, and incomplete incident cleanup.


Before Starting

Gather this context before working on anything in this domain:


Core Concepts

Access token lifetime is the tighter of two clocks

An OAuth access token’s usable lifetime is bounded by the Connected App session timeout and the org session timeout from Setup session settings. The effective value is the minimum of the two, within the platform-supported range described in Salesforce Help for Connected App session policies. Treat documentation as authoritative when quoting exact bounds; do not assume a fixed two-hour lifetime in every org.

Refresh tokens are a separate credential with their own policy

When the client requests offline access (refresh_token / offline_access scopes as applicable), Salesforce issues a refresh token subject to the Connected App refresh token policy (for example immediate expiry, fixed lifetime, or valid-until-revoked). That policy determines how often users or headless processes must re-run the interactive or initial grant—not the access token TTL alone.

Revocation is target-specific: access token vs refresh token

Calling the OAuth revoke endpoint with an access token ends the session represented by that token. Revoking a refresh token invalidates the refresh credential and, per Salesforce documentation for token revocation, also invalidates outstanding access tokens issued under that OAuth grant for that user and Connected App combination. Teams that only revoke access tokens during an incident can leave long-lived refresh paths active if they do not also address refresh credentials.

Refresh token rotation hardens replay of stolen refresh tokens

Salesforce documents refresh token rotation (see release notes for your edition) so that a consumed refresh token cannot be replayed: the authorization server returns a new refresh token alongside the new access token, and the client must persist the latest refresh secret. Clients that ignore the newly issued refresh token appear “randomly” broken after the first rotation event.


Common Patterns

Pattern: Incident response—remove stolen credentials cleanly

When to use: A client secret, refresh token, or integration user credential may have leaked.

How it works: Rotate or revoke the compromised artifact using the revoke endpoint or Setup actions documented for your scenario; force affected users or the integration user through a controlled re-authorization if refresh tokens were revoked; verify no long-lived valid until revoked refresh tokens remain where policy now requires shorter exposure.

Why not the alternative: Rotating only the access token while leaving a compromised refresh token in the wild leaves a silent re-entry path for an attacker.

Pattern: Long-running jobs that must survive access token expiry

When to use: Batch or middleware holds an access token for longer than the effective session timeout.

How it works: Obtain refresh-capable scopes only when appropriate, persist the latest refresh token when rotation is enabled, refresh before expiry, and keep the Connected App refresh policy aligned with operational reality (immediate expiry is rarely compatible with unattended jobs).

Why not the alternative: Extending Connected App session timeout to “avoid refresh logic” widens the blast radius of a single stolen access token.


Decision Guidance

SituationRecommended approachReason
User reports “logged out of integration everywhere” after admin revoked OAuthConfirm whether refresh token was revoked; if yes, expect full re-consent or re-loginRefresh revocation invalidates dependent access tokens for that grant
invalid_grant right after policy changeCompare old vs new refresh token policy and session timeoutsStricter policy often invalidates existing refresh tokens
Need to verify a token before a sensitive server actionUse documented token introspection where available and permittedAvoid home-grown “call /limits as a ping” checks that do not reflect token state semantics
Headless integration should never hold a refresh tokenPrefer JWT bearer or another flow that matches the trust modelFewer long-lived bearer artifacts to protect
User frozen and all refresh tokens revoked, with no admin action or policy changeCheck the client's egress IP before auditing org IP settings; expect Salesforce-side containment for anonymizing VPN/proxy/high-risk IPsSince April 24, 2026 this applies to all Connected App and API traffic; unfreezing alone does not hold and no allowlist is documented

  1. Confirm the token path: Identify grant type, scopes, and whether refresh tokens are in play for this Connected App.
  2. Read effective timeouts: Inspect Connected App OAuth session policy and org Session Settings; record the implied access token lifetime behavior from official Help rather than guessing.
  3. Reproduce the failure class: Distinguish HTTP 401 from Salesforce API, invalid_grant from the token endpoint, and UI-driven re-authentication prompts—each maps to different fixes.
  4. Choose the smallest revocation surface: Decide whether to revoke access only, refresh only, or reset the entire grant; document impact on parallel sessions.
  5. Update clients for rotation: If rotation is enabled, verify the client persists the newest refresh token on every refresh response before closing the incident.
  6. Validate in a lower environment: Re-run the integration’s token lifecycle (issue, refresh, API call, revoke) against a sandbox copy of policies.

Review Checklist


Salesforce-Specific Gotchas

  1. Tighter session wins — A conservative org-wide session timeout caps a permissive Connected App timeout; debugging “why is my token short” requires both settings.
  2. Policy changes invalidate existing refresh tokens — Moving from long-lived to stricter refresh behavior can invalidate outstanding refresh tokens immediately; plan maintenance windows.
  3. Rotation requires client discipline — Enabling rotation without updating middleware to store the new refresh token fails at the next refresh in ways that look like Salesforce “instability.”

Output Artifacts

ArtifactDescription
Token lifecycle diagramWho holds access vs refresh, when each expires, and what revocation clears
Runbook snippetOrdered steps for revoke, re-auth, and verification queries after an incident
Policy audit tableConnected App refresh policy, session timeout, and org session row for each integration

Dependencies

Package files