Dealing with record level access restriction with Dynamics CRM

CRM works extremely well with giving users access to records based on a different set of security configuration tools : cumulative security roles with a “most permissive win” mechanism, business units, team memberships, access teams, hierarchy and so on. One thing it does not do well is restricting access to specific record. Imagine the following scenario:

  • Company ABC uses Microsoft Dynamics CRM to manage its cases
  • An employee leaves company XYZ to join ABC
  • After joining ABC, the new employee is given access to Dynamics CRM and has access to ongoing and past cases, say in his/her region
  • Company ABC has open cases against firm XYZ. The employee should not be able to see those cases because it represents a conflict of interest (e.g. he/she might give insights to his/her old friends at XYZ)

The following image provides an illustration of what we are trying to accomplish.


If you have worked with Dynamics CRM and know its security model, you can already read between the lines here. There are no easy ways to make this happen. This article provides a possible solution for this requirement based on a recent experience on a large CRM implementation.

Ruling out Team Membership & Ownership

In our scenario, members of a team or a business unit get access to all records  owned by their team or business unit. If we follow basic team/BU record ownership, the problem in this case is that once a record needs to be isolated from one individual member of the team, one of two things needs to happen:

  1. The record owner has to be changed (it can no longer be the team everyone is a member of) and the record needs to be shared with users who can still see it, but not with the individual that is getting the restriction applied OR
  2. The individual who is getting a restriction applied has to be removed from the team and all the records owned by his/her team need to be shared with him/her except the one he/she is restricted to see.  This technique implies heavy maintenance since the user will need to access new cases created for the team he/she used to be a member of.

Sharing in both cases can be done via the record share functionality, access team or any other mechanism that suits the business need. It should also be automated if there is a large number of records to share. You also need to save the information about the user and its restriction on a separate entity to be able to backtrack and understand why the records/ownership and so on have been modified.

Why we didn’t like the “Sharing” functionality

Using the out of the box sharing of record can cause problems in the long run. The PrincipalObjectAccess (POA) table gets bigger and bigger, causes performance issues and has to be cleaned up on a regular basis. In addition to that, the more access is controlled by sharing, the more you run the risk of having performance issues because of the complexity overhead in system lookups when it needs to display a record or list of records to users.

A solution using “Access Teams”

We decided to go with a design centered around Access Teams. The “Case” entity gets an “Access Team Template.” When a user is created and added to his/her group (team or business unit), we start a process to insert the user in the Access Team of each case related to his/her business unit. In order to restrict access to a specific case for a user, we can simply remove the user from the case’s Access Team.  For tracking purposes, we created a “Security Exception” entity that is created and has a relationship with a case and a user and an additional attribute that indicate the type and reason for the “Restriction”. To apply the access restriction on a case for a user (i.e. remove user from access team), we create a Security Exception record. We link the target case and user, and specify the restriction type. After the Security Exception record is created, a plugin is fired to perform validation and to remove the user from the case’s access team.

One of the reasons with went with that model was that we didn’t want to have a base security model that gets “broken” every time there a single person with restricted access, by changing record ownership or removing user from the team he/she is supposed to be a member of. With access teams, the record ownership remains the same, and users also remain on their team at all times which makes everybody happy and maintenance easier. The downside is that when a user is created, we have to look for all the cases in his/her business unit and manually (with code) add the user to each access team. Same when a case is created, users member of the case’s business unit have to be added to the case’s access team manually (also with code). That is the comprise we had to make.

As far as performance goes, the end results remain to be seen in the long run. Our system will have between 2000 and 3000 users when we complete our rollout. It will deal with over 1 million cases across multiple teams. Preliminary performance tests results look promising. I will repost if we get into any issue as it relates to performance.

It’s been a while! This feels great Smile  – Happy CRM’ing !

11 thoughts on “Dealing with record level access restriction with Dynamics CRM

  1. Hi Salim,
    It is a very late but what about creating a RetrieveMultiple plugin that will filter the cases that a certain user can see (based on a flag on the user & case entities).

    • Shehab,

      You solution works but there are a few things to consider when using plugins on RetrieveMultiple. In this case for example,

      1. You have to loop through all the items returned by the RetrieveMultiple request and filter out records manually (possible performance issue)
      2. If the user accesses the case from a location other than the list view (e.g. a direct link), how do you make sure the record is protected? Additional code to write and maintain and possible negative impact on user experience.

      It still can be a viable solution in some cases, you just need to consider all the possible impacts.


  2. Hi Salim,

    I’m interested in the performance of this particular mechanism as I’d like to achieve something similar. How has performance been so far on your behalf?

    • Michael, sorry it’s been a long time since your comment.

      FYI, we went around and asked how heavily the access teams are utilized around the world and the responses were very encouraging. Some implementations have millions of access teams and it works fine (as long as you access to the backend to fine tune database indexes if needed). We don’t have issues yet on our side but we haven’t fully rolled out our entire user base. I’m still anxiously waiting… HTH.

  3. Hello,

    I really like your approach with the access team. We have exactly the same behavior that needs to be adopted for our project. However, some questions remain unanswered.

    How do you manage the ownership of the record ? Is it a generic team, a generic user or a real user who owns the record ? In addition, what kind of division structure do you have in place to meet this need ?

    We have difficulty setting up a proper divison structure and roles to restrict access to certain files.

    If you could give us some information, it would help us greatly in our project.


    • Bonjour Pierre,

      In our case, we have teams that own records based on region and case type, this is mostly for reporting, users are not members of these ownership teams; the teams have security roles to be able to own the records. The assignment of the cases is automated on creation using workflows. You don’t want the owner to be a generic user as it will burn licence counts.

      The best advice that I can give you is the simpler you can keep it, the better.

      Au plaisir – Salim

  4. Bonjour Salim,

    Thank you very much for the quick response, it’s really appreciated. I’m sorry to bother you again, but I have another question. Which level access the users have on the case entity (Parent/Chil BU or User or another) and all entities in a Relationship with cases ?

    We hesitate between two BU structures.

    Option # 1: A structure with three hierarchical levels (1 being the top level and 3 the lower level) where the users would be defined in the central division (2) and the owner (a generic team) in the divisions (1). The access levels would be set to Parent / Child BU for the case entity and the entities related to case.

    Option # 2: A structure with two hierarchical levels where users and teams would be at the same level and access levels would be set to user for the case entity and the case related entities.

    Wich approch seems to make more sense ? One of the two mentioned structures or another option that we have not seen ?

    Un énorme merci à l’avance.


    • Salut Pierre,
      Our scenarios are likely different. For us, we had 4 BU levels for business reasons (that in of itself added its own set of challenges). Users had the ability to view/edit Top-Down (so Parent Child). Ownership teams and users were sitting in each of the business units as required.

      In your case, I would go with your option #2 especially if you don’t have a need for 3 levels of hierarchy from a business standpoint. It will keep the structure and behind the scenes access calcuation easier for the system.

      Bonne chance!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s