You are on page 1of 28

Salesforce Training

By Gayatri Sharma
Salesforce Data Security Model
• To provide a security model that satisfies numerous, unique real-
world business cases, Salesforce provides a comprehensive and
flexible data security model to secure data at different levels.
Salesforce also provides sharing tools to open up and allow secure
access to data based on business needs.
• For more in-depth information about the Security Model, see
the Protect Your Salesforce Data Trailhead trail
Basics
• In Salesforce, data is stored in three key constructions: objects,
fields, and records. Objects are similar to tables in
databases. Fields are similar to columns of the table. Records are
similar to rows of data inside the table. Salesforce uses object-level,
field-level, and record-level security to secure access to object, field,
and individual records.
The scenario
• Gayatri is an experienced leader who has recently joined ABC Corp as
a sales executive. She also has a marketing background and reports
directly to the CEO. She needs access to various objects and apps in
Salesforce.
Layer 1: Object-level-security
• Before allowing a user access, first verify that the user has
permissions to see objects of that type. Object-level access can be
managed through two configurations, profiles and permission sets.
1.1 Profiles
• In Salesforce, profiles control access to object-level and field-level
security among other things like apps, tabs, and so on.
• Since Gayatri is a new employee, an admin needs to add Gayatri to
the appropriate profile that has access to sales apps and related
objects to begin giving her access to Salesforce data.
1.2 Permission sets
• Since Gayatri has a marketing background, let’s say she wants to
access the Campaigns object to help with marketing. But since she is
already part of a sales profile, if an admin adds CRUD (Create, Read,
Update, and Delete) to Campaigns, then everyone in the profile is
able to access Campaigns. The admin wants to give permission to
access Campaigns just to Gayatri. This is where permission sets come
in. Permission sets are used to provide additional (usually special)
permissions to users who are already in a profile. In our case, an
admin needs to create a permission set that provides access to the
Campaigns object and assign that permission set to Gayatri.
Notes about permission sets:
• With permission sets, you can add and remove permissions to a small
subset of users at any time.
• You can add multiple permission sets to a given user.
• Use permission sets only when a subset of users need additional
permissions.
• If a lot of people in a profile need that permission, then create a
custom profile and add permission directly to that profile.
Layer 2: Field-level-security
• Even if Gayatri has access to objects, she still needs access to
individual fields of each object. In Salesforce, profiles also control
field-level access. An admin can provide read and write permissions
for individual fields. An admin can also set a field to hidden,
completely hiding the field to that user.
Layer 3: Record-level security
• With just object-level access and field-level access, Gayatri can only
access records she owns (that is, records created by her). But if you
look at the organization structure, she reports to Sunita Gupta (CEO)
and has two sales reps (Diksha and Mohit) reporting to her.
• This is where record-level security comes in. Salesforce provides five
ways to share records with others and access others’ records.
Five types of record-level security (also known as
record sharing rules):
• OWD: organization wide defaults
• Role hierarchy
• Sharing rules
• Manual Sharing
• Apex sharing
3.1 Record-level-security: organization-wide
sharing defaults
• In Salesforce, records have a field called “OwnerId” that points to a real
user. Owners of records are usually people who created the record and
have full CRUD access to it. Salesforce provides other ways to automatically
assign ownership to users and to transfer ownership from one user to
another user.
• Organization-wide defaults (OWD) control the default behaviour of how
every record of a given object (for example, Accounts) is accessed by users
who do not own the record.
• For example:
• If OWD for Accounts is Private, it means Gayatri can only see records she is
a owner of.
• If OWD for Accounts is Read/Write, it means anyone can read and update
(but not delete) the record.
Organization-Wide Defaults
• From Setup, enter Sharing Settings in the Quick Find box, then select Sharing Settings.
• Click Edit in the Organization-Wide Defaults area.
• Define the default access level for an object’s records with organization-wide sharing settings. Organization-wide sharing settings
can be set separately for custom objects and many standard objects, including assets, campaigns, cases, and accounts and their
contracts.
• For most objects, organization-wide sharing settings can be set to Private, Public Read Only, or Public Read/Write. In environments
where the organization-wide sharing setting for an object is Private or Public Read Only, an admin can grant users additional access
to records by setting up a role hierarchy or defining sharing rules. However, sharing rules can only be used to grant additional
access—they cannot be used to restrict access to records beyond what was originally specified with the organization-wide sharing
defaults.

