Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[dreamOle26] How we handle Profiles and User Ac...

[dreamOle26] How we handle Profiles and User Access deployment

You’ve heard that you should ditch Profiles and move to Permission Set? Great. And then you start doing and you discover that all these nice theoretical blog articles only cover a part of a real life implementation. How to actually migrate? Retrieve and deploy what’s still only on Profiles? Create new Profiles with just the needed rights ? Clean Profiles from access that are now on Permission Set? Come and see how we handle these.

Avatar for Fabien Taillon

Fabien Taillon

March 27, 2026
Tweet

More Decks by Fabien Taillon

Other Decks in Programming

Transcript

  1. Fabien Taillon Paris Developer Group leader French Touch Dreamin team

    https://www.salesforce.com/trailblazer/fabien https://www.fabientaillon.com https://www.texei.com /in/fabientaillon @FabienTaillon Partner & CTO Texeï
  2. What do we want ? A reliable solution for managing

    and deploying user access rights
  3. Permission Set + Profiles Permission Sets are working fine BUT

    Profiles are still needed - Page Layout Assignments - Default Record Types - Default Custom App… And no one tells you how to handle that part
  4. We want to be clear that we won’t be making

    any improvements to profiles going forward. All of our efforts will be focused on permission sets, permission set groups, and related features Cheryl Feldman Senior Director of Product Management at Salesforce https://admin.salesforce.com/blog/2023/permissions-updates-learn-moar-spring-23
  5. Profile Retrieve Retrieving a Profile is an inconsistent operation •

    Depends on what you retrieve at the same time • Don’t behave the same between orgs with/without Source Tracking Without Source Tracking - Only package.xml content With Source Tracking - package.xml content - any metadata tracked by Source Tracking (SourceMember table)
  6. Profile Retrieve <?xml version="1.0" encoding="UTF-8"?> <Package xmlns="http://soap.sforce.com/2006/04/metadata"> <types> <members>Account.MyFirstField__c</members> <name>CustomField</name>

    </types> <types> <members>My Profile</members> <name>Profile</name> </types> <version>66.0</version> </Package> <?xml version="1.0" encoding="UTF-8"?> <Profile xmlns="http://soap.sforce.com/2006/04/metadata"> <custom>true</custom> <fieldPermissions> <editable>true</editable> <field>Account.MyFirstField__c</field> <readable>true</readable> </fieldPermissions> </Profile> package.xml retrieved profile
  7. Profile Retrieve <?xml version="1.0" encoding="UTF-8"?> <Package xmlns="http://soap.sforce.com/2006/04/metadata"> <types> <members>Account.MySecondField__c</members> <name>CustomField</name>

    </types> <types> <members>My Profile</members> <name>Profile</name> </types> <version>66.0</version> </Package> <?xml version="1.0" encoding="UTF-8"?> <Profile xmlns="http://soap.sforce.com/2006/04/metadata"> <custom>true</custom> <fieldPermissions> <editable>true</editable> <field>Account.MySecondField__c</field> <readable>true</readable> </fieldPermissions> </Profile> package.xml retrieved profile
  8. Profile Retrieve <?xml version="1.0" encoding="UTF-8"?> <Package xmlns="http://soap.sforce.com/2006/04/metadata"> <types> <members>Account.MySecondField__c</members> <name>CustomField</name>

    </types> <types> <members>My Profile</members> <name>Profile</name> </types> <version>66.0</version> </Package> <?xml version="1.0" encoding="UTF-8"?> <Profile xmlns="http://soap.sforce.com/2006/04/metadata"> <custom>true</custom> <fieldPermissions> <editable>true</editable> <field>Account.MySecondField__c</field> <readable>true</readable> </fieldPermissions> </Profile> package.xml retrieved profile • MyFirstField__c is not there anymore • Different behavior for Source Tracking
  9. Profile Deployment - Creation Deploying an empty Profile on creation

    gives a few extra access rights <?xml version="1.0" encoding="UTF-8"?> <Profile xmlns="http://soap.sforce.com/2006/04/metadata"> <custom>true</custom> <userLicense>Salesforce</userLicense> <userPermissions> <enabled>true</enabled> <name>ActivitiesAccess</name> </userPermissions> <userPermissions> <enabled>true</enabled> <name>AllowViewKnowledge</name> </userPermissions> <userPermissions> <enabled>true</enabled> <name>ChatterInternalUser</name> </userPermissions> <userPermissions> <enabled>true</enabled> <name>LightningConsoleAllowedForUser</name> </userPermissions> <userPermissions> <enabled>true</enabled> <name>ViewHelpLink</name> </userPermissions> </Profile> Still, much much better than before cf. https://texei.com/conseils/create-empty-profiles-automatically-to-fearlessly-deploy-all-your-access-rights-in-salesforce/
  10. Profile Deployment - Update <?xml version="1.0" encoding="UTF-8"?> <Profile xmlns="http://soap.sforce.com/2006/04/metadata"> <custom>true</custom>

    <userLicense>Salesforce</userLicense> … <userPermissions> <enabled>true</enabled> <name>CustomizeApplication</name> </userPermissions> … </Profile> <?xml version="1.0" encoding="UTF-8"?> <Profile xmlns="http://soap.sforce.com/2006/04/metadata"> <custom>true</custom> <userLicense>Salesforce</userLicense> … … </Profile> Removing a permission in the UI removes it in the Metadata
  11. Profile Deployment - Update <?xml version="1.0" encoding="UTF-8"?> <Profile xmlns="http://soap.sforce.com/2006/04/metadata"> <custom>true</custom>

    <userLicense>Salesforce</userLicense> … <userPermissions> <enabled>false</enabled> <name>CustomizeApplication</name> </userPermissions> … </Profile> Deploying as is doesn’t remove permission in org • just skips it • should be explicitly set to false (not done by the API on retrieve) • permission sets are working correctly to remove permissions, use them instead !
  12. Theory is simple: Use Permission Sets and Permission Set Groups

    Keep only on Profiles permissions that can’t be on a Permission Set Then what ?
  13. Then what ? 1. Even without doing anything, knowing how

    it works may help you to be careful 2. Move Profile permissions to Permission Sets (as some things that don’t work on Profiles do work on Permission Sets) 3. Then fix the underlying issues with extra tooling Our take on the tooling: Texeï SFDX Plugin, free, open source https://github.com/texei Documentation: https://texei.github.io/texei-sfdx-plugin/ (thank you Nicolas Vuillamy 💙)
  14. Migration to Permission Set • Migrating Profile to Permission Set

    • Use User Access Policy to assign Profile - Permission Set 1-1 ◦ Doesn’t cover removing old permset • Emptying Profile • Refreshing sandboxes Moving to Permission Sets could require a whole refactoring, have a look to Louise Lockie’s session
  15. Migration to Permission Set Migrating Profile to Permission Set •

    Some existing solutions, good with some flaws • Not open source, so nothing you can do about it → sf texei profile convert --profile-name “Sales User”
  16. Migration to Permission Set Emptying Profile → sf texei profile

    empty --profile-name “Sales User” --target-org “My Org” Will remove from Profile all Permissions that could be on a Profile. Still Beta, because permissions need to be set to false, and no API is returning all available permissions (or I couldn’t find it)
  17. Skinny Profiles Basically: A Profile containing only what can’t be

    on a Permission Set 3 commands to help: Creating an empty Profile on a target org: → sf texei skinnyprofile create Retrieving a Profile, based on local’s project content: → sf texei skinnyprofile retrieve Additional check for CI: → sf texei skinnyprofile check