Skip to main content
The Salesforce connector indexes CRM records into Omni with Salesforce’s sharing model mirrored into document permissions. It also exposes native CRM actions and the official Salesforce MCP server, so the assistant can both search indexed records and act on Salesforce live with the signed-in user’s own Salesforce identity.

Overview

What We Sync

Alongside those records the connector syncs the directory data needed to resolve permissions — User, Group, GroupMember, and UserRole — and the per-object share tables (AccountShare, ContactShare, OpportunityShare, LeadShare, CaseShare). Deletions are reconciled from Salesforce’s deleted-records API.
Accounts, contacts, and the other CRM records are indexed as documents, not as people-directory entries. Salesforce users are synced into the people directory, so to look someone up by name, email, or title, ask the assistant in chat — it queries the directory with its search_people tool.

How It Works

  1. The native connector authenticates to your org with an External Client App JWT bearer flow using a dedicated integration user. It mints and refreshes its own short-lived access tokens — no password or security token is required.
  2. Records and their share metadata are synced, and Salesforce’s ownership, role-hierarchy, sharing-rule, and public-read semantics are translated into Omni permissions.
  3. The companion MCP OAuth client is what lets users act on Salesforce through Omni rather than only search it. It is configured once per Salesforce source, and each Omni user then authorizes their own Salesforce account so the assistant can make live MCP/API calls against the org with that user’s own Salesforce identity and permissions — for example running an ad-hoc SOQL query that the synced records can’t answer, or invoking the write-capable tools enabled for the source. MCP never falls back to the org JWT credential, so a user who hasn’t authorized Salesforce has no MCP access.

Permissions

Omni mirrors four Salesforce visibility mechanisms: Only Salesforce users that are active and have an email address receive grants. Group and role membership is expanded through nested groups with cycle protection, and records owned by a role group no longer grant stale memberships. The connector ships with four settings enabled by default that affect permission resolution: sync_users, sync_groups, sync_shares, and grant_access_using_hierarchies. Groups and share resolution require user data, so disabling sync_users also disables sharing and hierarchy resolution. These are stored on the source configuration.
If the integration user cannot read User.UserRoleId, role hierarchy and role-based sharing cannot be resolved and sync fails with Required User fields are not queryable: UserRoleId. See Troubleshooting.

Prerequisites

Before setting up the Salesforce connector:
  • Omni version with the Salesforce connector service running (Compose profile or connector name: salesforce)
  • Salesforce administrator access to create a user, generate a certificate, and create an External Client App
  • A reachable Omni callback URL for the per-user OAuth flow (HTTPS for non-local deployments)
  • A secure location for the RSA private key — never commit it or paste it into tickets or chat

Setup

Step 1: Create a dedicated Salesforce integration user

The native connector should not depend on an individual employee’s password or OAuth session.
  1. In Salesforce, open Setup → Users → Users and select New User.
  2. Create a dedicated user, for example Omni Salesforce Integration.
  3. Use a full Salesforce user license for the sync user. The Salesforce Integration user license cannot be granted role-hierarchy or user-visibility permissions, which breaks native sync.
  4. Keep the user active and note its username — you’ll enter it in Omni.
A sync user on the Salesforce Integration license cannot resolve UserRoleId/UserRole, so sync fails by default. Use a full Salesforce user license and grant access with the permission set below.

Step 2: Grant the connector read access

Grant the missing object and system permissions with a permission set:
  1. Setup → Users → Permission Sets → New. Label it e.g. Omni Connector Read. Leave License empty and save.
  2. Object Settings → Edit for each of Account, Contact, Opportunity, Lead, Case, and Task, and enable Read and View All Records.
  3. System Permissions → Edit and enable API Enabled, View All Data, View Roles and Role Hierarchy, and View All Users.
  4. Users → the integration user → Permission Set Assignments and add the permission set.
