Newer Version Available

This content describes an older version of this product. View Latest

Apex Policies for Transaction Security

Every Transaction Security policy must implement the Apex TxnSecurity.PolicyCondition interface. Here are several examples.
Available in: Lightning Experience
Available in: Enterprise, Performance, Unlimited, and Developer Editions

Requires purchasing Salesforce Shield or Salesforce Shield Event Monitoring add-on subscriptions.


If you didn’t specify a condition value before you generated the Apex interface for a policy, you can add the condition later. If you want to change the condition, you can edit it. Edit the Apex code to include a condition before you activate your policy. If you never include a condition, your policy is never triggered. See the following examples for how to write up the condition.

To avoid errors, don't include DML statements in your custom policies. Also, if you send custom emails via Apex during transaction policy evaluation, you’ll get an error when the policy is evaluated, even if the record is not explicitly related to another record. For more information, see Apex DML Operations in the Apex Developer Guide.

When you delete a transaction security policy, your TxnSecurity.PolicyCondition implementation isn’t deleted. You can reuse your Apex code in other policies.

This Apex policy example implements a policy that is triggered when someone logs in from multiple IP addresses in the past 24 hours.

Example

1global class LoginPolicyCondition implements TxnSecurity.PolicyCondition {
2  public boolean evaluate(TxnSecurity.Event e) {
3    AggregateResult[] results = [SELECT SourceIp
4                                 FROM LoginHistory
5                                 WHERE UserId = :e.userId
6                                       AND LoginTime = LAST_N_DAYS:1
7                                 GROUP BY SourceIp];
8    if(!results.isEmpty() && results.size() > 1) {
9      return true;
10    }
11    return false;
12  }
13}

This Apex policy example implements a policy that is triggered when a session is created from a specific IP address.

Example

1global class SessionPolicyCondition implements TxnSecurity.PolicyCondition {
2 public boolean evaluate(TxnSecurity.Event e) {
3  
4   LoginHistory eObj = [SELECT SourceIp FROM LoginHistory WHERE Id = :e.data.get('LoginHistoryId')];
5   if (eObj.SourceIp == '1.1.1.1') {
6    return true;
7   }
8   return false; 
9 }
10}

This example implements a policy that triggers whenever more than 1000 leads are exported, for example by the Data Loader. EntityName is a field in the event e. It contains the actual name of the entity, such as Account, or Contact.

Example

1global class LeadExportPolicyCondition implements TxnSecurity.PolicyCondition {
2  public boolean evaluate(TxnSecurity.Event e) {
3  
4    Integer numberOfRecords = Integer.valueOf(e.data.get('NumberOfRecords'));
5    String entityName = e.data.get('EntityName');
6  
7    if ('Lead'.equals(entityName) && numberOfRecords > 1000) {
8      return true; 
9    }
10  
11    return false; 
12  }
13}

This Apex policy is triggered when someone accesses reports.

Example

1global class ReportsPolicyCondition implements TxnSecurity.PolicyCondition {
2  public boolean evaluate(TxnSecurity.Event e) {
3    if(e.data.get('SessionLevel') == 'STANDARD' ){
4      return true;
5    }
6    return false;
7  }
8}

This Apex policy is triggered when someone accesses a Connected App.

Example

1global class ConnectedAppsPolicyCondition implements TxnSecurity.PolicyCondition {
2  public boolean evaluate(TxnSecurity.Event e) {
3    if(e.data.get('SessionLevel') == 'STANDARD' && (e.entityId == '0CiD00000004Cce')){
4      return true;
5    }
6    return false;
7  }
8}