1

According to our client's requirements, ordinary users of developed applications should not be able to access Setup area in Salesforce.

Out first naive approach was simply to revoke 'View Setup and Configuration' permission at a profile level. But as it turns out, this also implicitly revokes whole bunch of other permissions - mainly to different system sobjects and fields.

As result we are now getting errors endlessly in different places of our application. Some examples of places where this causes problem with access:

  • User.ProfileId field - no access
  • Permission set related tables - no access
  • Table with static resources - no access when querying directly via SOQL

So it looks like revoking 'View Setup and Configuration' permission is a slippery slope. Is there any other way of blocking access to setup area for non admin user, i.e. something which wouldn't cause so many hidden consequences re access of system objects?

Any help would be appreciated.

  • The three items you mentioned, are they all examples of information that the user accesses through Apex? If so, did you try to route those requests through Apex classes with without sharing permissions? – Renato Oliveira Apr 28 at 15:08
  • @RenatoOliveira Yes, we are querying those things through Apex. 'Without sharing' has nothing to do with objects and fields access, it controls access to records. But in our case, user is loosing access to query object/field at all, i.e. 'No such object/field' error. – wesaw Apr 28 at 15:23
  • You are right. I thought maybe permission sets could help, but it looks like it won't as well... – Renato Oliveira Apr 28 at 15:27
  • 1
    That doesn't seem right - SOQL in Apex should still be able to access setup fields. SOQL doesn't enforce FLS on its own. And I've had no trouble with Apex querying permission sets while running as users with low privileges. Can you provide more detail on the context of how these failures are happening? E.g. what is the entry point to the transaction, what do your queries look like, and what line of code is throwing the exception? – Charles T Apr 28 at 15:30
  • @CharlesT There are two use cases. 1) When our mobile app queries for SF objects via Rest API - querying for permission set tables or for User.ProfileId fields results in 'Object/field does not exist' error or whatever; 2) When we are querying for the same right inside apex classes - by default Apex does not enforce object/field level security, but we are doing it on our own in our custom data access layer - that's where we are getting 'No permission error' to read object or field. – wesaw Apr 28 at 15:48
3

OK so I'm going to shift this to an answer based on wesaw's responses.

There are two use cases. 1) When our mobile app queries for SF objects via Rest API - querying for permission set tables or for User.ProfileId fields results in 'Object/field does not exist' error or whatever

OK, so what you will need to do is a custom Apex REST service which queries the privileged information, filters it out based on business requirements, and divulges only the parts that are necessary for your mobile app to function properly. Ensure that no combination of parameters can result in divulging information a user should not be allowed to see. Assume your users are hackers and could call the REST service themselves.

2) When we are querying for the same right inside apex classes - by default Apex does not enforce object/field level security, but we are doing it on our own in our custom data access layer - that's where we are getting 'No permission error' to read object or field.

So ultimately, the purpose of your data access layer enforcing SOQL is to ensure that you do not divulge information that the end user is not entitled to. And certainly if a user does not have view setup permissions they will not have the object/field permissions for setup objects.

But there are plenty of valid use cases where your Apex code needs to query setup information in order to execute business logic, even if that is not info you would normally disclose to the end user. I would suggest you create a helper class that you use for all these "setup queries". In the helper, query the tables directly, bypassing the access layer, but ensure the data you return doesn't represent sensitive information.

If the company is uncomfortable bypassing the access layer ever, create accompanying technical documentation that explains exactly how your code is still operating within their security requirements. Point to it from the comments of the helper file for future reference.

  • Thanks a lot for the detail answer. It's more or less acceptable for us to do what you're suggesting for case 2. But the main problem is with case 1. Switching from standard Rest API to custom one would cause significant amount of work (probably months). The other problem is that mobile app is fetching tons of records utilizing different optimization techniques provided by Rest API (e.g. bulk querying, querying in chunks). Trying to mimic all that with custom web service would be a nightmare (if feasible at all). That's why we are looking for other alternatives to block access to Setup Area. – wesaw Apr 29 at 9:58
  • To be clear, I'm not saying to dump the standard API completely. Just for the cases where you need business logic to depend on privileged information. Does the inaccessible data represent massive chunks? – Charles T Apr 29 at 11:30
  • Make sense. Need to check what exactly types of queries return huge amount of data. But I got your point, e.g. fetch User.ProfileId via custom webservice, then use standart Rest API to fetch tons of records for some sobject filtering by user profile id. That would be sort of two-step process (instead of single query), but sounds promising. – wesaw Apr 29 at 12:03
  • But I wish I knew the whole list of such system sobjects and other stuff which become non-accessible. Cause currently we are discovering problems via testing whole app, i.e. huge probability to miss something( – wesaw Apr 29 at 12:05
  • This will not be any comfort to you at such a late stage of development, but it really underscores why it is important to test Salesforce development as users with less permissions, early and often. As for a whole list of objects, maybe try some creative Tooling API queries on UserEntityAcccess (developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/…) to see what the differences are before/after removing the permission from a user? – Charles T Apr 29 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.