Newer Version Available
Filter SOQL Queries Using WITH SECURITY_ENFORCED
Apex generally runs in system context; that is, the current user's permissions and field-level security aren’t taken into account during code execution. Sharing rules, however, are not always bypassed: the class must be declared with the without sharing keyword in order to ensure that sharing rules are not enforced. Although performing field- and object-level security checks was possible in earlier releases, this clause substantially reduces the verbosity and technical complexity in query operations. This feature is tailored to Apex developers who have minimal development experience with security and to applications where graceful degradation on permissions errors isn’t required.
WITH SECURITY_ENFORCED applies field- and object-level security checks only to fields and objects referenced in SELECT or FROM SOQL clauses and not clauses like WHERE or ORDER BY. In other words, security is enforced on what the SOQL SELECT query returns, not on all the elements that go into running the query.
- After the WHERE clause if one exists, else after the FROM clause.
- Before any ORDER BY, LIMIT, OFFSET, or aggregate function clauses.
1List<Account> act1 = [SELECT Id, (SELECT LastName FROM Contacts)
2 FROM Account WHERE Name like 'Acme' WITH SECURITY_ENFORCED]- Traversing a polymorphic field’s relationship is not supported in queries using WITH SECURITY_ENFORCED. For example, you cannot use WITH SECURITY_ENFORCED in this query, which returns the Id and Owner names for User and Calendar entities: SELECT Id, What.Name FROM Event WHERE What.Type IN (’User’,’Calendar’).
- Using TYPEOF expressions with an ELSE clause is not supported in queries using WITH SECURITY_ENFORCED. TYPEOF is used in a SELECT query to specify the fields to be returned for a
given type of a polymorphic relationship. For example, you cannot use WITH SECURITY_ENFORCED in this query. The query
specifies certain fields to be returned for Account and Opportunity objects, and Name and
Email fields to be returned for all other objects.
1SELECT 2TYPE OF What 3 WHEN Account THEN Phone 4 WHEN Opportunity THEN Amount 5 ELSE Name,Email 6END 7FROM Event - The Owner, CreatedBy, and LastModifiedBy polymorphic lookup fields are exempt from this restriction, and do allow polymorphic relationship traversal.
- For AppExchange Security Review, you must use API version 48.0 or later when using WITH SECURITY_ENFORCED. You cannot use API versions where the feature was in beta or pilot.
If any fields or objects referenced in the SOQL SELECT query using WITH SECURITY_ENFORCED are inaccessible to the user, a System.QueryException is thrown, and no data is returned.
To enforce object and field permissions on the User object and hide a user’s personal information from other users in orgs with portals and communities, see Enforcing Object and Field Permissions.
Example
1List<Account> act1 = [SELECT Id, (SELECT LastName FROM Contacts),
2 (SELECT Description FROM Opportunities)
3 FROM Account WITH SECURITY_ENFORCED]Example
1List<Account> act2 = [SELECT Id, parent.Name, parent.Website
2 FROM Account WITH SECURITY_ENFORCED]Example
If field access for Type is hidden, this aggregate function query throws an exception indicating insufficient permissions.
1List<AggregateResult> agr1 = [SELECT GROUPING(Type)
2 FROM Opportunity WITH SECURITY_ENFORCED
3 GROUP BY Type]