As next week I will give a talk about security at London’s Calling, I would like to create a blog post series regarding to Salesforce security for developers. I already talked about CRUD and FLS in a previous post so I thought it was a good idea to continue with sharing.
Sharing is the common way of referring to record level security in the platform, this is, the settings that control if a user X will have read (&report) / write / transfer / delete / share permissions for a specific record Y.
Sharing is a really complex subject, because there are many many ways in which it can be configured declaratively:
- Ownership: being a record owner will allow you to read / write / transfer / delete / share a record. This is known as full access.
- OWD (Organization Wide Defaults): with these settings you define the default behavior that each table in the system is going to have regarding to record sharing. For example, if a table is private, it will mean that only record owners can see or manipulate records by default (has full access to it), while anyone else in the system can’t. However, if a table is public read-only, others will be able to see the record in read-only mode. Set the most restrictive configuration at OWD and then grant extra permissions with other features.
- Roles: role hierarchies grant extra permissions for those people that are managers of somebody else, so that they can see the same data than their employees. Basically, the manager will get all permissions that the subordinate has over the records he owns (full access) and other records he has access to (whichever level of access he has).
- Sharing rules: one of the tools we have to grant extra permissions, additional to those obtained through the OWD. Basically, sharing rules allow you to share records, selected following a specified criteria or ownership, with a group of people (public group, roles, roles & subordinates). You will be able to decide the access level you want to provide: read-only or read-write.
- Manual sharing (or user managed sharing): another option that we have to grant extra access is to manual share a record. If the OWD for a table is set to private or public read-only, a “sharing” button will appear on the record layout, visible by those users who have full access to the record. Clicking this button will allow you to share the record with a user or group of people (public group, roles, roles & subordinates), giving them read-only or read-write access to the record.
- Profiles / Permission Sets: we have several settings at profile and permission set level that can affect sharing and that we should be aware of:
- “View All” checkbox for a specific object: this will allow users with this profile / permission set assigned to read (read-only) any records for that object, skipping even the OWD settings.
- “Modify All” checkbox from a specific object: this will allow users with this profile / permission set assigned to have full access over any record for that object, skipping even the OWD settings.
- “View All Data” checkbox, that will have the same effect as “View All”, but over every object
- “Modify All Data” checkbox, that will have the same effect as “Modify All”, but over every object
“Transfer Record” checkbox, that should be checked if we want a user to be able to transfer records, even if the sharing settings allow him to do so. I would say that this is the only feature that will allow us to restrict sharing permissions defined by ownership / OWD / roles, rather than to grant extra access.
But is there something that developers can do to track or modify sharing? And the answer is YES! Salesforce creates automatically a __Share table for each private or public read-only custom object. A __Share table will look something similar to this:
The rows in these tables will reflect the sharing information stablished by:
- Ownership: who owns the record.
- Sharing rules: to whom the record is shared with, declaratively, through sharing rules.
- Manual sharing (user managed sharing): to whom the record has been manually shared. Manual sharing rows can also be inserted programmatically.
- Apex sharing (apex managed sharing): we can insert another special kind of entries programmatically with Apex (you’ll need to have “Modify All Data” permission to do so). This kind of rules won’t be deleted automatically if the record owner changes, as it happens with manual sharing rows.
Any other sharing information as the rules provided by OWD, the role hierarchy, and “View All” , “Modify All”, “View All Data,” and “Modify All Data” WON’T be tracked within the __Share tables.
Check here how to insert manual or Apex sharing entries programmatically and here how to recalculate Apex sharing rules to remove redundancies.
In conclusion, sharing is a really extensive subject to learn, you will need to understand all the puzzle pieces to create a good sharing model. If you are a developer, you will need to understand the guts of sharing tables and sharing recalculation.
In any case, I recommend you to read in depth the Apex developer guide in which all these concepts are very well explained.
Hi Alba,
Explained very well, really appreciate your research on sharing!
I have one doubt, suppose records are being shared by apex sharing based on the record owner field. The records will be shared with the respective manager of the record owner. (Consider there is no role hierarchy)
Now suppose the record owner got changed and the newly updated record owner has different manager, now the record will be shared using apex sharing with the newly updated owner’s manager.
What will happen with the previous owner’s manager? Will he be able to see that record because there is an entry in the table with that manager?
Thanks!
LikeLike
If you are using Apex managed sharing (adding sharing rows programmatically), you will need to handle the deletion of the initial sharing row by yourself. If it was manual sharing, this happens automatically. You could detect if the record owner has changed in the object trigger for example, and act accordingly.
Kind regards
LikeLike