Share Records using GrantAccess, ModifyAccess, RevokeAccess and its relation to PrincipalObjectAccess table
In dynamics CRM ‘GrantAccessRequest’ class is used to share any record with a team or a User. Similarly ‘ModifyAccessRequest’ class is used to modify the access rights and ‘RevokeAccessRequest’ class is used to revoke the access.
There are few AccessRights options are available. You can choose one or multiple of them while sharing the records.
- AccessRight.CreateAccess
- AccessRight.WriteAccess
- AccessRight.DeleteAccess
- AccessRight.ShareAccess
- AccessRight.AssignAccess
Multiple access rights can be assigned using ‘|’ symbol.
Ex: AccessMask = AccessRights.CreateAccess | AccessRights.WriteAccess
GrantAccessRequest and ModifyAccessRequest:
AccessMask, Principal and Target are the 3 important things required to grant or modify any access request. AccessMask has already been defined above.
Principal: It represents the team or user that is granted access to.
Target: It represents the entity that is target of request to grant or modify access.
Syntax:
var grantAccessRequest = new GrantAccessRequest { PrincipalAccess = new PrincipalAccess { AccessMask = AccessRights.ReadAccess | AccessRights.WriteAccess, Principal = TeamReference }, Target = OpportunityReference };
var modifyTeamAccessReq = new ModifyAccessRequest { PrincipalAccess = new PrincipalAccess { AccessMask = AccessRights.DeleteAccess, Principal = TeamReference }, Target = OpportunityReference };
If you have the id (guid) of team or opportunity then you can create the entity reference using the EntityReference class as:
TeamReference = new EntityReference(“team”, id);
After you have created the request for GrantAccess or ModifyAccess then you can call the execute method to apply changes.
RevokeAccessRequest:
Unlike GrantAccess and ModifyAccess, RevokeAccess has only 2 important things, one of them being Target has already been defined abovel. Other is :
Revokee: It represents the team or user whose access you want to revoke.
Synatx:
var revokeTeamAccessReq = new RevokeAccessRequest { Revokee = TeamReference, Target = OpportunityReference };
Now you can call the execute method to apply changes.
PrincipalObjectAccess table:
This table inside the Dynamics CRM database stores all the record sharing information, i.e. what records have been shared with which users and with what level of access.
The below table describes the structure of PrincipalObjectAccess table.
How data is being stored in this table for our day-to-day sharing activities?
For example we have an account as ‘ABC Test’ and it contains:
Contacts: 2, Opportunity: 3, Activities: 4
- Sharing with Users
Now if admin shares this record with another 2 users then, this operation of sharing record will create 10*2 (10 records with 2 users), so total 20 rows in PrincipalObjectAccess table.
A user who does not have a full view of all the subordinate records, may be thinking that he is sharing just a record, but in reality, it is not just one record, they are 10.
- Sharing with Owner team
After creating an owner team and then sharing records with it, will create only 10 records in PrincipalObjectAccess table.
- Sharing with Access team
As it is common practice in most implementations to have two teams for a record (readonly and full access), we will create two team templates and share account record.
There is a database overhead that comes with Access Teams because of their membership. For each record where an access team is used, it creates a membership row in the TeamMembership table. E.g. in our case, we shared 1 record with 2 access teams, so it has created 2 records in the TeamMembership table.
This overhead does not exist with owner teams.

This was originally posted here.
*This post is locked for comments