If you are like me, you’ve been following best practices and assigning one user license to each of your third party integrations – especially those that cause some DML to occur in your org. Having a separate user license per integration:
- Allows for traceability in the Field History related list as well as the
CreatedBy
andLastModifiedBy
fields on your records. - Facilitates assigning the integration user only those permissions it needs to do its job via a Permission Set
Most AppExchange packages will include a Permission Set for what the package documentation typically calls a “service account user” dedicated to performing integration functions between the package and your org.
$$$$
Of course, if you’ve done this, you are paying full license price per integration for a non-human user that probably never uses the UX. But, after intense customer pressure (and I was there at Dreamforce in 2022 when Bret Taylor, then President of Salesforce , agreed to provide lower cost integration-only licenses to jubilation from the crowd), Salesforce delivered five (5) free integration-only licenses to every Enterprise Edition org and offered additional integration-only licenses for the low, low cost of $10/month each (2024 pricing).
Since no one likes spending more Salesforce subscription money than they have to, I was tasked with converting thirteen (13) integration users to our five free + eight (purchased, but cheap) Salesforce Integration licenses. I had to do the conversion before our annual subscription renewal so we could avoid paying another year of thirteen full price user seats (~$1800-2000 p.a.).
Starting Conditions
Being a good boy, many of my (full, expensive license) integration users were already set up with:
- Profile =
Minimum Access - Salesforce
- Permission Set
XXX-Integration
with requisite CRUD, FLS, and other permissions
The oldest integrations were set up with
- Profile =
MyCompany Integration User Profile
Modify All Data
and FLS on every field
- No Permission Set
Vendor Documentation Review
An advantage of doing this work in late 2023 was that many of our third party vendors already had documentation of their support for the Salesforce Integration license. A survey of their Knowledge Bases yielded:
- Supported with tips (a good example of this was OwnBackup)
- Explicitly not supported (Talkdesk as of January 2024)
- Silent
Those vendors that had nothing to say got a support case filed from me so I didn’t waste time deploying a migrated user license and having it fail or work mostly but not always.
Internal third parties were a bit easier as I could ask the product owners or do some reports and SOQL inside the org to gain insight.
Some Doubts (Alleviated)
Could I change a user with a full license to a Salesforce Integration license without destroying any OAuth tokens, passwords, etc?
A simple experiment proved that changing the Salesforce license of a user didn’t affect any authentication already established.
- A user with a Salesforce Integration license can still login to Salesforce (even though it does not have UX permissions)
- That user can change their password
- That user can even set up Two-Factor Authentication
The Nitty-Gritty
I started off in my dev environment.
Permission Sets
I developed a Permission Set that I called Universal API User System Permissions
. This contained every System Permission that I wanted every integration user to have (like API Enabled
, Access Activities
, Edit Tasks
, Edit Events
) You’ll decide what makes sense for your org.
For each Integration User, I either reviewed the existing permission set or created a new one. This contained all the CRUD, FLS, and other permissions that that integration user needed. Notably, it can not contain VisualForce Pages or Lightning Experience User
permissions (among others that involve UX features).
If creating a new one, be sure to not set the Permission Set’s license as Salesforce
. Instead, leave it blank.
User License
Then I changed the integration user’s License in Setup > Users
from Salesforce
to Salesforce Integration
. This has the effect of deleting all the permission set and permission set group assignments (but fortunately, leaving public group membership intact).
IMPORTANT – I then assigned the Salesforce API User
Permission Set License to the user. You have to do this before assigning Permission Sets. While it may have been obvious to the SFDC Product Manager, assigning a Permission Set License
to the user is not typically done as ordinary Enterprise Edition users get an implicit Permission Set License
. If you forget this step, you’ll get an error in assigning Permission Sets to the user – permission not supported for the Salesforce Integration
license.
Permission Set Assignment
I then assigned the two permission sets to the integration user.
Universal API User System Permissions
XXX-Integration
(whereXXX
was the name of the integration, e.g. Hubspot, OwnBackup, etc.)
At this point you may encounter errors
- Your permission set includes a permission that isn’t supported by the
Salesforce API User
permission set license. Remove that permission. - Your permission set isn’t listed in the available permission sets to assign(!). This happens if you started with a permission set that defined it was available only for
Salesforce
licenses (rather than blank).- You can’t edit a Permission Set to change its license. You can’t clone in the UX and change the license field.
- Your only option is to go to your IDE (or Workbench) and create a new
.permissionset
file with a new name, then- Copy-paste the old permission set XML into your new file
- Change the value of the
<label>...</label>
- Delete the XML for
<license>Salesforce</license>
- Then save (deploy) the new
.permissionset
file to your org.
- I also renamed the old, now useless Permission Set, with a suffix
(retired)
. This would get deleted later after final deployment and testing
Testing
In many orgs, including my own, you aren’t lucky enough to have staging versions for all or any of your third part integrations.
By careful study of what I knew the third party integration did (for example, Hubspot reads/edits Accounts, Contacts, Leads, Opportunities, and Tasks), I then
- Used Workbench (or Postman or equivalent) and logged into my org as the integration user.
- Composed REST requests to query and DML records, simulating what the third party app does (to the best of my knowledge)
- If you use Event Monitoring, you could examine the REST API logs to gain insight into the GETs, POSTs, PATCHes, and DELETEs used by the third party app.
- In some cases, based on the tests, I needed to revise the Permission Set (usually because I had forgotten some CRUD or FLS permission).
Deployment
Once dev testing was done, I used my DevOps tool (Gearset) to deploy the permission set(s) to the downstream branches and orgs in my pipeline.
- In each deployed org, you have to manually swap the integration user’s license to
salesforce Integration
, assign the Permission Set License, then assign the Permission Sets. - In some cases, I had staging 3rd party systems bound to my SFDC staging org. Here I could do true end-end testing.
Summary
This is just tedious work but rewarding once done as by converting thirteen full user licenses to Salesforce Integration
licenses, I saved my org probably $25,000 p.a. in subscription costs. A bonus was that each integration user got a full review of its permissions and where too permissive, I brought the hammer down, yielding a more secure configuration.
If you have an org where you’ve lumped all your integrations to share a common Salesforce user, this is a good opportunity to follow best practices and dedicate a free/cheap integration user license to each integration.
Disappointments
The disappointments were the vendors who didn’t support (as of January 2024) the Salesforce Integration user license:
- Talkdesk – The integration user needs access to Visualforce pages and tabs.
- Groove – For “reasons”
Special cases
Backup / restore integrations
If converting your integration user for backup/restore vendors, you’ll need to create a Permission Set that includes CRUD on every object you want to backup/restore + FLS on every field that you backup/restore + recordtype access (all).
Platform Event Publishers
One of our integrations only published Platform Events (via REST calls) to our org. Since Platform Events run by default as Automated Process User
(or configured to run as a Salesforce user), the integration user only needed CRUD on the XXX__e
objects. No FLS is necessary to publish Platform Events