Troubleshooting Salesforce deployments with Shield Platform Encryption settings
Eric Kintzer on January 27th 2020
Today’s troubleshooting guide is written by the awesome Eric Kintzer, Salesforce Architect at Helix, and Gearset Community Advisor.
To protect your Salesforce data with an added layer of security, you may have opted for Shield Platform Encryption; the next step up from Salesforce’s Classic Encryption. This option allows you to encrypt a much wider subset of standard and custom fields, as well as person accounts, cases, search, approval processes, and other key Salesforce features.
However, orgs that adopt Shield Platform Encryption will face certain subtleties when deploying encryption settings. This article exposes some of these common quirks and how to work around them.
Encrypting a field used in an APEX SOQL WHERE clause
Let's say you have code that does the following:
Account accts = [SELECT Id, Name FROM Account WHERE Name = 'Foo'];
Let's also say that you encrypt
Account.Name using the scheme Deterministic - Case Insensitive as shown below:
You run your tests in your feature sandbox/org and all is well.
Now, let's say that you deploy both the encrypted field and the Apex class to another environment, and that you run the tests as part of that deployment. You'll find that any tests that use that SOQL statement will fail.
The reason for this is that SFDC does not encrypt the field immediately upon Metadata API deployment. Instead, the encryption is applied later after SFDC runs compatibility checks in the target org. Meanwhile, the SOQL tests are running. These two items are incompatible and the SOQl mysteriously fails - basically, no records are returned by the query. Your asserts are likely to fail.
Workaround: do two deployments:
- First, deploy the
Account.Name(encrypted) CustomObject metadata - don't run tests
- Then, deploy the Apex code (and run tests)
This allows SFDC to apply the encryption to the field as part of the first deployments, before the Apex tests are run in the second deployment.
Encrypting a field that is used in a Process Builder Update Records filter
Let's say in your target org, you have a Process Builder (perhaps several versions) that references a field within the Update Records action filter section (that is, update records only if the target record matches the filter criteria). The referenced field is currently unencrypted but you want to add encryption to it.
For example, you have a Process Builder action that updates accounts that have
Account.Name starting with 'Foo'.
Account.Name is currently unencrypted but you want to encrypt it.
First of all, as you will realize in your feature sandbox, you can't use any encrypted field in a Process Builder Update Records filter. You also can't use
LIKE operators at all on encrypted fields. As a result, your process builder logic has to be rethought. Let's assume you have figured out some strategy.
If you try to deploy the new Process Builder (the workaround) and the encrypted field
Account.Name in one package, it will fail because the SFDC encryption compatibility checker tells you that each target org Process Builder version uses
Account.Name in an Update Records filter.
- Go into the target org and delete all the inactive versions that reference the to-be-encrypted field within an Update Records filter.
- Deploy a new version of the Process Builder (the workaround) into the target org and make sure it is active
- Delete the previously active, now inactive Process Builder version
- Deploy the CustomObject containing the encrypted field
Encryption Policy Deployment Exceptions
As of V47, SFDC will not let you deploy any of the following with the Metadata API. Encryption Policy Settings as shown in the green box below:
Deploying Encryption on uncustomizable Objects
While the user interface allows encrypting Standard Fields on these Objects: ConversationContextEntry, EmailMessageRelation, ListEmail, you can't deploy them with Gearset, or any other Metadata API based tool, because the API won't fetch any non-customizable Objects (like the aforementioned list).
Deploying any of the Encryption Advanced Settings
None of these settings can be deployed with the Metadata API:
Workaround for all of the above:
Unfortunately, you'll have to manually configure the target org.
A Final Caution
When Gearset successfully deploys a package, you get that cheery "Successful Deployment" screen.
However, if the package includes encryption changes to a CustomObject field (this includes standard and custom objects), your deployment may not really be all that you wanted.
Because SFDC executes the encryption compliance check asynchronously to the Metadata API deploy, you may discover that while your package was deployed and the API reported it successful, the encryption of the field was not completed. You will receive an email from Salesforce that looks something like this:
Depending on the specifics, you will need to redeploy the CustomObject field after analyzing the specifics of the details in the email (the Process Builder example above is a likely generator of such an email, but there are other use cases too).
Running into more deployment errors? We’re happy to help
As always, if you’re ever struggling with a deployment, hitting a confusing error, or would like some advice on where to take your Salesforce DevOps strategy, our team of DevOps experts are more than happy to chat with you and help any way we can! You can get in touch via [email protected] or via the live chat widget at the bottom of the page.