Microsoft CRM has a security model feature which is not well documented but can be of use when designing the security for your CRM implementation. The concept is that with CRM configured a certain way you can ensure that child records created in CRM are automatically shared to the owner of the parent record. A common place you might want to do this is with customer records (Contacts and Accounts) – where you might like any child records added to these records by other users to be always visible to the owner of that Customer record. CRM utilizes Shares for this but these are hidden shares that you will not see in the CRM UI. They do exist in the PrincipalObjectAccess (POA) table though. Because Sharing is used, users are able to see records above and beyond what their security role permits. i.e. A user’s security role may grant them Read access to only the Activity records they own but if another user adds an Activity to one of their Contacts and implicit sharing is enabled then the user will be able to see this Activity, even if they are not the owner of the record.
There are some peculiarities related to implicit shares that you need to understand if you want this to be a key part of your security design.
Firstly, the settings that drive this behavior are the Cascade settings on your entity relationships:
To have an implicit share created when a child record is added to a parent you need to have the Reparent option set to the Cascade. This cascade is triggered when the lookup field on the child record changes from one parent to another. This trigger also fires when a child record is first created under a parent record as the lookup field goes from NULL to a non-NULL value. Now, there is a caveat here, the share will only be created if the owner of the child record differs from the owner of the parent record. But then if the records share the same owner there is no need to share access.
Here’s how this looks. I have these Cascade settings between Contact and Task:
I have a Contact owned by CRM Admin and another user, Ken Mallit has created a Task against this Contact:
On the Task record there is no visible Share:
But in the PrincipalObjectAccess table you will see a Share has been created against the Task, sharing access to the CRM Admin user:
And if I log in as CRM Admin I can see the Task owned by Ken, even when my security role only grants user-level read access to Tasks.
Now, if Ken moves the Task from the original Contact to a different Contact (re-parenting the record) that too fires the Re-parent event and the implicit share is updated. After this change I see 2 records in the POA table:
The original share sharing the Task to CRM Admin is still there but the InheritedAccessRightsMark value is now 0. This is what CRM does, it zero’s out the permissions shared rather than deleting the record. I believe I heard from a Microsoft colleague that a maintenance job purges these eventually. We also see a new share, sharing the Task to Jill Frank who is the owner of the Contact I moved the Task to. This sharing change means CRM Admin loses visibility of this Task (which is good as the Task no longer relates to one of their Contacts) and Jill gains visibility of the Task.
Let’s now look at what happens during an Assign event. Currently, we have a Task owned by Ken that is parented by a Contact owned by Jill. An implicit share provides Jill access to the Task. If we now reassign the Contact record from Jill to Mark let’s see what happens to the implicit share:
You will see that no new Share has been created for Mark. And the existing Share for Jill has been zeroed out (InheritedAccessRightsMark value is now 0). This caught me by surprise when I first hit this. This feels like a functional gap to me. Now there is another Cascade setting we can fiddle with here to alter the behavior, but you may not like what it does. The above tests were done with the Cascade Assign setting set to None. If we flick that over to Cascade All and then repeat the test we see the same result with the implicit shares but the reassignment of the Contact will cascade down and the Task record will get reassigned as well. This will give Mark access to the Task attached to his Contact (he will now be the Owner of the Task) but Ken, the original Owner of the Task, will lose access. Which may well be an undesirable behavior. I found this behavior quite problematic on my last project as I was using Teams to manage access to Contacts and whenever the Team changed on the Contact I had to make sure Tasks were not reassigned but still needed access to the Task to be adjusted to the new Team. End up creating a custom “Assigned To” field and some other bits and pieces to address that.
Hope this helps someone out there. Implicit shares are an interesting feature. It feels a little incomplete to me. It is important you are aware of it so understand why users see what they see. But if you want to build it into your security design you need to be very careful.