Custom Transaction Security Policies in Spring 16
Introduction
Towards the end of the Spring 16 release notes, in the Security and Identity section, is a particularly interesting new feature - Custom Transaction Security Policies. Transaction Security intercepts Salesforce events and can take action, including blocking the requested event. Custom Transaction Security Policies allow you to create your own policies that are evaluated when an event occurs. Essentially what this means is that you can have a lot more granularity around security than with the regular setup tools.
Note that there is an additional cost associated with this functionality - from the help :
Requires purchasing Salesforce Shield or Salesforce Shield Event Monitoring add-on subscriptions.
Enabling Custom Policies
Before you can create a custom policy, you need to enable the custom policies functionality by navigating to Setup -> Administration Setup -> Security Controls -> Transaction Security :
The Policy
The use case for this post is a request I’ve hit more than once in my world - restricting the users that can run reports from external IP addresses. Using the standard setup tools, all I can really do is restrict the IP addresses that users with a particular profile can login from, which stops them from carrying out any activities from an external address. Using a custom policy allows me to intercept a user’s attempt to execute a report or dashboard, and check that they are either from an approved IP address or they are a user that I have specifically allowed to do this.
The first step is to configure the custom policy:
Stepping through the parameter values :
- Enable - is the policy enabled (active)
- Name/API Name - the friendly and internal names for the policy, pretty much everything in Salesforce has these!
- Event Type - AccessResource - intercept when the selected resource is accessed
- Resource Name - the selected resource - in this case, any Report or Dashboard access will trigger the evaluation of the policy
- Notifications - how I want to be notified if the policy is breached
- Real-Time Actions - what I want to do when the policy is breached - in this case I’m going to block access, but I could choose to just get notified and take no action, or mandate that two-factor authentication is required.
- Apex Policy - this is the Apex class that contains the policy. I can either choose an existing policy or, as in this case, get the platform to generate me the basic class. Note that classes must implement the TxnSecurity.PolicyCondition interface.
- Execute policy as - the context user to execute the Apex policy class, must have the System Administrator profile.
- Create condition for - I need to check the source IP of the request. Obviously 1.1.1.1 is not a valid internal IP address, but for the purposes of this post assume it is.
This generates the following Apex code:
global class BlockIPAddressReportsPolicyCondition implements TxnSecurity.PolicyCondition { public boolean evaluate(TxnSecurity.Event e) { if(e.data.get('SourceIp') == '1.1.1.1') { return true; } return false; } }
Extending the Generated Policy
As it stands, this stops anyone from accessing reports unless it is from the IP address 1.1.1.1, which while an improvement on stopping users from doing anything from that IP address, isn’t all I’m hoping for.
The next step is to determine the user that made the request - luckily the Event class exposes the UserId property which I can use to retrieve the user record:
User u=[select id, FirstName, LastName from User where id=:e.UserId];
and I can then check that if I am not the user, the request is blocked:
if ( (U.FirstName!='Keir') || (U.LastName!='Bowden') ) { // Prohibited user - only Keir Bowden can access reports from external IP addresses! return true; }
Now if I try to access a report from any IP address, I’ll have full access, but if another user tries to access a report and their IP address isn’t 1.1.1.1, the request is blocked:
and as I specified myself as the recipient, I receive an in app notification:
and an email:
Conclusion
As I mentioned earlier, this feature requires an additional paid subscription. However, if you are working in a regulated industry, or for a customer with specific and nuanced requirements around application security, its well worth a look. Also, as its part of the Salesforce platform, there are no browser plugins or the like to be installed.
Thanks for sharing Bob. This is really a very useful feature.
ReplyDeleteHi Bob: I am trying to send email to user's (who initiated the transaction) Manager using Messaging.SingleEmailMessage but it is not sent if condition is met in Execute method.
ReplyDeleteI have also tried to create Custom object record. In the debug logs I am able to see the id of the record in execute method but when I try to locate that record I am not able to find it in system.
Any Idea?
Hi, I think you have already figured it out, but maybe for others to know: "Don’t include Data Manipulation Language (DML) statements in your custom policies. DML operations are rolled back after a transaction security policy is evaluated, regardless if the policy evaluates to true or false."
Deletehttps://developer.salesforce.com/docs/atlas.en-us.securityImplGuide.meta/securityImplGuide/security_transactions_apex_policies.htm
How do write a test class for this?
ReplyDelete