The importance of data security has reached unprecedented levels for Salesforce development. The increasing reliance of organizations on Salesforce for storing sensitive customer information and business operations requires developers to implement user permission enforcement and organizational policy compliance in every code line. The retrieval of Salesforce object data through SOQL (Salesforce Object Query Language) queries represents a critical area where this principle applies. Salesforce developers can enforce automatic field-level security and object permissions, and sharing rules through the WITH USER_MODE and WITH SECURITY_ENFORCED query options, which prevent data leaks and unauthorized access.
Which option should you select and at what time? The security features of User Mode differ from Security Enforced in practical terms, while affecting both code security and functional capabilities. This blog post explains the essential differences between SOQL security mechanisms while providing real-world examples and functional code examples to help you select the appropriate approach for your Salesforce project. The understanding of these options will enable you to create secure Salesforce applications that meet compliance requirements and provide robust functionality.
Understanding the Basics
WITH USER_MODE
- Purpose: Enforces field-level security (FLS), object permissions, and sharing rules for the running user.
- Scope: Applies security checks to all parts of the SOQL query, including
SELECT,WHERE, and polymorphic fields likeOwner. - Error Handling: Identifies all inaccessible fields in a single exception, enabling comprehensive debugging.
- Example: List<Account> accounts = [SELECT Id, Owner.Name FROM Account WITH USER_MODE];
WITH SECURITY_ENFORCED
- Purpose: Checks FLS and object permissions, but only for fields in the
SELECTandFROMclauses. - Limitations:
- Does not validate
WHEREclause fields. - Fails to handle polymorphic relationships (except
Owner,CreatedBy, etc.) - Reports only the first security error encountered
- Does not validate
- Example: List<Account> accounts = [SELECT Name, Phone FROM Account WITH SECURITY_ENFORCED];
Key Use Cases
When to Use WITH USER_MODE
- Polymorphic Field Queries
User Mode supports traversing polymorphic relationships (e.g.,What.NameinEvent), whileSECURITY_ENFORCEDdoes not. - Full Query Security Validation
Use when security must be enforced on all query components, including filters inWHEREclauses - Sharing Rule Enforcement
Automatically respects sharing rules without requiringwith sharingclass declarations. - Bulk Error Reporting
Identify all inaccessible fields at once usingQueryException.getInaccessibleFields().
When to Use WITH SECURITY_ENFORCED
- Legacy Code Compatibility
For projects using API versions below 48.0 where User Mode is unavailable. - Selective Field Validation
When onlySELECT/FROMclause fields need FLS checks, andWHEREclause fields are trusted. - Simplified Exception Handling
If your error-handling logic prefers single-exception reporting.
Best Practices
- Prefer
USER_MODEfor New Code
Salesforce recommendsUSER_MODEas it provides stricter security and future-proofing. - Avoid Mixing Modes
- Use
SYSTEM_MODEexplicitly if elevated permissions are required - Update Development Tools
Ignore VSCode warnings aboutUSER_MODEif using updated API versions. These are false positives caused by tooling lag. - Handle Exceptions Gracefully
Usetry/catchblocks to manageQueryException:
try {
List<Account> accounts = [SELECT Confidential_Field__c FROM Account WITH USER_MODE];
}
catch(QueryException e) {
System.debug('Inaccessible fields: ' + e.getInaccessibleFields());
}
WITH USER_MODE is the modern, comprehensive solution for enforcing security in SOQL queries, while WITH SECURITY_ENFORCED remains a legacy option for limited use cases. By understanding their strengths and limitations, developers can build secure, maintainable Apex code that aligns with Salesforce best practices
#Salesforce #SalesforceDevelopment #SOQL #DataSecurity #FieldLevelSecurity #SalesforceTips