In numerous other posts, I talk about the effect of where you create D365FO security (AOT vs user interface) has on how it is stored. In other posts, I talk about creating an application to help move your security created in the user interface to your AOT. I thought it might be a good idea to bring these ideas to together and summarize this topic and show what security management best practice looks like in D365FO.
How is security data actually stored
If you create/modify a role, duty, or privilege in a Visual Studio project, the security data is stored in XML format within the project folder under the AosService -> PackagesLocalDirectory folder and are categorized by the security layer type.
- Roles -> axsecurityrole
- Duties -> axsecurityduty
- Privilege -> AxSecurityPrivilege
If you create/modify a role, duty, or privilege from the user interface, the security data is stored in the database as actual data within tables categorized by the security layer type.
- Roles -> SecurityRoleCustomizeDiskObject
- Duties -> SecurityDutyCustomizeDiskObject
- Privileges -> SecurityPrivilegeCustomizeDiskObject
The one thing to note here when customizing the security layer the entire XML object is stored in the Data column, not just the deltas. The AOT security data of the security layer is also stored in the OriginalDiskData column. Once a customization is done and published in the user interface, it doesn’t matter what change is made in the AOT, the user interface version will override it and take precedence.
In the AOT, security is treated as the same as code which allows you to export the security data with the deployable packages functionality.
From the user interface, there is functionality to export all of your customizations to an XML file. There is no way to choose which customizations you want to include in this download, you do have the ability to modify this XML after downloading if you feel comfortable doing so. This XML file can be taken to another environment and imported to take customizations from one environment to another. Since this process is not nearly as concise and maintainable as having security in the AOT I have created an application to help move security from the user interface to the AOT and I created a blog post detailing this entire process:
Treating security as code
What I mean by this is that your security should go through all of the same testing, deployment, and version control processes you have for code… because it is code. From a best practice perspective, I would recommend the approach of creating a security model and having a project within that model that contains all of your custom security of standard objects (non-custom objects) while all security around custom objects resides in the corresponding D365FO project that includes the custom object. The advantage of doing this is two fold:
- You now have limited where security changes exist within your solution and therefore know where to go to make changes
- You can now create a single security deployable package (or model) that you can then deploy into any new environment without any other code or customizations.
In the example above I created a model specifically for my security (and prefixed it with a company prefix based on naming guidelines), then created role, duty, and privilege folders underneath. All security layers will then exist under their corresponding folders and of course will be prefixed as well. Once created you are then able to take this and go to Dynamics 365 -> Deploy -> Create Deployment Package… and bundle ALL of your security into one package that you can take and deploy into an environment of the same platform version easily.
Also one other reason to create your security in a separate model is that you can then create a singular model file to take to another environment of a different platform update and application versions (this will be useful until we all go to the Microsoft evergreen solution around April 2019) using the following command from command prompt:
K:/AosService/PackagesLocalDirectory/Bin/ModelUtil.exe -export -metadatastorepath="K:/AosService/PackagesLocalDirectory" -modelname="AbcSecurity" -outputpath="C:Temp"
I hope these series of posts around security have been helpful on describing the differences between AOT and user interface security, best practices around configuring and managing security, and the tools and functionality that I and Microsoft have created to help with this process.
As always feel free to reach out with any questions anyone has surrounding any of this, would be more than happy to help.