By default, Salesforce uses hierarchies, like the role or territory hierarchy, to automatically grant access of records to users above
the record owner in the hierarchy.
• To disable automatic access using your hierarchies, deselect Grant Access Using Hierarchies for any custom object that does not
have a default access of Controlled by Parent.
• If Grant Access Using Hierarchies is deselected, users that are higher in the role or territory hierarchy don’t receive automatic
access. However, some users—such as those with the “View All” and “Modify All” object permissions and the “View All Data” and
“Modify All Data” system permissions—can still access records they don’t own.
Sharing Default Access Settings: These access levels apply to custom
objects and most standard objects.
• Controlled by Parent: A user can perform an action (such as view, edit, or delete) on a contact or order based on whether he or she
can perform that same action on the record associated with it. For example, if a contact is associated with the Acme account, then
a user can only edit that contact if he or she can also edit the Acme account.
• Private: Only the record owner, and users above that role in the hierarchy, can view, edit, and report on those records.
• For example, if Tom is the owner of an account, and he is assigned to the role of Western Sales, reporting to Carol (who is in the
role of VP of Western Region Sales), then Carol can also view, edit, and report on Tom’s accounts.
• Public Read Only: All users can view and report on records but not edit them. Only the owner, and users above that role in the
hierarchy, can edit those records.
• For example, Sara is the owner of ABC Corp. Sara is also in the role Western Sales, reporting to Carol, who is in the role of VP of
Western Region Sales. Sara and Carol have full read/write access to ABC Corp. Tom (another Western Sales Rep) can also view and
report on ABC Corp, but cannot edit it.
• Public Read/Write: All users can view, edit, and report on all records.For example, if Tom is the owner of Trident Inc., all other users
can view, edit, and report on the Trident account. However, only Tom can alter the sharing settings or delete the Trident account.
• Public Read/Write/Transfer: All users can view, edit, transfer, and report on all records. Only available for cases or leads. For
example, if Alice is the owner of ACME case number 100, all other users can view, edit, transfer ownership, and report on that
case. But only Alice can delete or change the sharing on case 100.
• Public Full Access: All users can view, edit, transfer, delete, and report on all records. Only available for campaigns.
• For example, if Ben is the owner of a campaign, all other users can view, edit, transfer, or delete that campaign.
Limitations of OWD
• The organization-wide sharing default setting can’t be changed for some objects:
• Service contracts are always Private.
• User provisioning requests are always Private.
• The ability to view or edit a document, report, or dashboard is based on a user’s access
to the folder in which it’s stored.
• Users can only view the forecasts of other users who are placed below them in the role
hierarchy, unless forecast sharing is enabled.
• When a custom object is on the detail side of a master-detail relationship with a standard
object, its organization-wide default is set to Controlled by Parent and it is not editable.
• The organization-wide default settings can’t be changed from private to public for a
custom object if Apex code uses the sharing entries associated with that object. For
example, if Apex code retrieves the users and groups who have sharing access on a
custom object Invoice__c (represented as Invoice__share in the code), you can’t change
the object’s organization-wide sharing setting from private to public.
3.2 Record-level-security: role hierarchies
• Virtually all companies have an organization structure where groups
of people report to their managers and their managers in turn report
to their managers, forming a tree-like org chart. In order to simplify
sharing, Salesforce provides an easy way to share records with
managers. To use this sharing rule, an admin must first add the user
to a role and grant access.
• In our case, the admin needs to add Gayatri to the appropriate role
within Gayatri’s user record.
3.3 Record-level-security: sharing rules
• Hierarchy-based sharing only works for sharing upward and in a
vertical direction. What if we want to share laterally? For example,
what if we want to share records that Gayatri owns with her peers in
the service executive teams? This is where sharing rules come in.
Sharing rules provides a way to share records laterally and in an ad-
hoc fashion via public groups.
3.3.1 Ownership-based sharing rules
• Ownership-based sharing rules let admins share records based on
role, role-and-subordinate, and public group ownership.
• For example, we can share all the records owned by anyone in a sales
executive role (including Gayatri’s) with everyone in a service
executive role. Similarly, we can share all the records owned by the
sales executives, and their subordinates, with others as well.
• Note that the public group is an ad-hoc group of individual users,
users in various roles, and other public groups. Sharing with public
groups provides a highly flexible way to share records.
3.3.2 Criteria-based sharing rules
• Criteria-based sharing rules let users access records based on the
value of a field in a record, irrespective of who owns the record. For
example, if Gayatri wants to meet with all accounts in San Francisco,
she might set a criteria-based sharing rule on all accounts whose
billing city is San Francisco.
3.4 Record-level-security: manual sharing
(Classic only)
• Record-level-security provides a mechanism to share individual
records with others. This permission is accessed through the Sharing
button on the record details page, and lets end-users share individual
record with others.
• Note: This is only available if the OWD is private or public read-only
because otherwise (say public read/write), you wouldn’t need it.
3.5 Record-level-security: Apex managed
sharing
• There are occasions when you can’t share records via UI or settings,
but you need to write Apex code to do so. For example: If Gayatri
wants to share a record with just a single user (not roles, roles and
subordinates, public groups), then she needs to ask the admins to
create an Apex managed sharing rule. Learn more about Apex
managed sharing.
Sharing a Record Using Apex

