I’ve dealt with this exact scenario multiple times. The issue involves all three aspects you mentioned:
1. OAuth2 Refresh Token Management:
The 90-day expiration you’re seeing is actually Salesforce’s refresh token inactivity timeout, not the “valid until revoked” policy. Here’s what’s happening:
- Salesforce refresh tokens expire after 90 days if they haven’t been USED to obtain a new access token
- Your integration uses the access token (not refresh token) for API calls
- If the access token never expires during those 90 days, the refresh token goes unused and expires
Solution for refresh token management:
In your Connected Object configuration in Appian, verify the token refresh strategy:
- Go to Integration Hub > Connected Systems > Your Salesforce Connection
- Check “Token Refresh” settings
- Enable “Proactive Token Refresh” if available in 22.2
- Set refresh buffer to 300 seconds (5 minutes) before expiration
2. Scheduled Integration Setup:
Your scheduled integration needs proper error handling and retry logic:
Integration Error Handling:
- Catch HTTP 401 responses
- Log authentication failure
- Trigger re-authentication workflow
- Notify administrators
In your process model that calls the scheduled integration:
- Add an exception flow from the integration smart service
- Check for authentication errors: `if(fv!error.code = “401”, …)
- Implement a fallback that triggers OAuth2 re-authentication
3. CRM Connection Configuration:
The core issue is your Salesforce access token lifetime. Salesforce Connected Apps default to very long access token lifetimes (up to 12-24 hours), which means:
- Daily integrations reuse the same access token
- Refresh token never gets exercised
- After 90 days of non-use, refresh token expires
Immediate fix:
In Salesforce Setup:
- Go to App Manager > Your Connected App > Edit Policies
- Set “Refresh Token Policy” to “Refresh token is valid until revoked” (already done)
- Critical step: Set “Access Token Timeout” to 15 minutes (not hours)
- This forces Appian to refresh the token multiple times per day
- Frequent refresh token usage prevents the 90-day inactivity expiration
Appian-side configuration (22.2 specific):
Connected System Configuration:
- Authentication: OAuth 2.0 Authorization Code
- Refresh Token Handling: Automatic
- Token Expiration Buffer: 300 seconds
- Retry Failed Refresh: Enabled (3 attempts)
Long-term solution:
Implement a token health monitoring process:
- Create a daily process that checks token expiration dates
- If refresh token age > 80 days, proactively trigger a manual refresh
- Store last successful refresh timestamp in a database
- Send alerts when refresh fails
Alternative approach - Service Account:
For critical scheduled integrations, consider using Salesforce JWT Bearer Flow instead of OAuth2 Authorization Code:
- JWT tokens don’t have refresh token expiration issues
- Better for server-to-server integrations
- Requires certificate-based authentication setup
- More complex initial setup but eliminates 90-day expiration problem
Monitoring query for future prevention:
Add this to your integration logging:
Log on each integration call:
- Access token age
- Refresh token last used date
- Next expected refresh time
- Alert if refresh token unused > 75 days
Implement the Salesforce access token timeout reduction first - this is the quickest fix that addresses the root cause. The 15-minute access token lifetime ensures your daily integration will refresh the token at least once per day, keeping the refresh token active and preventing the 90-day expiration.