You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: apps/docs/content/docs/en/integrations/salesforce-service-account.mdx
+23-6Lines changed: 23 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -56,7 +56,7 @@ External Client Apps are Salesforce's current-generation connected apps and the
56
56
{/* TODO(screenshot): New External Client App form with the basic details filled in */}
57
57
</Step>
58
58
<Step>
59
-
In the OAuth settings section, enable OAuth (exact labels vary by Salesforce release)
59
+
Open the app's **Edit Settings** → **API (Enable OAuth Settings)** section and turn on **Enable OAuth**
60
60
</Step>
61
61
<Step>
62
62
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
@@ -81,7 +81,7 @@ External Client Apps are Salesforce's current-generation connected apps and the
81
81
Open your app in **External Client App Manager** and edit its **Policies**
82
82
</Step>
83
83
<Step>
84
-
Under **OAuth Policies** → **Client Credentials Flow**, check**Enable Client Credentials Flow**and set **Run As**to the integration user from step 1, then save
84
+
Under **OAuth Policies** → **Client 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 Settings**→ **OAuth Settings**, where you set it in step 2
85
85
86
86
{/* TODO(screenshot): OAuth Policies with the Run As integration user set under Client Credentials Flow */}
87
87
</Step>
@@ -133,9 +133,13 @@ The JWT Bearer Flow authenticates with an uploaded certificate rather than a sha
133
133
```
134
134
135
135
Keep `server.key` somewhere safe — Sim stores it encrypted and never shows it again.
136
+
137
+
<Callouttype="warn">
138
+
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.
139
+
</Callout>
136
140
</Step>
137
141
<Step>
138
-
In **External Client App Manager** → your app → **Edit Settings** → **OAuth Settings**, enable the **JWT Bearer Flow** toggle and upload `server.crt`. On a legacy Connected App the equivalent is **Use digital signatures** with the same file
142
+
In **External Client App Manager** → your app → **Edit Settings** → **OAuth 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
139
143
</Step>
140
144
<Step>
141
145
Edit the app's **Policies** → **OAuth Policies** and set **Permitted Users** to **Admin approved users are pre-authorized**
@@ -145,7 +149,11 @@ The JWT Bearer Flow authenticates with an uploaded certificate rather than a sha
145
149
</Callout>
146
150
</Step>
147
151
<Step>
148
-
Assign the integration user's **profile** or a **permission set** to the app (External Client App Manager → your app → **Policies** → manage profiles/permission sets), so that user is covered by the pre-authorization
152
+
Assign the integration user's **profile** or a **permission set** to the app, so that user is covered by the pre-authorization
153
+
154
+
<Callouttype="warn">
155
+
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.
156
+
</Callout>
149
157
</Step>
150
158
<Step>
151
159
Copy the **Consumer Key** as in step 4. There is no consumer secret to copy — the JWT flow doesn't use one
@@ -158,7 +166,7 @@ Go to **Setup** and search for **My Domain**. The host is required — Salesforc
-**Developer Edition:**`yourorg.develop.my.salesforce.com` (Salesforce appends `-dev-ed` only when it generated the name for you)
162
170
163
171
Sim also accepts other partitioned My Domain hosts (`scratch`, `demo`, `patch`, `trailblaze`, `free`).
164
172
@@ -176,6 +184,15 @@ There's no scope picking beyond the **api** and **openid** scopes on the app —
176
184
177
185
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.
178
186
187
+
<Callouttype="warn">
188
+
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:
189
+
190
+
-**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**.
191
+
-**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.
192
+
193
+
If a workflow must run reports, a standard-seat integration user is the safe choice.
194
+
</Callout>
195
+
179
196
## Adding the Service Account to Sim
180
197
181
198
<Steps>
@@ -230,7 +247,7 @@ Deactivating or freezing the integration user — the Run As user for client cre
230
247
{ question: "Setup → App Manager → New Connected App is greyed out — why?", answer: "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." },
231
248
{ question: "Why do I have to enter a My Domain host instead of login.salesforce.com?", answer: "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." },
232
249
{ question: "The credential validates but a specific tool fails with a permission error — why?", answer: "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." },
233
-
{ question: "Does this work with sandboxes and Developer Edition orgs?", answer: "Yes — enter the sandbox host (yourorg--sandboxname.sandbox.my.salesforce.com) or Developer Edition host (yourorg-dev-ed.develop.my.salesforce.com) as the My Domain host. Government/military domains (*.my.salesforce.mil) aren't currently supported." },
250
+
{ question: "Does this work with sandboxes and Developer Edition orgs?", answer: "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." },
234
251
{ question: "How do I rotate the credentials?", answer: "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." },
235
252
{ question: "What happens if the integration user is deactivated or frozen?", answer: "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." },
{ question: "How do I back up and restore the database?", answer: "Back up with: docker compose -f docker-compose.prod.yml exec db pg_dump -U postgres simstudio > backup.sql. Restore with: docker compose -f docker-compose.prod.yml exec -T db psql -U postgres simstudio < backup.sql. The database data is persisted in a Docker volume named postgres_data."},
160
160
{ question: "Can I customize the PostgreSQL credentials?", answer: "Yes. The docker-compose.prod.yml uses environment variable defaults: POSTGRES_USER (default: postgres), POSTGRES_PASSWORD (default: postgres), POSTGRES_DB (default: simstudio), and POSTGRES_PORT (default: 5432). Set these in your .env file to override them." },
`bun run sim update` pulls the versions configured by `SIM_VERSION` (or `latest` when it is
150
+
unset), recreates the changed services, and keeps data volumes. It is equivalent to running
151
+
`docker compose pull` followed by `docker compose up -d`.
152
+
150
153
There is a short window where the app is unavailable while containers restart. Compose has no rolling-update mechanism — plan a maintenance window, or run Kubernetes if you need zero-downtime upgrades.
0 commit comments