This guide covers the configuration steps required to connect Discourse to Salesforce using the Discourse Salesforce plugin.
Discourse Salesforce is available on the Enterprise plan.
Required user level: Administrator
Step 0: Finding the right people in your organization
Before doing anything in Discourse, first make sure that you know the right people to involve from your organization to handle what’s required on the Salesforce side.
Salesforce administrator
Who they are: In most organizations, this is typically whomever your team calls “the Salesforce admin” — the person who manages your Salesforce org’s configuration, not necessarily your IT system administrator.
What they do: Handles the initial setup on the Salesforce side by creating the External Client App (or Connected App) in Salesforce Setup, configuring OAuth settings, and retrieving the Consumer Key and Consumer Secret.
What they need: Access to Salesforce Setup and specifically the External Client App Manager. In Salesforce, this requires the Customize Application system permission. This is included in the standard System Administrator profile. If the person doing the setup doesn’t have a System Administrator profile, a Salesforce administrator will need to grant them a permission set that includes “Customize Application.”
Salesforce integration user
Who they are: A Salesforce user whose account credentials are used by the Discourse plugin to make API calls to Salesforce.
What they do: Provides the username to go into the salesforce username setting in the Discourse Salesforce settings to facilitate all the API calls from Discourse to Salesforce.
What they need: This user must have:
| Permission | Why it’s needed |
|---|---|
| API Enabled | Required for any Salesforce API access |
| Create, Read, Edit on Lead | Create and link Leads from Discourse users |
| Create, Read, Edit on Contact | Create and link Contacts from Discourse users |
| Create, Read, Edit on Case | Create Cases from Discourse topics |
| Create on Case Comment | Sync topic replies as Case Comments |
| Create on FeedItem (Chatter) | Post topic activity to Chatter |
Note: The Salesforce integration user can be the same person as the Salesforce administrator. However, as a security best practice, we recommend using a separate, more narrowly-permissioned account for the integration user.
Step 1: Generate a certificate and private key
Role: Discourse admin
Discourse Salesforce uses JWT Bearer Flow to authenticate with Salesforce. This requires an RSA key pair: a public certificate that Salesforce uses to verify the plugin’s identity and a private key that Discourse uses to sign its requests.
- Follow these instructions to generate the key pair:
server.crt- a public certificate that proves Discourse is the authorized appserver.key- a private key that signs Discourse’s APIs requests to Salesforce
- Send the
server.crtfile to your Salesforce administrator so they can upload it in Step 3. - Hold onto the
server.keyto paste into the Discourse Salesforce settings in Step 5.
Step 2: Create the External Client App in Salesforce
Role: Salesforce administrator
-
Log into Salesforce.
-
Click the gear icon (
) in the top right and select Setup. -
In the Quick Find box, search for External Client App Manager and select it.
-
Click New External Client App.
Note: These steps use the External Client App Manager, introduced in Salesforce Spring '25. If your org is on an older release, the UI may say App Manager or Connected Apps instead — the underlying settings are the same.
Step 3: Fill in Basic Information and OAuth Settings
Role: Salesforce administrator
-
Fill in the Basic Information section (App Name and Contact Email are required).
-
Expand the API (Enable OAuth Settings) section and check the Enable OAuth setting.
-
Configure the following settings in this section:
- Callback URL: Add both of these links, replacing
<your-discourse-site>with your Discourse site’s full URL (e.g.,meta.discourse.org):
https://<your-discourse-site>
https://<your-discourse-site>/auth/salesforce/callback
Make sure there is no trailing slash /at the end of either URL! - Available OAuth Scopes: Add all three:
- Access the identify URL service (id, profile, email, address, phone)
- Manage user data via APIs (api)
- Perform requests at any time (refresh_token, offline_access)
- Flow Enablement: Enable both:
- Enable Client Credentials Flow
- Enable JWT Bearer Flow — this is required for the plugin to create Leads, Contacts, and Cases
- Callback URL: Add both of these links, replacing
-
Under Certificate Upload, click Upload files and upload the
server.crtfile from Step 1. -
Click Create.
Step 4: Retrieve the Consumer Key and Consumer Secret
Role: Salesforce administrator
-
On the newly created External Client App, click the Settings tab.
-
Scroll down and expand the OAuth Settings.
-
Click Consumer Key and Secret.
-
Re-enter your Salesforce login credentials when prompted.
-
Copy the Consumer Key and Consumer Secret and send them to your Discourse admin for Step 5.
Step 5: Configure the Discourse plugin settings
Role: Discourse admin
-
In Discourse, go to Admin → Plugins → Salesforce → Settings.
-
Fill in the following settings:
Setting Value salesforce enabledCheck the box to enable the integration salesforce client idThe Consumer Key from Step 4 salesforce client secretThe Consumer Secret from Step 4 salesforce rsa private keyPaste the full contents of the server.keyfile from Step 1salesforce usernameThe username of the Salesforce integration user salesforce authorization server urlOnly needed if you use a custom Salesforce domain (e.g., https://mycompany.my.salesforce.com) -
Click Save changes.
Step 6: Authorize the Discourse app in Salesforce
Role: Salesforce integration user
- Go to
https://<your-discourse-site>/salesforce/admin/authorize, replacing<your-discourse-site>with your Discourse site’s full URL (e.g.,meta.discourse.org). - You will be redirected to Salesforce and prompted to authorize the app.
- Login to Salesforce and grant access to the app.
After completing this step, you should be all set. You can confirm it’s working by going to any user profile in Discourse — a Sync with Salesforce option should appear in the admin menu.
Troubleshooting
If the plugin isn’t working after setup, check these first:
-
Admin dashboard health checks: the plugin surfaces two alerts in
/adminwhen things are misconfigured:SalesforceInvalidCredentials: the Consumer Key, Consumer Secret, RSA private key, or username is incorrectSalesforceAppNotApproved: the authorization step (Step 6) hasn’t been completed, or the connected app was rejected
-
Enable verbose logging: Turn on the
salesforce_auth_verbose_loggingsite setting to write detailed authentication output to Discourse’s/logs. Common errors and causes:
| Symptom | Likely cause |
|---|---|
| “Insufficient privileges” when creating a Lead or Contact | The integration user doesn’t have Create/Edit permissions on Lead or Contact objects |
| “Insufficient privileges” when creating a Case | The integration user lacks Case or Case Comment permissions |
| “Invalid grant” on the authorization step | The RSA key doesn’t match the certificate uploaded in Step 3, or the JWT Bearer Flow wasn’t enabled |
| “DUPLICATE_VALUE” error on Lead or Contact creation | Expected behavior if the user already exists in Salesforce — the plugin handles this, but see the main plugin docs for details |
| Chatter posts not appearing | The integration user may not have FeedItem Create permissions |






