Now that we have all made it through the User Group Summit in Nashville this year I was able to get back to a little bit of writing. This year during Summit I presented a couple different deep dive sessions surrounding security in AX 2012 and Dynamics 365 Enterprise. I have written about numerous security changes in the past, but there are some more advanced security changes and features in D365E.
Entry Point Security
The way that entry point security is determined has changed in D365E, in the below scenario we are looking at a form that is getting access from a number of menu item entry points with both View and Delete access. We are going to be looking at what would happen if you accessed this form through Menu Item 1.
In AX 2012, the security framework looked at all of the access you had to this form and took the highest access to determine table access. This would mean that even though you accessed the form through a View level menu item you would still be assigned Delete level table access. This is a big deal in AX 2012 because command buttons were tied to table level access. So a user could access a form through a View level menu item and the Delete button would be enabled for the user to click. Obviously this ‘feature’ has caused a lot of grey hair for a lot of AX security administrators trying to figure this out.
Now in D365E we can see that if we take the same scenario where we access the form through a View menu item the security context of the accessing menu item is preserved and honored for table level access. So if you access a form through a menu item with View access you will get View access to the underlying table, if you access it with Delete access you will get Delete access to the underlying table.
In AX 2012, role overrides allowed you to assigned table level access directly at the role level (without having to go through a duty or privilege) and this permission would then override any permission to that table object given at a lower level within that role. With D365E, you can still assign table level permissions at the role level but it acts as any other permission and does not override lower level permissions.
Table Permission Framework
The table permission framework feature is used to provide an extra layer of security to your high business impact data (credit card numbers, social security numbers, etc). It is an extra check that the security framework does that requires that the user have been granted explicit rights to the table field for them to be able to interact with it. So even if a user has been given Delete permissions through a role, duty, or privilege to this table they still need an additional permission to View or Update this field for them to actually have rights to it.
The property that allows for this is called AosAuthorization in the AOT, if it is turned on (like it is below for the TaxLicenseNum field on the CustTable) then the table permission framework is active.
In AX 2012, this feature was somewhat cumbersome to use as you had to turn it on for the table and then go to each individual field and turn it on or off respectively. In D365E, you can now go directly to the field you would like to turn this feature on for, and enable it without having to worry about the table aspect.
One of the largest changes from a development standpoint (and I have written about this in my previous X++ changes post) is the separation of the design time and runtime environments. What I mean by this is that in AX 2012, the place where you developed your code (design time) and the place where your code is actually executed (runtime) is on the same machine or environment. This allowed for tools like the security development tool to exist because it could reach in and read from both your code side and the application side and be able to act as a middle-ware between them. With the switch to D365E, your design time is on a virtual machine with Visual Studio but your runtime is a web application running in Azure. So you no longer have that connection. There are many large ramifications of this, but for security in particular it means that changes made in the user interface are not propagated back to your AOT, instead they create a security ‘delta’. So when the security framework is determining access it takes the security you have in your AOT and applies the security delta from the user interface and creates a single security runtime and that is what gets used. One thing to keep in mind is that changes that are in the security delta take precedence over security in the AOT, that is to say that changes made in the user interface override security in AOT.
So the question that comes out of this, is how do I move/migrate my security from one environment to another? And second, how do I manage version control of security changes?
So there are really two options currently and unfortunately neither of them are very user friendly:
1. Make all of your security changes in the AOT and none through the user interface, this will force all of your changes to become ‘development artifacts’ and be part of the code
- Because all of your security is in code, it is very easy to create a deployable package or model that you can move easily between environments
- But the setup and maintenance is more difficult as every security change is a code change
- You get to use Visual Studio TFS version control system
2. Make all of your security changes in the user interface and export your customizations through the Data tab in Security Configuration and then import your customizations in the new environment using the same feature
- Using this feature, ALL customizations in the environment are exported to an XML file that can be taken and applied anywhere else (can’t export just specific changes)
- Changes can be made in the user interface which is easier for setup and maintenance (but remember that these changes do not get pushed back to code in the AOT)
- No version control system for security changes, will have to come up with your own methodology for that (could check in entire XML file to TFS or something similar)
My best piece of advice here would be to pick one method and stick with it, because the only place where you can get into trouble is if you do both of the above methods and have no idea who is making changes where and what changes are being made.