The ...Share objects (AccountShare, ContactShare, OpportunityShare, LeadShare, CaseShare) do not appear in Object Settings and cannot be granted individually. The connector reads them for per-document ACLs, so access must come from the parent object’s View All Records plus the View All Data system permission.
The Salesforce Integration user license rejects several permissions the connector’s default configuration needs (View Roles and Role Hierarchy, View All Users, and View All Data), and cannot read UserRoleId. In that case, configure the source to skip role and share resolution (grant_access_using_hierarchies: false, and sync_shares: false when the org uses role-based groups). Document permissions then fall back to record ownership and public grants, so share-based access is lost.

Step 3: Generate the JWT key pair

Generate an RSA private key and a matching self-signed public certificate outside the repository:
Keep privatekey.pem secret. Only the public certificate (server.crt) is uploaded to Salesforce.

Step 4: Create the Salesforce External Client App

4a. Create the app

  1. In Salesforce, open Apps → External Client Apps → External Client App Manager and select New External Client App.
  2. Set the app name to Omni, set the contact email, and keep the distribution state Local for an org-local app.
External Client App Basic Information

Basic Information for the Omni External Client App

4b. Set the callback URL and OAuth scopes

  1. Enable OAuth and set the callback URL to your Omni OAuth callback, e.g. https://your-omni-domain/api/oauth/callback.
  2. Add the OAuth scopes required for the integration:
    • Access the identity URL service (id, profile, email, address, phone)
    • Manage user data via APIs (api)
    • Manage user data via Web browsers (web)
    • Perform requests at any time (refresh_token, offline_access)
    • Access unique user identifiers (openid)
    • Access Salesforce hosted MCP servers (mcp_api)
External Client App OAuth settings and scopes

Consumer Key and Secret, callback URL, and selected OAuth scopes

4c. Enable the flows and upload the certificate

In OAuth settings → Flow Enablement, enable Authorization Code and Credentials Flow for per-user OAuth and JWT Bearer Flow for the native connector, then upload the public certificate generated in step 3.
External Client App flow enablement and certificate

Flow Enablement with the JWT bearer certificate uploaded

Under Security, keep Require Proof Key for Code Exchange (PKCE), refresh-token rotation, JWT-based access tokens for named users, and Salesforce’s enforced idle refresh-token limit enabled.
External Client App security settings

Security settings for the External Client App

4d. Configure the authorization policy

Open the Policies tab and configure the permitted profiles. Admin approved users are pre-authorized is recommended; add the profiles that may authorize the app, including the sync user’s profile.
External Client App profiles policy

App Policies with pre-authorized profiles

4e. Set the permitted-user OAuth policy

In OAuth Policies → Plugin Policies, keep the Permitted Users policy aligned with your organization’s security requirements and leave the OAuth Start URL empty unless the org has a specific start page.
External Client App OAuth policies

OAuth Policies with the permitted-user policy

4f. Review app authorization

Under App Authorization, confirm the refresh-token policy and validity, IP relaxation, and named-user JWT settings match your organization’s requirements.
External Client App authorization settings

App Authorization settings

After saving, open Consumer Key and Secret and copy the values into a secure password manager or deployment secret store. Do not commit them or include them in screenshots.

Step 5: Connect the Salesforce source in Omni

  1. Open Settings → Integrations and select Connect for Salesforce.
  2. Choose External Client App (JWT) and enter:
    • Consumer Key: the External Client App’s client ID
    • Private Key (PEM): the RSA private key from step 3
    • Username: the dedicated integration user
    • Login URL: https://login.salesforce.com for production or https://test.salesforce.com for a sandbox
    • Instance URL: the exact Salesforce instance URL, used to bind the source to the intended organization
  3. Select Connect, leave the source enabled, and choose a sync interval.
Omni Salesforce source settings

Salesforce source settings

Once connected, Salesforce appears under Organization Integrations as an enabled source with Sync and Settings controls:
Omni integrations list with Salesforce

Salesforce listed as an enabled source in the integrations list

