68

What is the best way to deploy profiles in Salesforce?

I have a system admin profile with access given to the objects that i have created in my sandbox. I have about 1000 fields across these objects. Eclipse suggests that we should not deploy profiles.

Also in production, there is a high possibility that Admins would have been given access to other object fields' which are not available in my sandbox.

Background :-

Say I have a sandbox dev1 and am working on it for application 1 after refreshing from production.

I have another sandbox dev2 and another group of devs are working on it for application 2 after refreshing from production.

Dev2 goes live (to production) before dev1, and in dev2 System Admin profile, I have added some fields based on the objects that are needed for application 2 and have deployed it to production..

Now, If I deploy dev1 to production (and if I have about some 1000 fields added in my dev1 sandbox and the access has been given to System Admin) :

How will I deploy this system admin profile with necessary field access to production? (Because if I overwrite the system admin profile, the field access that were already given for dev2, application2 will be removed. How do I handle this??

I know we can achieve this using permission set for all other existing profiles. How to do this for System Admin profile?

2
  • Have you tried using the feature where it lets you specify associated profile changes when you're adding a component to a change set. Does that help? Oct 9, 2012 at 6:58
  • we can do that @techtrekker but if we have some deployment from someother environment, the permissions will be overwritten if am right.
    – Sathya
    Oct 12, 2012 at 8:19

8 Answers 8

55

The metadata API and the "change set" feature are not "destructive" by nature. Many people think that when you copy a profile, you are copying all of the permissions for that profile, including all object and field permissions. However, this simply isn't true. While you do need to compare base profiles for a comparison of, for example, "API Enabled" or "Export Data", objects and fields are enabled separately by default, which means that you can copy just a subset of all available permissions without worrying about a complete overwrite.

It is true that you should be wary about using profiles in the Eclipse IDE, and with good reason. The plugin is "smart" and tries to only deploy changes. This means that in order to deploy a change to a field level security item, you have to modify both the profile and the custom field in order for a change to occur. This is usually a huge hassle, and so you should probably avoid doing that.

Change sets, and the metadata toolkit, however, are perfect ways to copy just the permissions you want to copy. This is because the system will only change the settings relevant to the combination of profiles and fields/objects. The Metadata Toolkit gives you the flexibility of editing raw XML files, allowing you to copy only the information you want to.

Let's take a look at using the Metadata Toolkit, since it's fairly easy to use, and has reasonable documentation.

First, I create a package.xml file that has the following content:

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Lead.CurrentGenerators__c</members>
        <name>CustomField</name>
    </types>
    <types>
        <members>Admin</members>
        <name>Profile</name>
    </types>
    <version>29.0</version>
</Package>

Here, I specifically request a single field and a single profile. The results of this export gives me:

objects/Lead.object

<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <fields>
        <fullName>CurrentGenerators__c</fullName>
        <externalId>false</externalId>
        <label>Current Generator(s)</label>
        <length>100</length>
        <required>false</required>
        <trackFeedHistory>false</trackFeedHistory>
        <type>Text</type>
        <unique>false</unique>
    </fields>
</CustomObject>

profiles/Admin.profile

<?xml version="1.0" encoding="UTF-8"?>
<Profile xmlns="http://soap.sforce.com/2006/04/metadata">
    <fieldPermissions>
        <editable>true</editable>
        <field>Lead.CurrentGenerators__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <userLicense>Salesforce</userLicense>
</Profile>

If I change "editable" to false, and deploy this change to another organization with the same field (or, even if the field does not exist), then the only change that would occur is that the single field level security setting would change-- all other fields, objects, and other permissions would remain intact.

This feature is often used to deploy security changes that are scoped out in a Sandbox. You can be as selective as you'd like to be, even down to just a single field's permissions. In this manner, you can choose which permissions you'd like to deploy. Also, you could choose to manually edit the XML files before deployment to deploy different sets of field level security permissions within the same package. They do not need to be a fully rectangular matrix. For example, you could build a deployment like this:

           Field 1 Field 2 Field 3
Profile 1  Edit    -       Read
Profile 2  Read    Edit    -
Profile 3  Edit    Edit    Edit

In this case, two field level security settings will not change (Profile 1's Field 2 security, and Profile 2's Field 3 security), while the other settings will be as specified. Hopefully this answer will help clear up the confusion of the other answers that have been posted to this question.

TL;DR version

Only settings explicitly mentioned in a change set or metadata API xml file will be modified. One should not think of this as an "overwrite", but instead a "selective edit."

4
  • 2
    Nearly 8 years later - do you still support this method? Essentially, you're saying to "cherry-pick" every change. Lightning has added so much more to the mix. I work in Health Cloud where there's constant development, separate apps, and mng pkg installs for docs etc. Dev env is widely different than Prod. This supposed to be a "click-config" solution. Trying it this way I'm constantly peppered with "No --master-- recordtype defined for..." or excluding things like automatic visibilities to "standard__AllTabSet". Wouldn't u agree today a spreadsheet matrix and "by hand" is the best way to go? Apr 30, 2021 at 11:57
  • 4
    @ESRouter Today, Permission Sets and Permission Set Groups are arguably the way to go. Don't mess with profiles if you can help it. Each app can have its own permission set, and you can assign them with Apex code, SFDX CLI, and other newer generation tools. Profiles should be limited to page layout assignments and record type assignments, and pretty much nothing else. I wouldn't recommend relying on profiles any more than necessary, and definitely not this level of cherry picking, if one can help it.
    – sfdcfox
    Apr 30, 2021 at 13:33
  • 1
    I would echo this statement: "Profiles should be limited to page layout assignments and record type assignments, and pretty much nothing else." definitely for the larger organisations. If you have a crystal ball and know you will never have too many permissions/user types, then maybe Profiles alone is ok. On a sliding scale small organisation and Profiles at 1 end, large organisations and Permissions Set and PS Groups at the other. Apr 29, 2022 at 4:12
  • That said, yet to see a large org implement properly (always a mess). What does properly mean? 1 question: "What does you change control process look like?" --- question: Do you(the global you) manage your permission change control in 1 matrix? If not you're doing it wrong. Apr 29, 2022 at 4:14
24

Profiles are the only piece of metadata for which I advocate making changes by hand. It can be tons of clicking, but the metadata API is far too "all or nothing" for profile changes to easily keep them in synch, at least in my experience. Attempting to deploy Profiles automagically carries the added risk that comes from the fact that in dev sandboxes, it's frequently necessary to mess around with privileges when doing profile-related stuff, and it's easy to accidentally deploy a security change one did not intend.

Using diffs against profiles is basically impossible for anything but the most trivial of changes - profiles get lots of stuff added in different positions, and your source profiles will likely be so out of synch with the destinations that a diff is not practical.

I've taken to doing deploys with Ant, then a long "run list" of sys admin manual changes, which are usually mostly profile clicks that have been compiled by the developers. Then the admin makes the changes, and tests them by impersonating the various modified profiles.

I suppose permission sets could ease part of the pain with this, but I haven't yet rolled them into my methodology so can't really comment.

4
  • Usually end up doing this as well...this is so painful for any large projects...so many clicks. Have done some quick selenium scripts to simulate a "check all" feature, but never attempted a full suite of automated profile set up with selenium. Oct 20, 2012 at 1:49
  • 2
    Long ago I wrote a Greasmonkey/Userscript that allows you to copy+paste basically an entire profiles settings as a text-string from one org to another and it highlights the changes it's about to apply before you press save. It modifies the standard profile edit pages (works on permission sets too). It comes with no support but it's worked well for my team for years. Works better in Firefox with greasemonkey addon than Chrome these days, primarily because Chrome enforces limits on the length of text you can handle in a prompt-dialog. Source/installable javascript: bit.ly/1F83oJP Jun 10, 2015 at 12:53
  • That's awesome! Thanks for that. Looks pretty useful. I have been using a Chrome plugin that allows a drag/drop to select checkboxes: chrome.google.com/webstore/detail/multicheck-checkbox-check/… but a greasemonkey script seems a better way to go!
    – jkraybill
    Jun 11, 2015 at 6:04
  • Manual changes is an ever changing situation. Duplicate Matching Rules for example. Community Settings, and the list goes on.... So to say ONLY would be incorrect. this is true now, and has always been true, profiles has never been the only manual change scenario. And it most likely will never be the ONLY. Apr 29, 2022 at 4:16
10

The Metadata API is the fullest footprint of settings - packaging and change sets both make assumptions on how to handle particular cases that may not be desirable. I definitely recommend making changes through the Force.com IDE or ANT. Also, while ultimately there will be some cases where you will have to make manual changes (e.g. standard apps like sales or call center are not supported in the Profile metadata type in the Metadata API and therefore must be made manually), you can at least reduce the number of manual changes you need to make.

Keep in mind, profiles can be big - for each object in your org, there are six bits of permissions, each field of each object there are two bits of permissions, each visualforce page or apex class is a bit, and then there are approximately 150 user permission bits to manage on top of it. And that's without settings like record types or layouts - all in all, there can be well over a million configurations to capture in a larger org so you might as well make it easier by automating where you can.

8

I have one other suggestion / workaround which worked well for me when faced with the same problem you have: use permission sets.

Profiles have their well-known drawbacks and permissions sets are perfect for packaging authorisation for new applications. Say you are developing a new application with it's own objects, pages, classes and tabs. Create a new permission set which you then deploy. You can then assign this to:

  1. Individual users manually
  2. Multiple users via the Data Loader OR
  3. Multiple users via The Permissioner app
2

I would suggest you can compare the metadata files for profiles using file comparator tools like diff doff or exam diff and then come to conclusion that this are the major changes that are essential.

Then may be you can modify metadata according to your need and then use ANT to push the changes .

ANT provides the flexibility of changing the metadata also you can mock run in the sandbox before doing final deployment

4
  • Comparing metadata files for Profiles across orgs is nearly impossible for anything but the most trivial of changes.
    – jkraybill
    Oct 9, 2012 at 7:37
  • While comparing the metadata may be tedious it is still probably the best way to identify the changes, short of keeping a running delta by hand.
    – Mike Chale
    Oct 9, 2012 at 11:06
  • Also, note that the metadata API and Change Sets will not update permissions to standard fields on standard objects; only to custom fields on standard objects or every field on custom objects.
    – Mike Chale
    Oct 9, 2012 at 11:07
  • Although it may serve a different use case than comparing one profile between two sandboxes, you can look at the Audit Trail in the source org to see all of the profile changes that were done. Oct 20, 2012 at 1:47
2

This is an excellent question in need of a solution. In theory you can compare the .profile files between orgs but here's what I've learned:

  1. Make sure you have 2 projects (PROD and SandBox) which both have all meta data contained. I noticed any objects missing in your project do not appear in the profile metadata file!
  2. You have to sort and normalize the .profile xml in order to compare it with text-based diff (non-XML) tools. One way would be to write an XSL which does this (see sample below).

You can then compare the PROD and Sandbox .profile files, merge and (in theory) deploy.

Sample XSL

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://soap.sforce.com/2006/04/metadata"
    version="1.0">

    <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes" />
      
    <xsl:template match="/Profile">
    <Profile>
         
    <xsl:for-each select="classAccesses">
        <xsl:sort select="apexClass"/>
        <classAccesses><xsl:copy-of select="apexClass"/><xsl:copy-of select="enabled"/></classAccesses>
    </xsl:for-each>

    <!-- Another for-each for each object type:
         classAccesses
         fieldPermissions
         layoutAssignments
         objectPermissions
         pageAccesses
         tabVisibilities
         userLicense
     -->

    <xsl:for-each select="userLicense">
        <xsl:copy-of select="."/>
    </xsl:for-each> 

</Profile>
</xsl:template>

</xsl:stylesheet>

This XSL still needs some work (obviously) in order to allow you to compare each object type.

0

Diff'ing profiles via their metadata XML is time consuming, but I disagree with previous answers that it is useless or impossible.

The first step to happiness is to push all non-profile changes so that the two orgs are synchronized.

Next, we must ensure that we are comparing apples to apples. To do this, we'll need to ensure that we are using the same package.xml when pulling the profiles (either through the Eclipse IDE or ANT). Now we can readily compare the files.

Additional suggestions:

  1. If there are many changes to the profile involving non-conflicting SObjects (e.g. we are only worried about additional field access granted on Accounts, Contacts, and Opportunities), consider splitting out the package.xml into "stuff we're happy to overwrite" and "stuff that we need to carefully merge". This will allow you to focus your attention where it is needed. With one deployment being easy, while the second requires the manual diff'ing.

  2. If you need to merge profiles, you can do this using a combination of cloning the existing profile, deploying your new profile on top of the cloned profile, then (optionally) redeploying the original profile on top of the cloned profile. Note, you'll need to manually change file names to accomplish this, but it works if the two profiles are generally distinct.

0

Problem: Deploy Profiles profiles includes permissions to many metadata items and needs to be included in the XML, and many of those metadata items may not exist on destination org causing the deployment to fail.

Solution: Use an appexchange application: Copado Deployer it will describe all the metadata on source org to produce a full XML of your profiles. it will apply a smart algorithm an remove any reference to non existing metadata on destination. Full Profile will be deployed successfully not leaving behind 1 permission.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.