Problem
A CloudSense service cannot authenticate to Salesforce using JWT OAuth. Each CloudSense service that logs in to Salesforce has its own connected app. Examples include Digital Fulfilment, the Orchestrator Accelerator and the Elastic Service. The problem is most often seen right after a sandbox refresh, or the first time a service is used in a new org. You may see one or more of the following:
- The error
400 Bad Request: user hasn't approved this consumer, or an HTTP 400 when the service requests its OAuth JWT token. - Setup > Login History for the service's integration user shows Status "Failed: Not approved". The Application column shows the name of the connected app.
- Setup > Connected Apps OAuth Usage does not list that connected app.
- A symptom specific to the service. Example (Digital Fulfilment): Ad Server > Check Login returns
loginStatus: FAILEDwith "The system cannot retrieve info from SFDC", and the logs showFailed to get OAuth JWT token for orgId <org id>.
Cause
Each CloudSense service logs in to Salesforce through its own connected app, which CloudSense provides. A System Administrator must authorize that connected app once in each org before Salesforce accepts its JWT logins. A refreshed sandbox does not keep this authorization, even when production still has it.
Setting Permitted Users to "Admin approved users are pre-authorized" and assigning the integration user's profile or permission set does not fix the error on its own. Those settings only take effect after the one-time authorization exists.
This is not a certificate or key problem. If the service's key check reports that the keys match, follow this article. Example (Digital Fulfilment): if the keys do not match, see KB 133286 instead.
Resolution
Step 1: Identify the connected app
In Setup > Login History, find the "Failed: Not approved" row for the integration user. The Application column shows the name of the connected app that needs to be authorized. Example: CloudSense Digital Fulfilment Application.
Step 2: Get the authorization link
If the connected app is listed under Known CloudSense connected apps below, use the ready-made link for your org type and go to Step 3.
Otherwise, the link has this format. Every parameter is required, including the two PKCE parameters at the end:
https://<login host>/services/oauth2/authorize?client_id=<Consumer Key>&redirect_uri=<Callback URL>&response_type=code&code_challenge=U-tl-KvR76dyr6gWrcep_hZn5J-INHo44R22_uQ2QQQ&code_challenge_method=S256
<login host>:test.salesforce.comfor a sandbox, orlogin.salesforce.comfor production. If your org blocks these, use your My Domain host instead, for example<yourdomain>--<sandbox>.sandbox.my.salesforce.com.<Consumer Key>: the Consumer Key (client ID) of the connected app.<Callback URL>: the callback URL configured in the connected app. It must match exactly.code_challengeandcode_challenge_method: use the values shown.
If you do not have the Consumer Key and Callback URL for the connected app, contact CloudSense Support for the link.
Step 3: Authorize the connected app
- Log in to the affected org as a System Administrator.
- In the same browser, open the authorization link.
- On the Allow access? page for the connected app, click Allow.
- You may then be redirected to a CloudSense web page. This is expected, and there is nothing to do on that page.
Step 4: Verify
- Setup > Connected Apps OAuth Usage now lists the connected app.
- Retry the operation that failed. Example (Digital Fulfilment): Ad Server > Check Login returns SUCCESS.
Step 5: Check pre-authorized users (if applicable)
If Permitted Users is set to "Admin approved users are pre-authorized", confirm that the integration user's profile or permission set is assigned. You can check this in Setup > Connected Apps > Manage Connected Apps > <connected app> > Profiles / Permission Sets.
Known CloudSense connected apps
CloudSense Digital Fulfilment Application
Sandbox:
https://test.salesforce.com/services/oauth2/authorize?client_id=3MVG9fTLmJ60pJ5IO2NiH5AuALHqkHunD9iOsdooKCKYp0n0gHYC4.ppeekfJu1kkZpCBTKw3jiEQA.dMNeAs&redirect_uri=https://www.cloudsense.com/cloudsense-digital-fulfilment-success&response_type=code&code_challenge=U-tl-KvR76dyr6gWrcep_hZn5J-INHo44R22_uQ2QQQ&code_challenge_method=S256
Production:
https://login.salesforce.com/services/oauth2/authorize?client_id=3MVG9fTLmJ60pJ5IO2NiH5AuALHqkHunD9iOsdooKCKYp0n0gHYC4.ppeekfJu1kkZpCBTKw3jiEQA.dMNeAs&redirect_uri=https://www.cloudsense.com/cloudsense-digital-fulfilment-success&response_type=code&code_challenge=U-tl-KvR76dyr6gWrcep_hZn5J-INHo44R22_uQ2QQQ&code_challenge_method=S256
Orchestrator Accelerator
Contact CloudSense Support for the current authorization link.
Elastic Service
Contact CloudSense Support for the current authorization link.
Important: links without code_challenge no longer work
Salesforce now rejects authorization links for CloudSense connected apps that do not include code_challenge and code_challenge_method=S256. Such a link fails immediately with:
HTTP 400 error=invalid_request, error_description=missing required code challenge
Older links do not have these parameters. This includes the link in section 3.2 of the Service Connectivity User Guide. Add the two parameters as shown in Step 2, or use the links above.
After every sandbox refresh
Repeat Steps 3 and 4 in each refreshed sandbox, for every CloudSense connected app the org uses, before you test the services. Include this step in your post-refresh checklist.
How the JWT flow works (background)
- The CloudSense service signs a JWT with its private key.
- It sends the JWT to the Salesforce OAuth token endpoint.
- Salesforce verifies the JWT with the public key held in the connected app.
- If the connected app is authorized for the org, Salesforce returns an access token. If it is not, Salesforce rejects the login as "Not approved" / "user hasn't approved this consumer".
Additional notes
- Each CloudSense service has its own connected app, and each one needs its own one-time authorization. Login History shows which app failed.
- The redirect URI in the link must match the connected app's callback URL exactly, including any trailing slash. Otherwise the authorization fails.
Priyanka Bhotika
Comments