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 SELECTWHERE, and polymorphic fields like Owner.
  • 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 SELECT and FROM clauses.
  • Limitations:
    • Does not validate WHERE clause fields.
    • Fails to handle polymorphic relationships (except OwnerCreatedBy, etc.)
    • Reports only the first security error encountered
  • Example: List<Account> accounts = [SELECT Name, Phone FROM Account WITH SECURITY_ENFORCED];

Key Use Cases

When to Use WITH USER_MODE

  1. Polymorphic Field Queries
    User Mode supports traversing polymorphic relationships (e.g., What.Name in Event), while SECURITY_ENFORCED does not.
  2. Full Query Security Validation
    Use when security must be enforced on all query components, including filters in WHERE clauses
  3. Sharing Rule Enforcement
    Automatically respects sharing rules without requiring with sharing class declarations.
  4. Bulk Error Reporting
    Identify all inaccessible fields at once using QueryException.getInaccessibleFields().

When to Use WITH SECURITY_ENFORCED

  1. Legacy Code Compatibility
    For projects using API versions below 48.0 where User Mode is unavailable.
  2. Selective Field Validation
    When only SELECT/FROM clause fields need FLS checks, and WHERE clause fields are trusted.
  3. Simplified Exception Handling
    If your error-handling logic prefers single-exception reporting.

Best Practices

  1. Prefer USER_MODE for New Code
    Salesforce recommends USER_MODE as it provides stricter security and future-proofing.
  2. Avoid Mixing Modes
  3. Use SYSTEM_MODE explicitly if elevated permissions are required
  4. Update Development Tools
    Ignore VSCode warnings about USER_MODE if using updated API versions. These are false positives caused by tooling lag.
  5. Handle Exceptions Gracefully
    Use try/catch blocks to manage QueryException:

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

Leave a reply

Your email address will not be published. Required fields are marked *