Newer Version Available
Apex Policies for Transaction Security
| 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}