---
title: "Salesforce access for CRM migration & audit — Rig guide"
description: "Grant Rig least-privilege, whole-org Salesforce API access for a CRM audit or migration: a free Integration user, the Salesforce API Integration permission set, and a Client Credentials app — no admin login, no new paid license."
canonical: "https://rig.so/guides/connect-salesforce-migration"
format: markdown
---

Search guides, references, playbooks…⌘K

Browse guides

# Salesforce Access for CRM Migration & Audit Clients

For a CRM audit or migration, Rig needs API access to read your whole Salesforce org — every object, field, automation, and usage signal — and (only if you approve an execution phase) to write approved changes back. This guide sets that up with **least privilege and no new paid license**. It's the recommended pattern for systems-integrator-style engagements and differs from the basic single-connector setup.

## Key principle: don't use an admin or a paid seat

The easy-but-wrong path is granting a System Administrator login. Instead use the free **Salesforce Integration user license**: Enterprise, Unlimited, and Performance editions include **5 at no cost** (Developer Edition includes 1; more are inexpensive via your Salesforce AE). It's API-only — no UI login — exactly right for an integration.

## Step 1: Create a dedicated integration user

1. In Salesforce, go to `Setup` → `Users` → `New User`.
2. Set **User License = Salesforce Integration**. This auto-assigns the `Minimum Access – API Only Integrations` profile — API-only, with no object access yet.
3. Use one dedicated user per integration.

## Step 2: Assign the permission set license

On that user's detail page, go to `Permission Set License Assignments` → `Edit` and enable **Salesforce API Integration**. This permission set license (PSL) contains the admin-equivalent permissions, grantable via a permission set in the next step.

## Step 3: Create and assign a permission set

Go to `Setup` → `Permission Sets` → `New`.

⚠️ Get the License field right
Set **License = "Salesforce API Integration"** — NOT `--None--`, and NOT the look-alike *"Salesforce Integration"*. Getting this wrong silently hides objects, and it's the #1 cause of access failures. Only the entry with **API** in the middle unlocks CRM objects.

In `System Permissions`, enable:

- **For a read-only audit**: `View All Data` + `View Setup and Configuration` (`API Enabled` is automatic). View All Data grants read on every object's records in one switch — no per-object clicking; View Setup and Configuration unlocks the Metadata/Tooling API used to map the schema and dependency graph.
- **For write-back / migration execution** (only if you approve that phase): also add `Modify All Data` + `Modify Metadata Through Metadata API Functions`.

Then assign the permission set to the integration user.

## Step 4: Create an OAuth app (Client Credentials Flow)

Use either a classic **Connected App** (`Setup` → `App Manager` → `New Connected App`) or the newer **External Client App** (`Setup` → `External Client App Manager` → `New`).

1. Enable OAuth and add three scopes. Salesforce presents these as a picklist, so select each one:
   
     - `Full access (full)`
     - `Manage user data via APIs (api)`
     - `Perform requests at any time (refresh_token, offline_access)`
2. Enable the **Client Credentials Flow** and set **Run As = the integration user** from Step 1.
3. For an **External Client App**, also enable the flow on the `Policies` tab — not just `Settings`.
4. Open the app's consumer details and copy the **Consumer Key** and **Consumer Secret**.

## Step 5: Send Rig three values

- The **Consumer Key**.
- The **Consumer Secret**.
- Your **My Domain URL**, from `Setup` → `My Domain`. It looks like this:
  
  `https://yourorg.my.salesforce.com`Copy

## Step 6 (recommended): Lock it down

Restrict the app/profile **Login IP Ranges** to Rig's published egress IPs so the credentials only work from Rig's infrastructure.

## Troubleshooting

| Error | What it means | Fix |
| --- | --- | --- |
| `invalid_grant: no client credentials user enabled` | The app has no Client Credentials run-as user. | Enable Client Credentials Flow AND set Run As on the exact app whose Consumer Key you shared. For External Client Apps, check the `Policies` tab too. |
| `invalid_client_id: client identifier invalid` | Wrong or truncated Consumer Key, or copied from a different app. | Re-copy the full Consumer Key. Brand-new app credentials can take a few minutes to propagate. |
| `INVALID_TYPE` / "sObject type 'X' is not supported" | The integration user can't see that object. | Confirm the permission set's License is `Salesforce API Integration`, it's assigned to the user, and `View All Data` is enabled. |

## Full-license alternative

If you prefer to reuse an existing licensed user instead of the free Integration user, a plain permission set (`License = --None--`) with the same System Permissions works identically. The dedicated free Integration user is simply the cleaner least-privilege choice.

## What people use this for

- Analyse pipeline velocity and stage conversion
- Forecast more accurately from real opportunity data
- Score account health and expansion potential
- Audit data quality and rep activity

[More ideas for using Salesforce](https://rig.so/integrations/salesforce)

Was this guide helpful?

Yes No

---

- [This page as HTML](https://rig.so/guides/connect-salesforce-migration)
- [Site map for language models](https://rig.so/llms.txt)
- [API and agent documentation](https://rig.so/developers)
