# Salesforce Foundry's **Salesforce** connector allows you to sync data between Salesforce and Foundry datasets. :::callout{theme="warning"} This document refers to the latest version of the Salesforce connector. If you are editing an existing Salesforce connector, it may be a legacy version. Review the section on [migration](#migration) below for more information. ::: ## Supported capabilities | Capability | Status | |-------------|------------------------| | Exploration | 🟒 Generally available | | Bulk import | 🟒 Generally available | ## Data model The connector models all available [standard β†—](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm) and custom Salesforce objects as Foundry datasets. Schemas are retrieved dynamically. The exploration view allows you to browse the data model and preview how Salesforce objects would appear once imported to Foundry. ### Data type mapping The connector maps Salesforce API types to the following [Foundry field types](../../data-integration/datasets/index.md#supported-field-types): | Salesforce | Foundry | |------------------------------|---------| | Auto Number | STRING | | Lookup Relationship | STRING | | Master-Detail Relationship | STRING | | External Lookup Relationship | STRING | | Checkbox | BOOLEAN | | Currency | DECIMAL | | Date | DATE | | Date/Time | LONG | | Email | STRING | | Geolocation | STRING | | Number | DOUBLE | | Percent | DOUBLE | | Phone | STRING | | Picklist | STRING | | Picklist (Multi-Select) | STRING | | Text | STRING | | Text Area | STRING | | Text Area (Long) | STRING | | Text Area (Rich) | STRING | | Text (Encrypted) | STRING | | Time | INTEGER | | URL | STRING | ## Performance and limitations The connector leverages the [Salesforce Bulk API β†—](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/bulk_ingest.htm) by default, which is recommended for any data operation including more than 2000 rows. Read more about [Bulk API Limits β†—](https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_bulkapi.htm). The connector can optionally use the [Salesforce SOAP API β†—](https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_quickstart_intro.htm) when setting the JDBC property `UseBulkAPI` to `false`. The SOAP API is also subject to [Salesforce SOAP API Call Limits β†—](https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_apicalls.htm). ## Setup 1. Open the [Data Connection](../../data-connection/overview/index.md) application and select **+ New Source** in the upper right corner of the screen. 2. Select **Salesforce** from the available connector types. 3. Follow the additional configuration prompts to continue the set up of your connector using the information in the sections below. Learn more about [setting up a connector](../../data-connection/set-up-source/index.md) in Foundry. ## Authentication Select a credential method to authenticate your Salesforce connection: JWT token or username-password. :::callout{theme="warning"} Salesforce restricted the creation of new connected apps as of the Spring '26 release. Existing connected apps continue to work, and Salesforce recommends [external client apps β†—](https://help.salesforce.com/s/articleView?id=xcloud.external_client_apps.htm\&language=en_US) for new integrations. The sections below describe how to configure an external client app. Review the [Salesforce authorization documentation β†—](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_oauth_and_connected_apps.htm) for more information. ::: ### JWT token You can use the OAuth 2.0 [JSON Web Token (JWT) bearer flow β†—](https://help.salesforce.com/articleView?id=remoteaccess_oauth_jwt_flow.htm) to authorize Foundry to access data without interactively logging in on each request. To enable JWT authentication, you must generate a certificate, upload it while creating an external client app, then authorize the integration user. #### Part 1: Generate a certificate First, create a Salesforce user and verify it has access permission for APIs and any Salesforce objects you wish to modify. Be sure you are able to log in as the integration user, as you will need to authorize as this user in a future step. Now, create a JWT certificate. The Salesforce [JWT bearer flow β†—](https://help.salesforce.com/articleView?id=remoteaccess_oauth_jwt_flow.htm\&type=5) requires an X.509 certificate and the associated private key. To generate a private key, use `openssl` at the command line and run the following commands: 1. Generate the x.509 public and private key pair: ```bash openssl genrsa 1024 | openssl pkcs8 -topk8 -inform PEM -out key.pem -nocrypt openssl req -new -x509 -key key.pem -out cert.pem -days 3650 ``` 2. Export the certificate to a PFX store, convert to Base64, and copy to clipboard: ```bash openssl pkcs12 -export -in cert.pem -inkey key.pem | openssl base64 | pbcopy ``` :::callout{theme="warning"} Be sure to save the certificate value in a secure location. You will need to access the value later in the [configuration](#part-3-authorize-user). ::: #### Part 2: Create an external client app If your Salesforce organization already has a working connected app for this connector, you can continue to use it. Salesforce restricted the creation of new connected apps but did not disable existing ones. For an existing connected app, review the [Salesforce guidance on managing OAuth access β†—](https://help.salesforce.com/articleView?id=connected_app_manage_oauth.htm\&type=5). Before you begin, confirm that external client apps (formerly connected apps) are enabled for your Salesforce organization. Your Salesforce user must also be permitted to create external client apps and to edit their policies. Create the app by following the Salesforce documentation on [creating an external client app β†—](https://help.salesforce.com/s/articleView?id=xcloud.create_a_local_external_client_app.htm\&language=en_US), or the Trailhead unit [Create and Configure an External Client App for API β†—](https://trailhead.salesforce.com/content/learn/projects/build-integrations-with-external-client-apps/create-and-configure-an-external-client-app). Only the settings listed below affect this connector; leave the remaining sections of the creation form at their defaults. When you are finished, the app must have: * **OAuth enabled:** The connector authenticates through OAuth, so an app without OAuth turned on cannot be used. * **A callback URL of `https://localhost:12345`:** Salesforce requires a callback URL, but the connector never sends one. Use this value so that it matches the browser authorization option in [Part 3](#part-3-authorize-user). * **The X.509 certificate from [Part 1](#part-1-generate-a-certificate) uploaded:** Upload the `cert.pem` file. Uploading a certificate is what enables the JWT bearer flow. There is no separate setting that turns the flow on. * **OAuth scopes:** Grant `api`. Grant `offline_access` and `refresh_token` as well, but only if you intend to use the browser authorization option in [Part 3](#part-3-authorize-user). Retrieve the consumer key of the app and store it in a secure place. You will enter this value as `Consumer key` in the connector configuration below. The key is hidden until you reveal it, and Salesforce may ask you to confirm a verification code sent to your email address before showing it. The connector sends the consumer key inside the signed JWT, so you do not need the consumer secret that Salesforce issues alongside it. :::callout{theme="warning"} Do not confuse the JWT bearer flow with the **Issue JSON Web Token (JWT)-based access tokens for named users** setting on the app. That setting changes the format of the access tokens that Salesforce issues, and this connector does not require it. ::: A new external client app may not be usable immediately. If authentication fails shortly after you create the app, wait up to 30 minutes and retry before you change the configuration. #### Part 3: Authorize user The integration user must be authorized for the external client app before the connector can use it. Pre-authorization is the recommended option, because the connector authenticates with a signed JWT and never exchanges the authorization code that the browser flow produces. * **Pre-authorize the user:** In the OAuth policies of the app, set **Permitted Users** to **Admin approved users are pre-authorized**. Then, grant the integration user access through the Profile assigned to that user, or through a Permission Set that includes that user. The policy alone does not authorize the user without that grant. Review the [Salesforce external client app documentation β†—](https://help.salesforce.com/s/articleView?id=xcloud.external_client_apps.htm\&language=en_US) for the available policy values. * **Perform a one-time authorization:** Complete the Salesforce login flow once in a browser as the integration user. This option requires that the app also has the `offline_access` and `refresh_token` scopes: 1. Navigate to the following Salesforce URL: `https:///services/oauth2/authorize?client_id=`**``**`&redirect_uri=`**``**`&scope=api%20offline_access%20refresh_token&response_type=code&response_mode=query&nonce=bebmwgu22zh` * Replace `` with your consumer key and `` with the callback URL configured on the app. * Replace `` with your Salesforce instance URL (`.my.salesforce.com`). 2. Complete the login flow and approve the requested scopes. Confirm that the username shown is the integration user and not your personal account. Authorizing the wrong user produces a connector that appears to work and then fails on the permissions of the wrong user. 3. Expect the browser to finish on a "Not Found" error at `https://localhost:12345`. The callback URL is not a real endpoint, so that error indicates the flow completed. Continue setting up a Salesforce connector in Foundry using the JWT authentication configuration options below: | Name | Required | Description | |--- |--- |---| | `This is a Salesforce sandbox account` | Yes | Determines if the connection should be made to a Salesforce sandbox account. Sets the default value for `Login URL`: `login.salesforce.com` for standard accounts and `test.salesforce.com` for sandbox accounts. | | `Username` | Yes | Enter the username of the integration user. | | `Base64 PFX certificate` | Yes | Value obtained from [generating a certificate](#part-1-generate-a-certificate).| | `The certificate is password protected` | No | Toggle on if the certificate store is password protected.| | `Certificate password` | No | The certificate store password. | | `Specify the certificate subject` | No | Leave off to use the first certificate in the store. Toggle on to specify a certificate to use if the certificate store contains multiple certificates. | | `Certificate subject` | No | The subject of the desired certificate. Used to locate the certificate in the store . If an exact match is not found, the store is searched for a certificate whose subject contains the supplied value. | | `Consumer key` | Yes | Enter the consumer key available in the settings of the [external client app](#part-2-create-an-external-client-app).| ### Username-password To connect to Salesforce with the [username-password β†—](https://help.salesforce.com/articleView?id=remoteaccess_oauth_username_password_flow.htm) authentication method, you must create a service user account and an external client app in Salesforce. Then, add the service user credentials into the Salesforce connector. Follow the steps below to enable the username-password authentication flow. 1. Create a Salesforce user and verify it has access permission for APIs and any Salesforce objects you wish to modify. Note the user’s username and password for future reference. 2. Create an external client app, following [Part 2](#part-2-create-an-external-client-app) with these differences: * No certificate is required. * Grant the **Full access (full)** OAuth scope instead of `api`, so that the app can access all data available to the active user. * In the OAuth policies of the app, set **Permitted Users** to **All users may self-authorize**. * No consumer key is required. This authentication method uses only the username and password that you configure below. The username-password authentication method supports the following configuration options: | Name | Required | Description | |--- |--- |---| | `This is a Salesforce sandbox account` | Yes | Determines if the connection should be made to a Salesforce sandbox account. Sets the default value for `Login URL`: `login.salesforce.com` for standard accounts and `test.salesforce.com` for sandbox accounts. | | `Username` | Yes | The username of the account that the app is imitating. | | `Password` | Yes | The password of the account that the app is imitating. | :::callout{theme="warning"} If you experience authorization problems when trying to connect from Foundry and see `Failed: API security token required` in the **Salesforce Login History** of the user, you must add the user's security token to the end of the password. The security token is an automatically generated key that must be added to the password to log in to Salesforce from an untrusted network. Salesforce does not allow users to view the security token within the application; instead, you must log in to Salesforce as the *integration user* and navigate to **My Settings** in the top right corner. Then, navigate to **Personal > Reset My Security Token**. ::: ### Networking If a direct connection is running your Salesforce connector, you must add a [network egress policy](../../administration/configure-egress/index.md) to allowlist the connection. Choose to add an existing policy, or create a new policy. To allowlist a direct connection for Salesforce, add the following policies: * Login URL: Requires `DNS`, port `443` (HTTPS), and one of the following: * `login.salesforce.com` (production) **OR** * `test.salesforce.com` (sandbox) * Instance URL: Requires `DNS` for `.my.salesforce.com`, port `443` (HTTPS). ### Certificates and private keys SSL connections validate server certificates. Normally, SSL validations happen through a certificate chain; by default, both agent and Foundry workers trust most industry-standard certificate chains. If the server to which you are connecting has a self-signed certificate, or if there is TLS interception during the validation, the connector must trust the certificate. Learn more about [using certificates in Data Connection](../../data-connection/set-up-source/index.md#optional-add-certificates). ## Configuration options The Salesforce connector supports the following configuration options: | Name | Required | Default | Description | |-----------------------------|-------------------------|------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------| | `API version` | Yes | 50 | The Salesforce API version. | | `Connected app credentials` | Yes | `JWT bearer token` | Contains credentials needed to connect to Salesforce. In Salesforce, these credentials are configured on an external client app. Review the [Authentication](#authentication) sections above for more information. | | `Login URL` | No | `login.salesforce.com` (production), or `test.salesforce.com` (sandbox) | The URL used to connect to retrieve OAuth tokens. | | `Timeout` | No | 60 | The duration of time before the HTTP client connection times out while waiting for a response. Time is in seconds. | | `Proxy settings` | No | No | The proxy configuration to use when connecting to Salesforce. | ## Sync data from Salesforce Use the [exploration view](../../data-connection/source-exploration/index.md) to sync tables. Additional configuration options are available when editing a sync. ### Incremental During incremental syncs with the Salesforce connector, new data is synced if the incremental column value is *greater than or equal* to the previous observed maximum value. This behavior, though required for precision and correctness of synced data, will lead to duplicate rows in the output dataset. Incremental pipelines should always contain a deduplication step. ### Filtering You can add row filters to a sync configuration to exclude data that does not fit a set criteria. Use the condition tree to define your filter: * Logical operators: * `ALL`: Requires all nodes nested beneath to be true. * `ANY`: Requires at least one of the nested nodes to be true. * Conditions: * Select from a list of available columns. * Depending on the column type, choose an appropriate operator. * Set a value to compare against the selected column. Be sure to **Save** your configurations to apply them to the sync. ## Migration If you already have a Salesforce connector, you may be running a legacy version. To identify your connector version, migrate to **Connection settings > Connection details**. If source configuration shows a **Custom YAML** section with a `type: salesforce` field, you are using a legacy Salesforce connector. You must migrate to the latest version to receive Palantir support beyond bug fixes. ### Migrate connector 1. Open the [Data Connection](../../data-connection/overview/index.md) application and select **+ New Source** in the upper right corner of the screen. 1. Select **Salesforce** from the available connector types. 2. Follow the additional configuration prompts to continue the set up of your connector using the information in the sections below. 2. Configure the authentication to match that of the legacy source. In the legacy source configuration, find the `auth-method` or `authentication-method` block in the custom YAML. * If `type: oauth2-jwt`, configure the new source with [JWT authentication](#jwt-token): * `claim-sub` from the custom YAML becomes `Username` in new connector configuration. * `x509-cert` is exported to PFX, then Base64 encoded and becomes `Certificate`. Learn more about certificates in the [JWT authentication](#jwt-token) section above. * If the PFX is password protected, toggle on `The certificate is password protected` and enter the `Certificate password`. * `claim-iss` from the custom YAML becomes `Consumer key` in the new connector configuration. * If `type: oauth2-username-password`, configure the new source with [username-password authentication](#username-password): * `username` from the custom YAML becomes `Username` in the new connector configuration. * `password` from the custom YAML becomes `Password` in the new connector configuration. * `client-id` and `client-secret` properties on the legacy source are *not* required by the new connector. 3. Configure other properties: * `auth-url` from the custom YAML becomes `Login URL` in the new connector configuration. * If `auth-url` had a value of `test.salesforce.com` in the custom YAML, toggle on `Is Salesforce sandbox account` in the new connector configuration. ### Migrate syncs After configuring a new Salesforce connector, create syncs for the objects that were previously synced by the legacy connector. Use the [exploration view](../../data-connection/source-exploration/index.md) to bulk sync multiple objects at once and create new datasets. If using the same API version, both the legacy and new Salesforce connectors will use the same schema; all downstream applications should continue to function if inputs are remapped. You must migrate downstream pipelines to use the new sync datasets. Once you have confirmed that no other consumers require the legacy datasets, you can delete the datasets, associated syncs, and connections. Use [Data Lineage](../../data-lineage/overview/index.md) to find where the legacy datasets are used in your environment.