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 SetupUsersNew 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 AssignmentsEdit 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 SetupPermission SetsNew.

    ⚠️ 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 (SetupApp ManagerNew Connected App) or the newer External Client App (SetupExternal Client App ManagerNew).

    1. Enable OAuth and include the scopes Full access (full), Manage user data via APIs (api), and refresh_token.
    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 (SetupMy Domain — e.g. https://yourorg.my.salesforce.com).

    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

    ErrorWhat it meansFix
    invalid_grant: no client credentials user enabledThe 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 invalidWrong 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.

    Was this guide helpful?