When you first learned that every record in Salesforce has a designated owner, you might have been a little surprised. In most database-driven applications and platforms, access to data isn’t tied to any ”’ownership” concept.
Record ownership is at the core of Salesforce’s record access capabilities, which allow you to specify which users or types of users should be able to access specific records or types of records. Salesforce.com’s architects and developers have spent years creating a highly functional and massively scalable record access infrastructure around record ownership, saving you the monumental effort of building that infrastructure yourself.
In this post, you’ll learn how those years of heavy lifting have actually simplified record access for the most common enterprise security models, allowing you to configure record access declaratively instead of with painstakingly developed code. You’ll also get an “under the hood” view of record access, and learn how to implement your record access model and avoid potential pitfalls along the way.
Why Users Should Own Records
The record ownership sharing model recognizes the natural responsibility that people take for various touch points with their customers. For example, salespeople add contacts to their Salesforce organization to flag them as potential customers, managers direct the activities of their employees, and service agents take temporary custody of cases while working to resolve customer issues.
By assigning records to owners and owners to roles in a role hierarchy, you can easily configure your sharing model to suit these tasks, as well as the following more general use cases.
- Solo work: For many assignments, employees work independently for their individual customers and have their progress monitored by their team’s manager. Configuring access at the role level is ideal for this use case because the role hierarchy configures record access vertically, not horizontally. Being a member of a role does not grant a user access to records that other members of that role can access, but record access does roll up the role hierarchy, giving role members access to records that their role subordinates can access.
- Ad hoc collaboration: Every organization must both protect sensitive data and allow its users to collaborate so they can quickly solve problems for their customers. The record ownership model clarifies which user is responsible for keeping each record accurate and secure, and allows record owners to share their records with other users when appropriate.
- Structured collaboration: As companies grow and need to allocate responsibilities for processes and functions across many business units, the members of their organization need to share data across these business units more and more often. A company’s customer service team needs business account data from its sales team, its finance team needs to know the revenue that the sales team is converting from its opportunities, and so on. The record ownership model makes this kind of large-scale, cross-team record sharing easy.
For example, you could use this account sharing rule for the previous sales-to-customer service use case.
How Ownership Drives Record Access “Under the Hood”
All of the data sharing capabilities of the Force. com platform are supported by three key components of the ownership-based sharing architecture.
- An Owner field for all records, except detail records in master-detail relationships.
- Object share tables, which define which users and groups should receive access to records.
- Group membership tables, which can grant users access to records through personal and public groups, queues, the role hierarchy, and the territory hierarchy.
Sharing Rows and Hierarchy-based Inheritance
When a user creates a record, that user is identified in the record’s Owner field in the appropriate object record table. (The account object has an Account table, the opportunity object has an Opportunity table, and so on.) At the same time, Salesforce adds a sharing record to the object’s share table, which gives record owners access to the records that they own.
Each row in an object share table contains fields that record the following.
- The ID of the record being shared
- The ID of the user or group being granted access to the record
- The level of access (e.g., Read Only, Read/Write) being granted to the user or group
- The reason the access is being granted (e.g., because the user owns the record, because the record has been manually shared by its owner to a user)
When a record is shared to a group, Salesforce doesn’t create a sharing record in the object share table for each of the group’s members. Instead, it creates a single sharing record for the group in the object share table. The object share table and group membership tables are then used together when a user requests access to a particular record.
When a user requests access to a record, the system does the following.
- First, it determines whether a profile, permission set, or organization-wide default setting already give the user the level of access that user is requesting to the record.
- If the user does not have at least that level of access to the record, the system queries the object share table to see if there is a row in which the record’s ID appears in the object ID column and the user’s ID appears in the UserOrGroupId column.
- Next, it queries the group membership tables to identify all the groups that could provide access to the user.
- It then scans the object share table again to see if there is a row in which any of these groups has already been granted access to the record.
- Finally, it compares the level of access granted directly to the user with the levels of access granted to the groups the user belongs to, giving the user the least restrictive level of access from this comparison.
Salesforce also uses group membership tables together with the role hierarchy to give users assigned to roles access to records owned by or shared to members of subordinate roles, and records shared to the subordinate roles themselves.
- Each user can be assigned to only a single role in the role hierarchy, and no user is granted access by default to records that other users assigned to the same role can access.
- Users at higher levels of the role hierarchy inherit the same level of access to records that users assigned to subordinate roles have.
- Under the hood, Salesforce maintains role groups that give users assigned to a role access to records owned by or shared to members of subordinate roles, and records shared to the subordinate roles themselves. In this diagram, Marc is assigned to the CEO role, so he is a member of all the other role’s role groups. Similarly, because Maria is assigned to the VP of Sales role, she is a member of Sales Ops, Western, and Eastern role groups.
Note: For clarity, these descriptions simplify how record access is inherited in the role hierarchy. To optimize the underlying Salesforce architecture for performance, salesforce.com uses various junction objects in addition to the role hierarchy, the object share tables, and the group membership tables described here. See this overview of the Salesforce sharing architecture.
Ownership-based Sharing Rules
Sharing rules like the one introduced in the previous “Structured Collaboration” bullet also use the object share table and group membership tables to grant record access in an organization.
- Each rule has both a source group that identifies which records will be shared and a target group that defines who is granted access to those records.
- Again, users at higher levels of the role hierarchy inherit the same level of access to records that users assigned to subordinate roles have.
- When you create a sharing rule for an object, Salesforce creates a row in the object’s share table for each of the records owned by users assigned to the source group (e.g., the Sales Ops role). Each of these rows grants users in the target group (e.g., the VP Service role) access to one of the records.
Note: Criteria-based sharing rules operate just like ownership-based sharing rules, but they determine which records should be shared differently. Criteria-based sharing rules determine which records to share based on field values in object records. Salesforce writes a sharing row for the target group in the object share table for each of the records that satisfy the sharing rule’s selection criteria. Just as it does for ownership-based sharing rules, Salesforce then uses the object share table and group membership tables to determine the appropriate record access.
Sharing Records from and to a Role and its Subordinate Roles
The rule in the example above shares data between two single roles on different branches of the role hierarchy. You can use the “Roles and Subordinates” category on sharing rules to share records more broadly across hierarchy branches. When you define a sharing rule, you can use this category for your owned by members of source group, your Share with target group, or both.
When you use the “Roles and Subordinates” category for the source group of your sharing rule, all records owned by users in and below the source group in the hierarchy are shared to the target group. Similarly, when you use “Roles and Subordinates” for the target group of your sharing rule, the source group’s records are shared to all users in and below the target group in the hierarchy. Users above the target group also gain record access because of the role hierarchy’s default access rollup.
You can use “Roles and Subordinates” to share records from:
- A role and all of its subordinate roles in one branch of the role hierarchy to a role and all of its parent roles in a different branch (“Roles and Subordinates” on the source)
- A single role in one branch of the role hierarchy to all the roles in a different branch (“Roles and Subordinates” on the target)
- A role and all of its subordinate roles in one branch of the role hierarchy to all the roles in a different branch (“Roles and Subordinates” on both the source and the target)
Sharing Records from and to Public Groups
In addition to using the role hierarchy to configure record access in your organization, you can also create and use public groups, which are unstructured and can have any collection of users and other groups as their members. You can use public groups as the source or target group in your sharing rules, and then share the records owned by anyone in your organization to anyone else in your organization.
Record Ownership and Data Security
Distributing ownership of records to end users and allowing the users to share those records does raise security concerns for some Salesforce developers, administrators and architects. They might say, “This data is the property of my company, not any individual; I need to be in full control of who sees what and when.”
To ensure that companies are able to strike the right balance between collaboration and control for their organizations, Salesforce includes a number of features that restrict access to data.
- Each object in Salesforce has an organization-wide default setting that specifies the default level of access that an organization’s users have to that object’s records. When you set an object’s organization-wide default to Private, only users who own records belonging to that object, and users with profile- or permission set-based access to that object, can access its records, unless you extend access to those users with sharing tools such as the role hierarchy.
- You can configure custom objects to prevent users from automatically inheriting access to them through the role hierarchy. You can also apply this restriction to records shared to specific public groups.
- To prevent users from deleting records, you can configure user profiles so that no user—including record owners—can delete any records. (If you make this configuration, record owners can still manually share records to other users.)
- If you determine that none of these restrictions provides sufficient control for your organization, you can make a single user—such as yourself, an administrator, or a “dummy” user—the owner of all of an object’s records.
Record Ownership and Sharing Performance
While you might need to concentrate data ownership for security reasons, you should also be aware that this security strategy could present performance risks.
For example, when you move a user from one role to another role, Salesforce automatically adjusts both the sharing configuration provided by the role hierarchy and the sharing rules associated with the records that the user owns. If the user owns all or a large percentage of an object’s records, the sharing calculations can take a long time to complete. To avoid these long calculations, exclude the user from your role hierarchy if possible. If you must assign the user to a role so this user can properly share records to other users in your organization, try both to dedicate an entire branch to this user at the top of your role hierarchy and to avoid moving this user elsewhere in the role hierarchy. See Designing Record Access for Enterprise Scale.
Record ownership might seem like an unfamiliar method of controlling access to data on a development platform, but it greatly simplifies the task of implementing most common enterprise security models. With the default Salesforce record access functionality, you can implement a security model that both allows your users to collaborate effectively and protects your company’s sensitive information.
- Designing Record Access for Enterprise Scale
- Record-Level Access: Under the Hood
- Architect Core Resources
About the Author
Bud Vieira is an Architect Evangelist within the Technical Enablement team of the salesforce.com Customer-Centric Engineering group. The team’s mission is to help customers understand how to implement technically sound salesforce.com solutions. Check out all of the resources that this team maintains on the Architect Core Resources page of Developer Force.