Understanding WITH SECURITY_ENFORCED in Salesforce Apex

Salesforce : WITH SECURITY_ENFORCED keyword in SOQL
Chinmaya By Chinmaya
8 Min Read

Introduction

Salesforce is a powerful platform that allows developers to build custom applications and automate business processes.
However, with great power comes great responsibility, especially when it comes to data security. Salesforce provides several tools to ensure that your data is secure, and one of those tools is the WITH SECURITY_ENFORCED clause in Apex.

In this blog post, we’ll explore what WITH SECURITY_ENFORCED is, why it’s important, and how you can use it in your Apex code. We’ll also walk through some examples to help you understand how it works in practice.

What is WITH SECURITY_ENFORCED?

In Salesforce, Field-Level Security (FLS) and Object Permissions are critical components of data security.
FLS controls which users can see or edit specific fields on an object, while Object Permissions control access to the entire object (e.g., read, create, edit, delete).

When writing Apex code, developers often query data using SOQL (Salesforce Object Query Language). However, by default, SOQL queries in Apex do not enforce FLS or object permissions. This means that even if a user doesn’t have access to certain fields or objects, the query might still return that data, potentially exposing sensitive information.

This is where WITH SECURITY_ENFORCED comes in. It’s a clause you can add to your SOQL queries to enforce FLS and object permissions. If a user doesn’t have access to a field or object, the query will throw an exception, preventing unauthorized access.

Why Use WITH SECURITY_ENFORCED?

    • Automatically enforces FLS (Field Level Security) and OLS (Object Level Security) in SOQL queries.

    • Reduces manual checks, making code cleaner and more maintainable.

    • Prevents security loopholes that could expose sensitive data.

    • Throws an exception if a user does not have permission to access the queried fields.

    • Best Practise : Using WITH SECURITY_ENFORCED is considered a best practice for writing secure Apex code.

How to Use WITH SECURITY_ENFORCED?

Using WITH SECURITY_ENFORCED is simple.
You just add it to your SOQL query, and Salesforce will enforce FLS and object permissions for that query.

Syntax :

				
					SELECT Field1, Field2 
FROM ObjectName 
WITH SECURITY_ENFORCED 
WHERE Condition
				
			

Example 1: Basic Usage

Let’s say you have a custom object called Employee__c with fields like Salary__c, SSN__c, and Name. You want to query employee data, but you want to ensure that the user has access to these fields.

				
					public List<Employee__c> getEmployees() {
    try {
        List<Employee__c> employees = 
            [SELECT Name, Salary__c, SSN__c FROM Employee__c WITH SECURITY_ENFORCED LIMIT 10];
        return employees;
    } catch (SecurityException e) {
        System.debug('Security violation: ' + e.getMessage());
        return new List<Employee__c>();
    }
}
				
			

What Happens Here?

    • If the user has access to all the fields (Name, Salary__c, SSN__c), the query will return the data.

    • If the user doesn’t have access to any of the fields, a SecurityException will be thrown, and the code will handle it gracefully.

Example 2: Handling Security Exceptions

In the previous example, let’s say we caught the SecurityException and returned an empty list. However, you can customize the error handling based on your requirements.

				
					public List<Employee__c> getEmployees() {
    try {
        List<Employee__c> employees = [
        SELECT Name, Salary__c, SSN__c FROM Employee__c WITH SECURITY_ENFORCED LIMIT 10];
        return employees;
    } catch (SecurityException e) {
        // Log the error and notify the user
        System.debug('Security violation: ' + e.getMessage());
        throw new AuraHandledException('You do not have permission to access this data.');
    }
}
				
			

In this example, if a security violation occurs, the user will see a friendly error message instead of a generic exception.

Example 3: Combining with Other SOQL Features

You can use WITH SECURITY_ENFORCED with other SOQL features like ORDER BY, LIMIT, and WHERE clauses.

				
					public List<Employee__c> getHighPaidEmployees() {
    try {
        List<Employee__c> employees = [SELECT Name, Salary__c 
                                       FROM Employee__c 
                                       WHERE Salary__c > 100000 
                                       WITH SECURITY_ENFORCED 
                                       ORDER BY Salary__c DESC 
                                       LIMIT 5];
        return employees;
    } catch (SecurityException e) {
        System.debug('Security violation: ' + e.getMessage());
        return new List<Employee__c>();
    }
}
				
			

This query retrieves the top 5 highest-paid employees, but only if the user has access to the Name and Salary__c fields.

When to Use WITH SECURITY_ENFORCED?

âś… Use it in SOQL queries where you need to enforce FLS automatically.
âś… Ideal for custom controllers, service classes, and batch Apex.
âś… Useful when querying standard and custom objects where security enforcement is necessary.

Limitations of WITH SECURITY_ENFORCED

❌ It does not enforce record-level security (Sharing Rules, OWD). You still need WITH SHARING or USER_MODE for record access.
❌ It throws an exception if a field is inaccessible, so handle exceptions gracefully.
❌ It only works in SOQL queries; it does not apply to DML operations or dynamic SOQL.

When Not to Use WITH SECURITY_ENFORCED?

While WITH SECURITY_ENFORCED is a powerful tool, there are some scenarios where you might not want to use it:

    1. Admin-Only Code: If your Apex code is only executed by system administrators, you might not need to enforce FLS.

    2. Performance-Critical Code: Enforcing FLS adds a small overhead to your queries. If performance is critical and you’re confident about the security context, you might skip it.

    3. Custom Security Logic: If you’re implementing custom security logic, you might handle FLS and object permissions manually.

Alternative Approach: Security.stripInaccessible

If you prefer handling security gracefully (instead of letting an exception crash your code), use Security.stripInaccessible():

				
					public class AccountService {
    public static List<Account> getSecureAccounts() {
        List<Account> accounts = [SELECT Id, Name, Industry FROM Account];
        return (List<Account>) Security.stripInaccessible(AccessType.READABLE, accounts);
    }
}
				
			

This approach removes fields the user doesn’t have access to instead of throwing an exception.

Best Practices:

    • Always Use WITH SECURITY_ENFORCED in SOQL queries when you want strict security enforcement.

    • Test Thoroughly: Test your code with different user profiles to ensure that security is enforced correctly.

    • Use Security.stripInaccessible() if you prefer handling restricted fields dynamically.

    • Combine WITH SHARING if you also want to enforce record-level security.

    • Handle Exceptions Gracefully: Always catch and handle SecurityException to provide a good user experience.

    • Document Your Code: Clearly document why you’re using (or not using) WITH SECURITY_ENFORCED in your code.

    • Log exceptions properly to debug security issues without exposing sensitive data.

Conclusion

The WITH SECURITY_ENFORCED keyword is a powerful tool for enforcing FLS and OLS in SOQL queries. It enhances security by preventing unauthorized field access while simplifying Apex code. However, understanding its limitations and alternatives like Security.stripInaccessible() ensures a well-rounded security strategy in Salesforce development.

By using WITH SECURITY_ENFORCED effectively, you can build more secure, maintainable, and scalable Salesforce applications.

Share This Article
Follow:
Chinmaya is working as a Senior Consultant with a deep expertise in Salesforce. Holding multiple Salesforce certifications, he is dedicated to designing and implementing cutting-edge CRM solutions. As the creator of Writtee.com, Chinmaya shares his knowledge on educational and technological topics, helping others excel in Salesforce and related domains.
Leave a comment