An Access Token mode is also available for quick trials. It accepts a static session or OAuth access token, expires within hours, and cannot be used for MCP — MCP requires an External Client App.

Step 6: Configure the source-scoped MCP OAuth client

MCP OAuth is configured separately from the native JWT source credentials:
  1. From the Salesforce source settings page, select Configure MCP OAuth client.
  2. Enter the External Client App’s Client ID and Client Secret.
  3. Leave the DCR initial access token blank when using a pre-created External Client App. Salesforce Dynamic Client Registration is an alternative that requires an administrator-issued initial access token.
  4. Save the configuration.
The MCP client is stored for this Salesforce source only. It is not an org-wide credential and is not shared with other Salesforce sources. Until it is configured, Salesforce MCP tools do not appear in chat.

Step 7: Authorize each user’s Salesforce MCP access

Every Omni user who uses Salesforce MCP tools authorizes Salesforce separately:
  1. Start an MCP action from an Omni chat, or use the Salesforce authorization action when Omni presents it.
  2. Follow the Salesforce OAuth redirect and sign in as the intended Salesforce user.
  3. Complete any identity verification or MFA Salesforce requests, approve the scopes, and return to Omni through the callback.
The resulting credential is stored for the combination of Omni user and Salesforce source. If it is missing, revoked, expired, or belongs to another Salesforce org, MCP access fails closed and asks for authorization again.

Managing the Integration

Changing the synced objects, fields, or permission-affecting settings forces a full reconciliation on the next run, which removes stale permissions and attributes.

Search Operators

Once the source is running, these operators work in Search and Chat:

Native Actions

These actions use the org JWT credential and are available to the assistant: Write actions require confirmation in interactive chat and respect the source’s read-only policy and any action authorization configured for the deployment.

MCP Tools

Salesforce MCP tools run through Salesforce’s official MCP server using each user’s own OAuth credential, so results respect that user’s Salesforce permissions. The connector exposes the read-only catalog it enables — get_username, list_all_orgs, and run_soql_query. Any other discovered tool is classified as write and is withheld unless write authorization is granted for the source. A typical request asks for a specific tool and SOQL explicitly:

Troubleshooting

The integration user’s profile or permission set does not expose the CRM objects. Grant Read and View All Records on Account, Contact, Opportunity, Lead, Case, and Task as described in Step 2. MCP success does not prove native sync works — they use separate credentials.
The sync user cannot read role data. View Roles and Role Hierarchy is required whenever grant_access_using_hierarchies is enabled (the default) or role-based sharing is in effect. The Salesforce Integration user license rejects this permission — authenticate native sync as a user with a full Salesforce license, or disable hierarchy and share resolution.
Confirm the source-scoped MCP OAuth client is configured (client ID and secret) and that the signed-in user has authorized Salesforce. A missing, revoked, or expired per-user credential fails closed and must be re-authorized.
The source’s Instance URL and login URL must match the org the user is authorizing. The connector validates that the OAuth credential’s instance belongs to the same Salesforce organization as the source.
Permission and share changes are reconciled on sync. Trigger a manual sync after changing profiles, permission sets, roles, or sharing rules, and confirm the run completes without errors.

Security Considerations

  • Separate identities: native sync and native actions use the org JWT credential; MCP tools use each user’s own OAuth credential. The org JWT is never an MCP fallback.
  • Least privilege: limit the integration user’s object and system permissions to what Omni must sync.
  • Secret handling: never commit the private key, consumer secret, access tokens, refresh tokens, or MFA codes, and never capture the Consumer Key and Secret page.
  • Credential storage: source credentials and per-user OAuth credentials are encrypted at rest in Omni.
  • Read-only option: the source can be set read-only, which removes write-capable actions including write-classified MCP tools.
  • Rotation: revoke and recreate credentials in both Salesforce and Omni if a secret is exposed.

What’s Next

Search Your Data

Search CRM records alongside your other sources

Access Control

Understand how Salesforce sharing becomes Omni permissions

Connector Management

Monitor syncs and manage the source