Salesforce Integration Users

Salesforce's server-to-server OAuth flows let your workflows authenticate as a dedicated integration user instead of through a person's OAuth login. An admin creates an External Client App once and names the integration user whose permissions every API call executes with — no user consent to expire, no browser session, and data access governed entirely by that user's profile and permission sets.

This is the recommended way to use Salesforce in production workflows: nothing depends on a person staying logged in, and what the credential can touch is exactly what the integration user can touch. It also works with an API-only user, who cannot sign in to the Salesforce UI at all and therefore cannot complete the interactive OAuth flow.

Sim supports both server-to-server flows. Pick one:

Client credentialsJWT bearer
What Sim storesConsumer key + consumer secretConsumer key + private key
Who calls run asThe app's Run As userThe username you name in Sim
Salesforce setupEnable Client Credentials Flow, set Run AsUpload a certificate, pre-authorize the user
Pick it whenYou want the simplest setupYour security policy forbids shared secrets, or you want one app to serve several integration users

Both are equivalent in what they can do — every Salesforce tool works on either, subject to the integration user's permissions.

Prerequisites

You need a Salesforce admin to create the External Client App and the integration user. Every API call Sim makes runs with the integration user's permissions, so plan that user's profile and permission sets deliberately.

Setting Up the External Client App

1. Create a Dedicated Integration User

In Salesforce, go to SetupUsersNew User. Set License to Salesforce Integration (the free API-only license) and Profile to Minimum Access - API Only Integrations

Create a permission set backed by the Salesforce API Integration permission set license, grant it the object and field permissions your workflows need (least privilege), and assign it to the user

If your org doesn't have Salesforce Integration licenses, any standard user with the API Enabled permission works too — but a dedicated API-only user keeps the credential's access explicit and auditable.

2. Create the External Client App

External Client Apps are Salesforce's current-generation connected apps and the default way to create new OAuth apps.

Go to SetupExternal Client App ManagerNew External Client App, give the app a name and contact email, and keep it local to your org (not packaged for distribution)

Open the app's Edit SettingsAPI (Enable OAuth Settings) section and turn on Enable OAuth

