---
title: "Set up Salesforce and DWS signing integration"
canonical_url: "https://www.nutrient.io/guides/salesforce-documents/admin-guide/setup-signing-integration-with-dws/"
md_url: "https://www.nutrient.io/guides/salesforce-documents/admin-guide/setup-signing-integration-with-dws.md"
last_updated: "2026-05-23T00:08:18.147Z"
description: "Configure one-time Salesforce administrator setup for Nutrient signing: outbound API authentication to DWS and inbound DWS webhook delivery back to Salesforce."
---

# Set up signing integration (Salesforce and DWS)

This guide walks Salesforce administrators through the one-time configuration required to enable signing in Nutrient Documents app for Salesforce.

The setup has two parts:

1. **Outbound** — Salesforce calls the DWS API (create envelopes, upload documents, cancel envelopes).

2. **Inbound** — DWS sends webhook events back to Salesforce (for example, `envelope_completed`, `signer_signed`).

## Who should use this guide

Use this guide if you’re a Salesforce administrator or implementation owner configuring signing for your organization.

## Prerequisites

Before you start, ensure you have:

- Admin access to your Salesforce organization

- The Nutrient package installed in Salesforce

- Access to DWS Signer and an API key

- A dedicated Salesforce integration user for webhooks (recommended)

If you need the Salesforce installation link, DWS Signer dashboard access, or a DWS Signer API key, [contact our Sales team](https://www.nutrient.io/contact-sales/?=sdk).

## Part A — Connect Salesforce to DWS API (outbound)

Create an external credential and a named credential so Salesforce can authenticate callouts to DWS.

### 1. Create an external credential

1. Click **Setup** > **Named Credentials** > **External Credentials**.

2. Click **New**.

3. Enter the label/name (example: `NutrientDWSSigning`).

4. Set **Authentication Protocol** to `Custom`.

5. Save.

### 2. Create a named credential

1. Click **Setup** > **Named Credentials** > **Named Credentials**.

2. Click **New**.

3. Enter the label/name and URL:
   - `https://api.nutrient.io`

4. Select the external credential you just created.

5. Enable:
   - **Generate Authorization Header**
   - **Allow Formulas in HTTP Header**

6. Save.

### 3. Store the API key and set the authorization header

1. Open the external credential from step 1.

2. In **Principals**, click **New**.

3. Create a `Named Principal` (parameter name example: `Signing Key`).

4. Add the authentication parameter:
   - **Name** — `APIKey`
   - **Value** — your DWS Signer API key

5. Save.

6. In **Custom Headers**, click **New** and add:
   - **Name** — `Authorization`
   - **Value** — `Bearer {!$Credential.NutrientDWSSigning.APIKey}`
   - **Sequence Number** — `1`

7. Save.

### 4. Grant external credential principal access

Users who execute signing callouts must be granted access to the external credential principal.

For a first-time setup/test organization, assign access directly on the packaged permission sets:

1. Go to **Setup** > **Users** > **Permission Sets**.

2. Find and open these permission sets one by one:
   - `Nutrient_Admin`
   - `Nutrient_Sign_Documents`
   - `Nutrient_Signing_Integration`

3. In each permission set, open **External Credential Principal Access** > **Edit**.

4. Move `NutrientDWSSigning - Signing Key` from **Available External Credential Principals** to **Enabled External Credential Principals**.

5. Save.

For production durability, use org-local permission sets and permission set groups:

1. Create an org-local permission set (example: `Nutrient DWS Credential Access`).

2. In that permission set, enable **External Credential Principal Access** for `NutrientDWSSigning`.

If the webhook integration user is an API integration-only user, also grant read access to **User External Credentials**:

> **Security recommendation** — Don’t use an administrator as the integration user. Use a dedicated API integration user with minimum required permissions, including explicit **User External Credentials** read access for DWS callouts.

1. Create another org-local permission set (example: `Nutrient UserExternalCredentials Access`).

2. In `Nutrient UserExternalCredentials Access`:
   - Assign license **Salesforce API Integration**.
   - Navigate to **Object Settings** > **User External Credentials** and grant **Read** access.
   - Save.

Then create permission set groups to bundle assignments:

1. Navigate to **Setup** > **Permission Set Groups** > **New**.

2. Create the group (for example, `Nutrient Admin with DWS`) and save.

3. Add the required permission sets to the group.

4. Open the group and click **Manage Assignments**.

5. Click **Add Assignment**.

6. Find the target user(s), select them, and click **Assign**.

7. Verify the users now appear in the assignment list.

8. Repeat for the other groups based on the roles in the table below.

Recommended groups:

| Group                       | Permission Sets                                                                                               | Assign to                 |
| --------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------- |
| `Nutrient Admin with DWS`   | `Nutrient_Admin` + `Nutrient DWS Credential Access`                                                           | Administrative users      |
| `Nutrient Signing with DWS` | `Nutrient_Sign_Documents` + `Nutrient DWS Credential Access`                                                  | Regular signing users     |
| `Nutrient Webhook with DWS` | `Nutrient_Signing_Integration` + `Nutrient DWS Credential Access` + `Nutrient UserExternalCredentials Access` | Webhook integration users |

Package redeployments can reset direct grants on packaged permission sets. Use org-local permission sets and permission set groups to avoid repeating setup.

### 5. Select named credential and signing user in Nutrient tab

1. Open the **Nutrient Documents** app in Salesforce.

2. Go to the **Nutrient Admin** tab.

3. In **Named Credential for Nutrient Signing**, select the named credential created above.

4. In **Signing Integration User**, select the integration user.
   - If this user isn’t ready yet, complete **Part B, Step 1** first.

5. Save.

6. Click **Test Connection** and verify it succeeds.

## Part B — Configure DWS webhooks to Salesforce (inbound)

DWS webhooks authenticate into Salesforce using OAuth 2.0 JWT Bearer Flow through an **External Client App**.

### 1. Prepare a dedicated integration user

Create or use a dedicated system user with:

- **User License** — `Salesforce Integration`

- **Profile** — `Minimum Access - API Only Integrations`

Assign the **Nutrient Webhook with DWS** permission set group.

Assign the webhook permission set group before testing connection in Nutrient Admin or enabling Salesforce integration in DWS.

### 2. Generate a key pair for JWT signing

JWT Bearer Flow requires an X.509 certificate (public key) and a matching private key.

Run:

```bash

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout dws_jwt_private.pem \
  -out dws_jwt_certificate.crt \
  -subj "/CN=DWS Signer Integration/O=Your Company"

```

Use the generated files as follows:

- `dws_jwt_certificate.crt` — Upload to Salesforce External Client App

- `dws_jwt_private.pem` — Paste into DWS Salesforce integration settings

- Keep `dws_jwt_private.pem` secure. Do not commit it to source control.

- The generated certificate expires after the number of days passed to `-days` (for example, `365`). Plan to rotate the certificate before expiry.

### 3. Configure the external client app for the JWT bearer flow

In Salesforce setup:

1. Open **External Client App Manager**.

2. Click **New External Client App**.

3. Fill basic information:
   - **Name** — `DWS Signer Integration`
   - **Contact Email** — admin email
   - **Distribution State** — `Local`

4. Enable OAuth and set:
   - **Callback URL** — `https://login.salesforce.com/services/oauth2/callback`
   - **Selected OAuth Scopes**:
     - `Manage user data via APIs (api)`
     - `Perform requests at any time (refresh_token, offline_access)`

5. Under **Flow Enablement**, enable **JWT Bearer Flow** and upload your public certificate (`.crt`).

6. Click **Create**.

7. Open the created app and go to the **Settings** tab.

8. In **OAuth** > **Consumer Key and Secret**, copy the **Consumer Key** (this is the client ID for DWS).

9. Open the **Policies** tab and click **Edit**.

10. In **OAuth Policies**, set **Permitted Users** to **Admin approved users are pre-authorized**.

11. In **App Policies** > **Permission Sets**, add **Nutrient\_Signing\_Integration**.

12. If **Start URL** is required in your organization, set a valid organization URL (for example, `https://your-domain.my.salesforce.com/lightning/page/home`).

13. Save.

### 4. Configure the webhook destination in DWS Signer dashboard

In the [DWS Signer dashboard](https://dashboard.nutrient.io/signer/):

1. Open Salesforce integration configuration from the left navigation panel.

2. Fill OAuth fields:
   - **Salesforce Instance URL** — Your Salesforce **My Domain URL** (for example, `https://your-domain.my.salesforce.com`)
   - **Username** — Salesforce integration user username
   - **Consumer Key (Client ID)** — Copied from External Client App settings
   - **Private Key (PEM format)** — Matching private key for the uploaded certificate

3. Set **Webhook Endpoint** to `/services/apexrest/dwss-webhook`.

4. Enable event subscriptions (for this app, select all events except `envelope_created`).

5. Save/enable and confirm the integration validates.

For **Salesforce Instance URL**, use the **My Domain** URL (`*.my.salesforce.com`). To find it, go to **Setup**, search **My Domain** in Quick Find, and copy **My Domain URL**. Do not use the Lightning URL (`*.lightning.force.com`) or Setup URL (`*.salesforce-setup.com`).

## Validate the setup

Run this checklist after setup:

- **Test Connection** in Nutrient Admin succeeds

- A signing-enabled user can create/send an envelope from Salesforce

- Recipient can open the signing session and sign

- Envelope status updates appear in Salesforce after webhook events (for example, status becomes `Completed`)

- No auth/callout errors are shown in Salesforce logs

## Troubleshooting

The following are common issues and resolutions.

### Callout fails with auth errors

- Confirm the named credential URL and selected external credential.

- Verify `APIKey` value is present.

- Verify the `Authorization` header formula uses the correct credential name.

- Confirm principal access is granted to the user executing the callout.

### DWS enable fails with OAuth credential validation failed

- Confirm **Salesforce Instance URL** uses My Domain (`*.my.salesforce.com`), not Lightning URL (`*.lightning.force.com`).

- Confirm the **Consumer Key** is copied from the same external client app where the JWT Bearer Flow was configured.

- Confirm the pasted private key matches the uploaded certificate.

- Confirm the uploaded certificate hasn’t expired. If expired, generate a new key pair, upload a new certificate to the external client app, and update the private key in DWS.

- In the external client app **Policies**, set **Permitted Users** to **Admin approved users are pre-authorized**.

- In **App Policies** > **Permission Sets**, add **Nutrient\_Signing\_Integration**.

### Send fails with salesforce_integration_not_found

- Confirm the correct **Named Credential for Nutrient Signing** is selected in Nutrient Admin.

- In shared or preconfigured organizations, multiple named credentials may exist — pick the credential mapped to the active tenant/environment.

- If needed, ask the DWS team to enable Salesforce integration for your tenant/organization pairing.

### Webhook events aren’t updating Salesforce

- Confirm the DWS webhook endpoint URL is correct (`/services/apexrest/dwss-webhook`).

- Verify the JWT Bearer Flow app configuration and key pair.

- Confirm the integration user is API-only and assigned the required permission set group.

### Works for administrators but fails for regular users

- Regular users likely lack external credential principal access.

- Recheck the permission set group assignments for signing users.

## Security and operations recommendations

- Rotate DWS Signer API keys regularly.

- Rotate Salesforce JWT certificates before expiration (for example, every 90–180 days based on your policy).

- Track certificate expiration dates with reminders or monitoring.

- During certificate rotation, overlap credentials to avoid downtime (upload the new certificate before removing the old one, and then update the DWS private key).

- Keep webhook integration users dedicated and least-privileged.

- Retest webhook delivery after package upgrades or auth changes.

## Related guide

If your team also needs end user document generation instructions, refer to [create documents in Salesforce](https://www.nutrient.io/guides/salesforce-documents/end-user-guide/create-documents.md).