0

I am working on an assignment where I need to expose Contact data to a webservice via REST API. I was able to get the REST API call working thru Postman/SoapUI only when the Profile has the View All permission checked for the Contact of the running user. My objective is to restrict the access for the webservice to specific fields on Contacts, not on all fields. Is there anyway I can get this done without having to give the View All permission?

1

Permissions and the Salesforce REST API

The Salesforce REST API respects field-level security and record-level security. In order for you to obtain access to a specific Contact record, the user account under which you authenticate to Salesforce must be able to see it.

"View All" permission controls record-level visibility. A context user with View All permission ignores the effects of sharing rules and Organization-Wide Defaults, meaning it can see every Contact in the system at the record level. It does not mean that every field on the Contact is visible.

Field visibility is controlled by Field-Level Security. You can configure this on the Profile and/or assigned Permission Sets for the user under which you authenticate. That user will only be able to obtain data for the fields for which the user has Read access, on Contacts which Record-Level Security allows them to see.

You can leave the View All permission turned on if it meets your specific record-level visibility needs while restricting access to individual fields with Field-Level Security.

You can illustrate this FLS enforcement for yourself using Workbench. For example, if you remove FLS for yourself from the Industry field on Account, and then use REST Explorer to issue the following GET request:

/services/data/v43.0/sobjects/Account/001360000XXXXXXXXX?fields=Name,Id,Industry

You will get back

SELECT Name,Id,Industry FROM Account ^ ERROR at Row:1:Column:16 No such column 'Industry' on entity 'Account'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names

Because you don't have permission to see that field. This applies even to a System Administrator, who has Modify All Data permission - which trumps View All.

Custom API Classes

The material below is less relevant to your situation, since you explained that you are using the native Salesforce API directly rather than writing your own API class.

Because Apex runs in system mode, you need to manually enforce CRUD and FLS based on the permissions of the current running user in your Apex REST API classes. The document Enforcing CRUD and FLS actually has an example just for your use case, "CRUD and FLS Enforcement in Apex Web Services" (it's written with SOAP web services in mind, but REST would be the same logic).

Read enforcement looks like this, from the linked document:

  webservice static String getContactPhone (Id contactId) {
        // Check if the user has read access on the Phone field
        if (!Schema.sObjectType.Contact.fields.Phone.isAccessible()){
          return null;
        }

        return [SELECT Phone FROM Contact WHERE            
                Id=:contactId].Phone;                                                      
      }

Another critical piece to consider is the sharing model declared on your REST service class. If you're seeing a need to have the Contact View All permission on your authenticated user, you probably have declared your class with sharing or inherited sharing. That's good, in most situations, because it applies your org's sharing rules to queries performed by the class. In select use cases, you might want to use without sharing, but it's better to permission that level of access at the user level.

  • Thanks for your response. I don't have any wrapper class in Salesforce and hence I cannot enforce CRUD in code. The service is directly calling the REST API by providing the contact Id as /services/data/v43.0/sobjects/Contact/{salesforce_id_of_contact}?fields=Id,Name. The problem is I cannot get this REST API working without giving the "View All" permission on contact object. If I uncheck and just leave the "Read" permission, it still doesn't work. So, it appears that I cannot enforce FLS in this case, correct? – Balaji Pooruli Oct 24 '18 at 15:06
  • I misunderstood your question. You are calling the Salesforce REST API directly, not writing your own REST API in Apex. I will update my answer. – David Reed Oct 24 '18 at 15:08
  • again thanks for updating the answer. Without the "View All" permission, the REST API is not working for me. With the "View All" and have the FLS checked on Id and Name, I assume the webservice user cannot see any info other Id and Name, correct? However, this is not the case. The webservice user is able to see all fields on Contact even though all contact fields are not visible under his profile. Only Id and Name are checked for 'Read' access. – Balaji Pooruli Oct 24 '18 at 16:17
  • Where are you configuring the FLS? That is not how enforcement works on API access (I added an example in my answer). – David Reed Oct 24 '18 at 16:34
  • 1
    Does the Basic User profile itself have field permissions on Contact? The Permission Set is additive to the Profile; it does not override existing FLS. – David Reed Oct 24 '18 at 16:40

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.