When deploying new custom profiles between orgs with Gearset, there's some slightly unintuitive behaviour in how the profiles are applied in the target org which can catch some people out. This article explains what the behaviour is, and how to work around it.

What's the scenario?

You're deploying a new custom profile from a source org to a target org. The custom object permission is set to unticked/false in the source org, and to ticked/true in the Standard User profile in the target org.

(Note: standard objects are considered custom objects in the metadata API, so custom object permission can include permissions to standard objects.)

What happens?

After the deployment completes, you'll find that the custom object permission on the new profile in your target org is set to ticked/true, when you would expect it to be unticked/false.

Apex class access, app permissions and system permissions are similarly affected.

I've also helped customers who found that some user permissions on the new profile in your target org are set to ticked/true, when you would expect it to be unticked/false.

Why does this happen?

It comes down to how permissions are represented by the Salesforce metadata API, and how Gearset interprets them:

  • A permission which is ticked/true is represented as <permission>true</permission> 

  • A permission which is unticked/false not returned at all in the XML

When deploying permissions through the metadata API, if the permission is not explicitly set, Salesforce will set it to the default (taken from the Standard User profile) in the target org. The default can be either true or false.

As a result, when Gearset queries an org before a profile exists it's hard to tell if a specific permission is explicitly set to false (in which case nothing is returned), or if it's in the default state (which could be true or false, but is also not returned), as both generate the same XML from Salesforce.

In this scenario, Gearset will assume the profile should be set to the org default instead of forcing it to be unticked/false.

What's the workaround?

Once you've run the first deployment, run a second comparison between the same source and target. 

You should now see the appropriate custom object permission as a deleted item in the result grid, and be able to deploy that deleted custom object permission to correctly set it in the target org.

Did this answer your question?