Authentication & Flow
Frontend Integrations can be created at https://accounts.salesloft.com/frontend_integrations. Users will see the name and description of your integration in the Salesloft application, so these fields should be descriptive of your company and integration.
Icon support is coming soon, and will involve having multiple sizes and versions of your icon for the different locations in the Salesloft application.
Installing an Integration
Users install integrations through the Salesloft Marketplace. Once installed, integrations become visible in the Salesloft application, but are not yet active. Users must enable the integration, which will go through a modified OAuth flow. In the development process, a link to install the integration will be visible at the bottom of the setup page.
Only certain users have permission to install and enable an integration. While this defaults to team admins, it can be configured through custom roles and permissions.
Enabling an Integration
The following flow occurs when a user enables your integration:
- 1. User toggles enable switch
- 2. User is redirected to your auth redirect URL, with return_to specified
- 3. Your server proceeds through the "code" OAuth flow
- 4. Your server receives an access_token, refresh_token, secret, integration_id, tenant_id
- 5. Secret is stored in such a way that it can be found when given an integration_id and tenant_id
- 6. User is redirected to the return_to URL
A modified OAuth flow is used to enable an integration. Once the user toggles the enable switch, they are redirected to your auth redirect URL, with a return_to parameter set. Your auth redirect URL should proceed through the OAuth flow directly, or show a setup interstitial as needed.
The modification to the OAuth flow is in the additional data returned. This is accessed at the same point that the access_token and refresh_token are accessed.
Iframe Flow
Salesloft will POST to your iframe URL for the type of slot that the integration will appear in. Salesloft issues a POST to avoid data sizing issues and to prevent sensitive information from appearing in your logs as query parameters. The POST will include different information depending on the type of integration.
Information included in the main POST body is (but not limited to additions over time):
- payload - A JWK encrypted payload. See below for details
- tenant_id - Plaintext ID of the tenant, allowing for secret lookup
- integration_id - Plaintext ID of the integration, allowing for secret lookup
- origin - URL that can be used when calling postMessage, allowing for higher security in different environments
Information included in the encrypted payload will include the following fields, which could be added to over time:
- Always included - integration_id, tenant_id, user_guid
- full_page - no additional payload
- custom_action - nonce(always), action (always), person (always), account (as applicable)
- email_editor - nonce(always), person (as applicable), account (as applicable)
- people_page - nonce(always), person (always), account (as applicable)
- account_page - nonce(always), account (always)
- origin
Each integration type is explained in more detail below.
Decrypting the Payload
Salesloft will post a payload to your iframe URL which includes the above properties. The payload is always decrypted the same way regardless of the contents of the payload.
The payload is a JWK encrypted string which is not readable without a shared secret. The shared secret is the SHA256 hash of the secret provided to your integration in the OAuth flow. This allows the secret to be 256 bits even if the provided secret is not 256 bits. The JWK token "alg" is A256GCMKW and "enc" is A256GCM.
Most languages provide an off the shelf way to decrypt this JWK payload. For example, Ruby, Elixir, Node.js, PHP, and Java all provide JWK decryption implementations. One important thing to note is that your language may require that the SHA256 hash of the secret is base64 encoded. This will vary between languages and implementations. You can view our Ruby decryption code in our Demo Integration.
The flow for decrypting the payload is as follows:
- 1. Receive a request with tenant_id, integration_id, and payload
- 2. Find the secret based on the tenant_id / integration_id pair
- 3. Compute the SHA256 hash of the secret
- 4. Use your language's JWK decryption library with the payload and the SHA256 hash of the secret
- 5. If the above fails, evaluate if your language only accepts a base64 encoded secret
- 6. Extract the information needed out of the payload
Frontend postMessage API
Certain integration types allow for postMessage to be used to affect the application. A nonce is required when making these calls and is obtained in the secure payload of the request. The calling page's domain will be https://app.salesloft.com, but other site support may be added over time in Salesloft Connect Chrome extension. Due to this, the origin that invoked the iframe is securely passed as a parameter and this origin should be used for any postMessage calls.
Only send your postMessage APIs to window.parent at the current time. This ensures that only the iframe's parent page will receive the message.