Enter any placeholder Callback URL (e.g. https://login.salesforce.com/services/oauth2/callback) — it's required by the form but unused by this flow

Add the OAuth scopes Manage user data via APIs (api) and Access unique user identifiers (openid)api is required for the flow, and openid lets Sim look up the integration user's name via the userinfo endpoint (the instance URL comes back in the token response itself)

Client credentials only: enable the Client Credentials Flow in the OAuth settings and acknowledge the warning. Skip this if you're setting up JWT bearer — that flow has its own toggle (see below)

Create the app

3. Configure the Run As User

Open your app in External Client App Manager and edit its Policies

Under OAuth PoliciesClient Credentials Flow, set Run As to the integration user from step 1, then save. That page holds only the Run As picker — the Enable Client Credentials Flow checkbox itself lives in Edit SettingsOAuth Settings, where you set it in step 2

Every API call Sim makes executes with this user's permissions.

4. Copy the Consumer Key and Secret

Open the app's SettingsOAuth Settings and click Consumer Key and Secret (Salesforce prompts for identity verification). Copy the Consumer Key and Consumer Secret.

The Consumer Secret plus the Run As configuration is full API access as the integration user. Treat both values like passwords — do not commit them to source control or share them publicly. Sim encrypts them at rest.

Using an Existing Connected App (Legacy)

Creating new Connected Apps is blocked by default: since Summer '25 new orgs ship with Connected App creation disabled, and Spring '26 turned it off across all orgs — re-enabling it requires a request to Salesforce Support. Use an External Client App for new setups.

If you already have a classic Connected App, it keeps working and the credential fields are identical — the token endpoint and Sim configuration don't change. Configure it the classic way:

In SetupApp Manager, confirm the app has Enable OAuth Settings, the Manage user data via APIs (api) and Access unique user identifiers (openid) scopes, and Enable Client Credentials Flow checked

From App Manager, open the app's Manage page, click Edit Policies, and set Run As under Client Credentials Flow to your integration user. Permitted Users policies don't apply to the Client Credentials Flow's execution user, so no pre-authorization is needed

Open the app with View and click Manage Consumer Details to copy the Consumer Key and Consumer Secret

Using the JWT Bearer Flow Instead

The JWT Bearer Flow authenticates with an uploaded certificate rather than a shared secret, and runs as a username you name in Sim rather than the app's Run As user. Set this up instead of steps 3 and 4 above. Steps 1, 2, and 5 are the same — but in step 2, skip the Client Credentials Flow substep; JWT bearer does not use that flow.

Generate a key pair. server.key stays with Sim; server.crt is uploaded to Salesforce:

openssl req -x509 -sha256 -nodes -days 3650 -newkey rsa:2048 \
  -keyout server.key -out server.crt -subj "/CN=sim-salesforce"

Keep server.key somewhere safe — Sim stores it encrypted and never shows it again.

Salesforce requires an RSA key of at least 2048 bits for this flow; an ECDSA key is rejected. The uploaded certificate must also stay under 4 KB, which a 2048-bit self-signed cert comfortably is.

In External Client App Manager → your app → Edit SettingsOAuth Settings, turn on Enable OAuth (the JWT toggle does not appear until it is on), then Enable JWT Bearer Flow, and use Upload Files to upload server.crt. On a legacy Connected App the equivalent is Use digital signatures with the same file

Edit the app's PoliciesOAuth Policies and set Permitted Users to Admin approved users are pre-authorized

This step is mandatory. The JWT flow requires prior approval of the app, and an API-only integration user can never grant that approval interactively — there is no UI for them to log in to. Without pre-authorization every token request fails with user hasn't approved this consumer.

Assign the integration user's profile or a permission set to the app, so that user is covered by the pre-authorization

Assign it through the profile, or through a second permission set that does not carry the Salesforce API Integration permission set license. A permission set backed by that license cannot hold an Assigned Connected Apps / Assigned External Client Apps section at all, so the app can never be assigned from the same permission set that grants the user its object access. Getting this wrong produces exactly the user hasn't approved this consumer failure this step exists to prevent.

Copy the Consumer Key as in step 4. There is no consumer secret to copy — the JWT flow doesn't use one

5. Find Your My Domain Host

Go to Setup and search for My Domain. The host is required — Salesforce rejects the Client Credentials Flow at login.salesforce.com and test.salesforce.com. Depending on your org type it looks like:

  • Production: yourorg.my.salesforce.com
  • Sandbox: yourorg--sandboxname.sandbox.my.salesforce.com
  • Developer Edition: yourorg.develop.my.salesforce.com (Salesforce appends -dev-ed only when it generated the name for you)

Sim also accepts other partitioned My Domain hosts (scratch, demo, patch, trailblaze, free).

Use the my.salesforce.com host, not the my.salesforce-setup.com host you see in the address bar while working in Setup, and not lightning.force.com. Government Cloud Plus domains (*.my.salesforce.mil) are not currently supported.

Permissions Instead of Scopes

There's no scope picking beyond the api and openid scopes on the app — what the credential can actually do is the integration user's profile plus permission sets. In particular:

  • Object and field access for every object your workflows read or write, plus API Enabled
  • Customize Application for tools that manage custom fields and custom objects (Tooling API) — a Minimum Access API-only user passes validation but fails these specific tools without it
  • Run Reports and folder access for report and dashboard tools

A permissions gap surfaces at run time as a Salesforce API error; fix it on the integration user's permission sets — no changes are needed in Sim.

On the Salesforce Integration (API-only) license specifically, SOQL and CRUD on standard objects are well supported, but two areas are not safe to assume:

  • Reports and dashboards are unverified on this license. Salesforce documents neither a grant nor a prohibition. Test them in a sandbox before depending on them, and remember the user also needs access to the report or dashboard folder.
  • Anything Apex-related is blocked — Apex Class Access is one of the permissions this license cannot hold, so Tooling API calls touching ApexClass will fail. Custom field and custom object management is unaffected.

If a workflow must run reports, a standard-seat integration user is the safe choice.

Adding the Service Account to Sim

Open Integrations from your workspace sidebar

Search for "Salesforce" and open it, then click Add to Sim and choose Add integration user app

In the Add Salesforce integration user app dialog, pick the Authentication method you configured. The dialog then asks only for that flow's fields:

  • Client credentialsConsumer key and Consumer secret
  • JWT bearerConsumer key, the Private key (paste the whole server.key file, -----BEGIN line included), and the Run as username (the integration user's Salesforce username, e.g. integration.user@yourorg.com)

Then paste your My Domain host (e.g. yourorg.my.salesforce.com) and optionally set a display name and description

Click Add integration user app. Sim verifies the credentials by minting a real access token against your My Domain host. A host that doesn't resolve gets its own error message; every other misconfiguration surfaces as a general authentication error — re-check the values and the app's OAuth policies.

Using the Service Account in Workflows

Add a Salesforce block to your workflow. In the credential dropdown, your Salesforce service account appears alongside any OAuth credentials. Select it and configure the block as you normally would.

The block calls your org's REST API with a freshly minted access token — the same requests as the OAuth flow, so every Salesforce tool works, subject to the integration user's permissions.

Token Behavior

Access tokens from both flows have no fixed lifetime in the response — an opaque token stays valid until the Run As user's session times out (2 hours by default; configurable from 15 minutes to 24 hours in Session Settings). There is no refresh token; Sim mints a new token whenever one is needed, so session timeouts are invisible to your workflows.

Deactivating or freezing the integration user — the Run As user for client credentials, or the run-as username for JWT bearer — stops all token minting with an invalid_grant error, halting every workflow that uses the credential. Password policies that expire the user's API access have the same effect. Treat the integration user as production infrastructure.

Common Questions

Either works with every Salesforce tool. Client credentials is the simpler setup: enable the flow, set a Run As user, paste a consumer key and secret. Pick JWT bearer when your security policy forbids storing a shared secret, or when you want one app to authenticate as several different integration users — the username is part of each credential rather than fixed on the app.
Yes — that's the intended setup for both flows, and the reason to use one instead of OAuth. Assign the free Salesforce Integration license plus the Salesforce API Integration permission set license. Interactive OAuth is the only method that cannot work for such a user, because it requires a browser login they cannot perform.
The app's Permitted Users policy is not set to "Admin approved users are pre-authorized", or the run-as user's profile/permission set is not assigned to the app. An API-only user can never approve the app interactively, so pre-authorization is the only path. Fix both in the app's OAuth Policies and retry.
Salesforce could not find the app in the org the audience names. Check that the My Domain host belongs to the same org the app is installed in, and that the consumer key is that app's. Since Spring '26 the audience must be your My Domain URL — Sim always uses it, which is why the host has to be exactly right.
The certificate uploaded to Salesforce does not match the private key pasted into Sim. Regenerate the pair together, re-upload server.crt to the app, and re-paste server.key. Also confirm you pasted the key and not the certificate — Sim flags that inline.
No. Sim collects no passphrase, so decrypt the key first: openssl rsa -in server.pass.key -out server.key. Both PKCS#1 ("BEGIN RSA PRIVATE KEY") and PKCS#8 ("BEGIN PRIVATE KEY") containers are accepted, so whichever your OpenSSL version emits is fine.
The credential authenticates as a dedicated API-only user, not a person — nothing expires when someone leaves or their login lapses. What it can access is exactly the integration user's profile and permission sets, which makes the credential's reach explicit and auditable.
Salesforce likely rejected the token request with invalid_grant (e.g. 'no client credentials user enabled'), which Sim reports as not being able to authenticate with those credentials. The app either doesn't have Enable Client Credentials Flow checked, or no Run As user is set. Edit the app's OAuth policies (External Client App Manager → your app → Policies, or a legacy Connected App's Manage → Edit Policies), enable the flow, and set Run As to your integration user.
Salesforce disabled new Connected App creation by default (new orgs since Summer '25, all orgs since Spring '26); re-enabling it requires a Salesforce Support request. You don't need it — create an External Client App instead (Setup → External Client App Manager), which supports the same Client Credentials Flow and produces the same consumer key and secret.
Salesforce only supports the Client Credentials Flow at your org's My Domain URL — login.salesforce.com and test.salesforce.com are explicitly rejected for this flow. Find yours under Setup → My Domain.
Every call runs as the Run As user, so the failing tool needs a permission that user doesn't have. Common gaps: Customize Application for custom field/object tools, Run Reports plus folder access for report tools, and object or field permissions for the records involved. Fix it on the integration user's permission sets and re-run.
Yes — enter the sandbox host (yourorg--sandboxname.sandbox.my.salesforce.com) or Developer Edition host (yourorg.develop.my.salesforce.com, with a -dev-ed suffix only if Salesforce generated the name for you) as the My Domain host. Government/military domains (*.my.salesforce.mil) aren't currently supported.
For client credentials, rotate the Consumer Secret from the app's OAuth settings (External Client App: Settings → OAuth Settings → Consumer Key and Secret; legacy Connected App: Manage Consumer Details), then update the credential in Sim with the new secret. For JWT bearer, generate a new key pair, upload the new certificate to the app, and paste the new private key into Sim. Either way, reconnecting asks you to restate the authentication method — Sim never returns a stored secret, so it cannot pre-select it for you.
All token minting fails with invalid_grant and every workflow using the credential stops. Reactivate the user (or point Run As at a new integration user) and runs resume — no changes needed in Sim.

On this page