đź“Ł Attention Salesforce Certified Trailblazers! Link your Trailhead and Webassessor accounts and maintain your credentials by December 14th. Learn more.

Use Apex in Transaction Security Policies

Learning Objectives



Be careful—Transaction Security is a powerful feature. An incorrect Login Event policy that blocks for its real-time action locks you out of your org. To prevent this from happening in an org you care about, create a new Trailhead Playground for this module. Yes, we really mean a brand new Trailhead Playground.

After completing this unit, you’ll be able to:
  • Describe how Apex is used to implement your transaction security policies.
  • Describe transaction security events and policies.
  • Explain the programming side of transaction security policies.

A Short Note About Using Apex

Working with Apex can be scary. Well, don’t worry, be happy. While we don’t go into great detail here, we do cover everything you need to know to edit the Apex part of your Transaction Security policies. You don’t have to edit any of the code generated when you create a policy. However, when you need to fine-tune a policy, such as having it trigger for a very specific event, editing the Apex is the way to go. Transaction Security provides a way for you to edit your code, so you don’t need a special software development environment. You also don’t need any programming or admin experience, because we’ll show you how to make changes.

Let’s take a minute to review some basics. Everything in Apex that we’re going to use is a class that implements the Transaction Security PolicyCondition interface. Yes, that was a bit of jargon, so let’s say that again, this time in plain words.
  • An Apex class is a self-contained unit of code. The name of the class is a handy way to refer to what it does. Transaction Security uses the Event class to contain event information for all policies. There’s also one class for each policy implementation, and we’ll call it the policy’s class. A policy class is named by concatenating the policy’s API name with “PolicyCondition”, so each class has a unique name.
  • Implementing something means writing the code for a class. The initial implementation is automatic. Remember the Generate Apex option when you created the policy? That option tells Transaction Security to write the policy’s code for you as a class.
  • An interface connects two things, for example, the event we’re watching for and the action we want to take when the event occurs. Transaction Security uses the PolicyCondition interface to evaluate events against a policy. Each policy has a unique interface implementation because each policy is different.
So what we have here is a piece of code (the class) that implements (creates) the condition (the event criteria) with the interface (that links the event to the policy). For our example of detecting someone logging in on Android:
  • The interface class is BlockAndroidPolicyCondition.
  • The implementation is the code for the BlockAndroidPolicyCondition class, which is created automatically. This is the part you modify to fine-tune your policy.
  • The interface is always PolicyCondition for Transaction Security.

The other class we use is the event, or action, that triggers the policy. When someone logs in, accesses a resource, updates an account, or just about anything else, an event is created in the database. The events we care about are represented in Apex by the Transaction Security Event class. The Event class contains all sorts of interesting information, like when the event happened, who created it, where it happened, and what it was. We’ll cover events more in a bit.

Whenever you create a policy, Transaction Security automatically creates the matching Apex PolicyCondition implementation. That’s handy, because you don’t have to write any code for basic policies. And for more advanced policies, you have a starting point for fine-tuning.

Transaction Security checks every event to see if it matches any of your policies. If a match is found, the policy condition is run to see if the event meets the criteria to trigger the policy. If so, Transaction Security takes the action and issues any notifications for that policy. Continuing with our example, BlockAndroidPolicyCondition runs only when Transaction Security gets a login event. Transaction Security triggers the policy only if BlockAndroidPolicyCondition says that the event meets the policy criteria.

If all this has your head spinning, don’t worry. We’ll explain everything as we go in plain language.

Review the Apex Policy

Let’s take a look at the generated Apex code that implements the Transaction Security policy. This is a plain-language explanation of the code—no programmer jargon required.

In your list of policies, click the Apex policy name for our policy: BlockAndroidPolicyCondition. Let’s take a short stroll through the code. Basically, only four lines are doing the work. The rest of the code is housekeeping.

Apex code for the BlockAndroid policy.

The first few lines describe the Apex components we’re creating. Line 1 says that the Apex class name is BlockAndroidPolicyCondition and that this class implements the transaction security policy condition interface. This information tells Transaction Security that when the event we defined for this policy occurs, run this code. Line 2 is blank—yay! Line 3 says that the class gets one parameter, which is the event that just happened.

Line 4 is where the work starts. The event we’re looking at, e, has a lot of information in it. The user that caused the event, when it occurred, the action to take, and more are stored here.


If you’re curious, take a look at the Transaction Security Event class to see all the parts. It’s not a requirement for this module, but you might find it interesting.

The only thing a PolicyCondition implementation does is evaluate the event to check whether to trigger its action. For now, we just want to find the type of platform, or operating system, that was used for logging in. That’s not included in the event, but there’s a way to find it. The event, e, has a member named data. The data member has a value named LoginHistoryId. LoginHistoryId is the address in the org of this particular login’s information. We can use LoginHistoryId to get the actual LoginHistory object, which is called eObj in the code. eObj contains a member named Platform, and that’s what we want.

In plain language, the line says “Get the login history address in the event, read the platform information at that address, and save the information in the login history object we just created.”

Whew! Now that we have that, we check in Line 5 to see if Platform is Android 9. If it is, we return True in Line 6, meaning that the policy’s condition was met, and Transaction Security blocks the login. Otherwise, False is returned in Line 9, and everything continues as if nothing happened. Lines 7, 10, and 11 are the closing brackets that match the opening brackets on Lines 5, 3, and 1, respectively. Brackets are how Apex groups statements.

This entire checking process takes a fraction of a second.


Apex Quick Start

Transaction Security Namespace

Transaction Security Policies

Create Transaction Security Policies

Flower icon used to indicate that the content is for Salesforce Classic

Remember, this module is meant for Salesforce Classic. When you launch your hands-on org, switch to Salesforce Classic to complete this challenge.