• To access sharing programmatically, you must use the share object associated with the standard
or custom object for which you want to share. For example, AccountShare is the sharing object for
the Account object, ContactShare is the sharing object for the Contact object. In addition, all
custom object sharing objects are named as follows, where MyCustomObject is the name of the
custom object:
• MyCustomObject__Share
• Objects on the detail side of a master-detail relationship do not have an associated sharing
object. The detail record’s access is determined by the master’s sharing object and the
relationship’s sharing setting. For more information, see “Custom Object Security” in the
Salesforce online help.
• A share object includes records supporting all three types of sharing: Force.com managed sharing,
user managed sharing, and Apex managed sharing. Sharing granted to users implicitly through
organization-wide defaults, the role hierarchy, and permissions such as the “View All” and
“Modify All” permissions for the given object, “View All Data,” and “Modify All Data” are not
tracked with this object.
Every share object has the following
properties:
• objectNameAccessLevel:The level of access that the specified user or group has been granted for
a share sObject. The name of the property is AccessLevel appended to the object name. For
example, the property name for LeadShare object is LeadShareAccessLevel.
• Valid values are:
• Edit
• Read
• All
• ParentID: The ID of the object. This field cannot be updated.
• RowCause: The reason why the user or group is being granted access. The reason determines the
type of sharing, which controls who can alter the sharing record. This field cannot be updated.
• UserOrGroupId: The user or group IDs to which you are granting access. A group can be
• a public group or a sharing group associated with a role
• a territory group if you use the original version of Territory Management, but not with Enterprise Territory
Management
• This field cannot be updated.
•public class JobSharing {

• public static boolean manualShareRead(Id recordId, Id userOrGroupId){
• // Create new sharing object for the custom object Job.
• Job__Share jobShr = new Job__Share();

• // Set the ID of record being shared.
• jobShr.ParentId = recordId;

• // Set the ID of user or group being granted access.
• jobShr.UserOrGroupId = userOrGroupId;

• // Set the access level.
• jobShr.AccessLevel = 'Read';

• // Set rowCause to 'manual' for manual sharing.
• // This line can be omitted as 'manual' is the default value for sharing objects.
• jobShr.RowCause = Schema.Job__Share.RowCause.Manual;

• // Insert the sharing record and capture the save result.
• // The false parameter allows for partial processing if multiple records passed
• // into the operation.
• Database.SaveResult sr = Database.insert(jobShr,false);

• // Process the save results.


• if(sr.isSuccess()){
• // Indicates success
• return true;
• }
• else {
• // Get first save result error.
• Database.Error err = sr.getErrors()[0];

• // Check if the error is related to trival access level.
• // Access level must be more permissive than the object's default.
• // These sharing records are not required and thus an insert exception is acceptable.
• if(err.getStatusCode() == StatusCode.FIELD_FILTER_VALIDATION_EXCEPTION &&
• err.getMessage().contains('AccessLevel')){
• // Indicates success.
• return true;
• }
• else{
• // Indicates failure.
• return false;
• }
• }
• }

•}
•@isTest
•private class JobSharingTest {
• // Test for the manualShareRead method
• static testMethod void testManualShareRead(){
• // Select users for the test.
• List<User> users = [SELECT Id FROM User WHERE IsActive = true LIMIT 2];
• Id User1Id = users[0].Id;
• Id User2Id = users[1].Id;

• // Create new job.
• Job__c j = new Job__c();
• j.Name = 'Test Job';
• j.OwnerId = user1Id;
• insert j;

• // Insert manual share for user who is not record owner.
• System.assertEquals(JobSharing.manualShareRead(j.Id, user2Id), true);

• // Query job sharing records.
• List<Job__Share> jShrs = [SELECT Id, UserOrGroupId, AccessLevel,
• RowCause FROM job__share WHERE ParentId = :j.Id AND UserOrGroupId= :user2Id];

• // Test for only one manual share on job.
• System.assertEquals(jShrs.size(), 1, 'Set the object\'s sharing model to Private.');

• // Test attributes of manual share.
• System.assertEquals(jShrs[0].AccessLevel, 'Read');
• System.assertEquals(jShrs[0].RowCause, 'Manual');
• System.assertEquals(jShrs[0].UserOrGroupId, user2Id);

• // Test invalid job Id.
• delete j;

• // Insert manual share for deleted job id.
• System.assertEquals(JobSharing.manualShareRead(j.Id, user2Id), false);
• }
•}
Sharing Considerations: Apex Triggers and
User Record Sharing
• If a trigger changes the owner of a record, the running user must have
read access to the new owner’s user record if the trigger is started
through the following:
• API
• Standard user interface
• Standard Visualforce controller
• Class defined with the with sharing keyword
• If a trigger is started through a class that’s not defined with the with
sharing keyword, the trigger runs in system mode. In this case, the
trigger doesn’t require the running user to have specific access.
Exercises:
• Protect Your Salesforce Data—Trail
• Sharing Settings, Field Access and others in the Salesforce docs
• Record-Level-Access Under the Hood—PDF
• Sharing Architecture—PDF
Thank You

You might also like