A Brief Explanation of Dynamics 365 Entity Ownership Performance Considerations
Security in Dynamics 365 is kind of this mysterious topic. It's not documented in any meaningful depth and what is known publicly comes more from observation than a comprehensive look at its physical implementation. The underlying orchestration is somewhat of a black box that is easy to take for granted. The irony is no one can implement a system without some attention to the security model as it's a fundamental part of every deployment. A user can't even access the system unless they have at least one security role assigned. As a system model is being designed customizers must choose between a user ownership versus an organization owned security paradigm. Most customizers don’t know really know potential implications and one might choose one paradigm over another. This is a high-level overview of how entity ownership can come into play in your system performance.
Apparently, there’s a common notion that all entities should be user owned. It’s very easy to select user ownership for every custom entity because it offers the most flexibility. The interesting thing is there’s real costs for the flexibility of user ownership. The entity ownership model is particularly deceptive because you’ll probably never see what happens behind the scenes or the performance implications until the system is live for a period of time. One of my primary concerns on any enterprise scale project (AKA thousands of users and large data volumes) are the hidden scalability issues that can arise after going live. Scalability is significantly more challenging and painful to address after going live because not only do you have to change a live model, but your pants are most likely on fire at the same time.
If you’ve ever chose organization ownership for an entity and had to change it later you probably experienced a degree of pain only known to people set on fire. I’ve had the pleasure of feeling that pain myself a long time ago having to manually make entity ownership changes for entities that had lots of dependencies (something I wouldn’t wish on my worst enemy). The fact is you can change the ownership model later very easily, but that’s another story. Feel free to ask me if you want to know how this can be is done.
At the end of the day if you look at the Dynamics platform it’s fundamentally a website, some background services and a database. The front and back end servers can be scaled up and out, but for the most part your database can only really be scaled up per the platform architecture. The database is your most significant performance bottleneck and should be protected for maximum scalability. One of the ways you can protect the database is to understand the pros and cons of what CRM is doing to implement the customizations you've made for a solution.
Security in Dynamics is implemented via table joins. Every row displayed to a user is security checked to ensure the user passes at least one of a series of privilege checks. In Dynamics CRM security is like a set of keys and users can get one or more of these keys from various roles. The user only needs one key to get access. The Dynamics product team chose not to implement a negative access privilege like what can be done in Active Directory. I believe this was a wise decision as it would significantly add to the complexity of the security model.
When you create an organization owned entity the platform only needs to perform a single check across assigned roles. Users either have a security role that gives them access or they don't. On the other hand, when you create a user owned entity the platform now must make multiple queries for the added granularity of role privileges (Organization, Business Unit/Child BU, Business Unit, User) and a record share check to determine access. Each of the different privilege levels that you specify in a role corresponds to table joins in the database. Oh, and did I forget to mention all the front and back end servers are caching and flushing this information in memory as users access the system, become inactive or the security model changes for users? So as the number of active users and data grows in the system the associated load increases on the system.
Record sharing is of interest in a system security model because of how much this can hit query performance of every user owned entity in the system. The principal object access table (where shares are recorded) is a single table notorious for destroying performance. There are two primary challenges with record sharing. The first is all shares reside in a single table for the entire system. Secondarily record sharing in practice can grow exponentially to the amount of data in the system. Between user and system shares this one table can grow astronomically compared to others. Take for example a single record shared to 20 users. Each of those shares for that one record creates 20 corresponding records in the principal object access table and this table is queried for every view for every user when the entity is configured as user owned. Add to the fact that most customers don't implement a data archive strategy and I've rarely seen users revoke record shares so the POA table tends to only grow larger over time. This is why I look for ways to minimize or eliminate the need for sharing or utilize another security mechanism such as Access Teams (AKA trading shares for teams). The takeaway here is that all user owned entities have a heavier load profile than organization owned entities because of the security orchestration implemented.
The fact is choosing an entity ownership model can have a real performance impact on the system. For small implementation you most likely never see any difference. The sad fact is most system don’t see any impact until months after go live which puts the project team under pressure to quickly fix the issues while being under fire from users and the business. Which entity ownership model you choose should be based on the scenario and future expectations. The good news is it can be changed, but obviously making a better decision during initial design requires less pain than having to do it on a live system. If you have a fundamental understanding that there is a difference to which ownership model you can make more educated architecture decisions moving forward.
.Net Developer focused on Dynamics 365, Power Platform and Azure
4 年Thanks for this article. Just wondering in ur experience what is a small and what is a large implementation?
Principal Program Manager | Microsoft Copilot Studio | Power CAT
7 年Very good article thank you Stephan Smith. My understanding was that it was OK to use User/Team ownership, because as long as users have “organization” scope privileges, the security cache is quite easy to figure for the system and it does not perform any further checks on POA etc.
D365 CE Consultant (Contract)
7 年Invaluable advice Stephan, something I hadn't really considered before, but will now for sure!
Microsoft MVP, Dynamics 365 Consultant & Developer, President of Exalents Solutions
7 年That easy way to do it is fine during initial dev but it's a nightmare for a live system because you need to delete the entity, which kills all your data. You'd need to either export it then start and reimport it, or move to a temp entity and back. For all that, it's be easier (though more shameful) to create a replacement entity in parallel and replicate the data from old entity to the new one.
Technical Architect | Managing Director | Fmr. Microsoft MVP
7 年Let me make sure to put the word "easily" in quotes and make it relative to doing it manually. Dynamics respects the ownership model of an entity regardless of what may be defined within a solution import. So the way you accomplish this is to create a temp solution, import your target entity along with all dependencies and export it. Then do what you need to do to delete the target entity. If this is a system that has been under development you have to remove a few dependencies. Lastly recreate the entity with the desired ownership model and reimport your temp solution. This will put everything back the way it was and the entity will effectively be replaced.