The Extensible Data Security (XDS) framework is a feature in D365FO and AX 2012 that allows users to supplement role based security and allow access to tables to be restricted by a policy. This feature was an evolution of the record-level security that existed in previous versions of Dynamics AX.
In simple terms, XDS is placing a WHERE (or ON) statement on any SQL SELECT, UPDATE, DELETE, or INSERT statement done to a table based on parameters from another related table.
Data Security Policy Concepts
Before we jump into how the functionality works we need to have an overview of some of the concepts and terms. In the below terms I’m going to use the example of wanting to secure the SalesOrder table based on the customer group.
- Constrained table – is the table(s) given a security policy from which data is filtered or secured, based on the associated policy query. In the above example, the SalesOrder table would be the constrained table.
- Primary table – is used to secure the content of the related constrained table. In the above example, the CustTable would be the primary table. The primary table must have an explicit relationship to the constrained table.
- Policy query – the query used to secure the constrained table contents via the primary table contents
- Context – the piece of information that controls the circumstances that a given policy is applicable. Contexts have two categories:
- Role Context – enables a policy based on the role(s) the user is assigned
- Application Context – enables a policy based on information set by the application
Developing an Extensible Data Security Policy
Before you begin developing XDS policies there are a couple things understand/keep in mind:
- Understand the scenario requirement/use case of why you are using XDS
- Identify the constrained and primary tables and analyze the relationships between them
- Analyze the data access patterns, table size/record counts, and existing indexes of the constrained and primary tables
If we take the scenario that we want to limit the customers a particular user sees based on a specific customer group, how would we set that up?
- The first thing to do is to determine your Constraint and Primary tables, in this case the CustTable table is our constraint table and the CustGroup table is our primary table.
- Next we create the policy query around our CustGroup, we want this query to return the results that we want to restrict the constraint table with
- Create a new Query, set the data source of the query to the primary table and then perform any filtering or other joins that need to be done for this query to return the results you want to filter by
- In our case we are limiting the user to only be able to see customers that have a CustGroup of ’10’ and Name of ‘Major Customers’
- Now we can create our Security Policy, we set the following parameters
- We then add a constrained table to the policy, in our case CustTable and set the following parameters
- Now if we build the solution and do a database sync of our project our XDS policy becomes live, to show what this does I did a before and after using a user assigned the FpTestRole to show the affect of the XDS policy
User access without XDS policy applied
User access after applying XDS policy
Now one question I had is, how do you apply an XDS policy against a group of roles? Well this is where the Context Type and Context String parameter on the policy comes into play. The Context Type parameter determines how the Context String parameter is handled. The Context Type has 3 different values:
- ContextString – should be set if you want to change the value of the Context String parameter via X++ code (via the XDS::SetContext method)
- RoleName – should be set if you want this policy to be assigned to a single role, this has the same effect as setting the Role Name field
- RoleProperty – allows for applying the policy to multiple roles via the Context String value, if a role has the same Context String then that role will have the XDS policy applied
If we set the Context Type to RoleProperty, then any role with a context string of the value we input in the Context String parameter will be assigned the XDS policy. So if we set the Context String value as CustGroup_XDSPolicy,
and then we set the same Context String value on a role, any user assigned that role will have the XDS policy applied to them.
Ensuring Efficient XDS Policies
Using XDS within D365FO will have an impact on the performance of queries on a table, the goal is to minimize this impact. There a couple things to keep in mind:
- Follow standard best practices of developing SQL queries (using indexes on join conditions, correct primary keys, etc)
- Simplify queries as much as possible, don’t have unnecessary joins
How to Debug/Troubleshoot Issues
If while using XDS you come across an instance where a user has more or less rows from a constrained table than you think they should you will have to try and debug the XDS policy. There are two ways of doing that:
- Execute a snippet of X++ code to see the SQL statement generated for a particular XDS policy (an example of this can be found in the white paper resource link below)
- Run a SELECT statement against the ModelSecPolRuntimeEx table to see the human readable query stored for this XDS policy
- For example, if we look for the CustomerGroupPolicy from the example above in the table the ModeledQueryDebugInfo column shows the SQL query
Another issue that you may see is a performance impact once XDS policies have been applied. In this case you will need to review the simplicity of your queries, the indexes on your tables, the proper joins are being used, and take into account the number of rows within each table you are using.
I hope this gave an overview on how to use the Extensible Data Security framework to extend your role based security to allow for fine grained control of user access. As always, feel free to reach out with any questions.
Developing Extensible Data Security Policies White Paper
Extensible Data Security examples – Secure by warehouse (Great overview and examples from Andre Arnaud De Calavon)
Would it be possible to exclude a from from it’s underlying security policy? To be specific, we need to apply different warehouse security policies on Transfer Order form as the “from warehouse” and “to warehouse” have different business rules and should provide different list of warehouses to the user to choose from.
You should be able to do this, the idea would be you have to designate a constrained table and policy table. In your case the ‘business rules’ for a user would be your policy (not sure what these entail) but then your constrained table would be your user warehouses.
So users would be assigned access to all warehouses and then XDS would limit which warehouses they could actually see/interact with.
Feel free to reach out if you have any further questions!
Thanks a bunch Alex.
how can I setup the framework to deploy my XDS
The blog post shows how to set this up in the AOT, the XDS framework is enabled by default in all AX/D365FO environments. The end user just has to set up if they want to implement any XDS policies and then set them up in the AOT.
Thanks for a very nice description of the XDS framework!
I have a scenario where I need to restrict the ability to edit certain records. My scenario is very similar to your example, only I don’t want to filter the restricted records out. I only what to restrict if a user can edit the records.
In your scenario that would correspond to not allowing the users to edit the sales orders with CustGroup 10, but they can still view those orders.
I see a property “Operation” on the Policy in your example, which is set to Select. Is this were you would instead set Operation = Update?
Yes, if you wanted to change the action that XDS should be applied on you can do it from the Operation parameter. It supports Insert, Update, Create, Delete, InsertUpdateDelete, and AllOperations and these actions follow the same hierarchy as security does. For example, if you set it as Select then XDS would not be applied to Update, Create, or Delete actions for those records. So you need to be sure you are applying XDS in conjunction with security to only allow for the changes to objects you would like.
Thank you for your response. I think then, if I want users to be able to view, but not modify, then the Operation to choose would be InsertUpdateDelete.
One more question:
Say you have the policy restricting viewing of sales orders for customers with customer group 10. This policy is applied for Role1.
Another role, Role2, also has access to view Sales orders. The policy is not applied for this role, so a user with only Role2 is able to view all sales orders.
If a user has both roles, which permissons come into force? Does the restriction from the policy applied for Role1 “win” over the permissions given by Role2? In other words, can this user see sales orders for customers with customer group 10?
You are correct, the the Operation to choose to affect Inserts, Updates, and Deletes should be the InsertUpdateDelete good catch!
If you have multiple roles assigned the user with one having XDS and one without, the most restrictive access will be granted.
Is it possible to use XDS to restrict the value returning for a particular financial dimension, except if users are using the dimension lookup in the expense management module, where we want all users to be able to see all dimension values?
If XDS is applied to a role, then the restriction will execute every time the underlying resource is accessed. And since it is done in code, there really isn’t a way to easily turn if on/off. If the users should be able to see all dimension values in one area of D365FO then they would be able to see those dimension values in another area. I will say that you can put different restrictions on the XDS, so maybe the user can see all of the dimensions but is restricted to Create/Update/Delete only certain ones.
EDIT: Trying to fix indentions, because spaces have been trunated.
We have a XDS policy that constrains table A, and there is table B added to the policy, too, as a constrained table of table A. So the policy looks something like this:
|—— constrainted table A
|————-|—— constrained table B (using relation R1)
Basically this works fine. But when we have a form where we use table A and join table B to it using relation R1 (same relation that has been unsed in XDS), the XDS framework will add the securing query to table A (which is good), but in addition will also add table A to table B (as an additional join, due to the XDS policy) and then also add the XDS query to that additionally joined query. So we end up with a query like this:
|- Table A
|——|—— Table B (inner join, relation R1)
|- Table A
|—–|— XDS-Query added to first table A
|—–|—Table B (inner join, relation R1)
|————-|— Table A (added to table B
|———————-|— XDS-Query added to second table A
This is obviously not optimal. I think the optimal query would be this:
|- Table A
|—–|— XDS-Query added to first table A
|—–|—Table B (inner join, relation R1)
Is there a way to tell XDS that it should only apply itself to table A in a form, and not being applied to table B in order to improve the performance?
How the SQL is generated for all AOT objects is abstracted away from the end user, I don’t know of any way to modify how it is created. The only option I could think of trying would be to create a view of Table A and the join to Table B then create another XDS policy using this view as the table parameter. I have not tested to see if this will generate different SQL but I think treating the query as a singular object (as a SQL view) might help.
thank you for this great post.
Great post !
How would it work if instead of the user only viewing CustGroup 10 they want to view all except CustGroup 10?
Yes you absolutely can, we just have to change the query value. So if we have a list of customers like this:
And we want to show all customers that do not have a CustGroup of 10, we change the query to be:
And now if we go back to Customers we can see all customers except those with a CustGroup of 10:
You actually can use any formats that you use in QueryBuildDataSource logic in that Value parameter.
More information can be found here: https://community.dynamics.com/ax/b/axdaily/posts/and-33-operators-in-query-ranges
Fantastic, thank you so much Alex !
What are the oData (restAPI) service end points to create the security policies?
There isn’t an OData endpoint to hit to create/modify XDS policies, XDS policies must be created in code via Visual Studio.
My requirement is to show the data on budget analysis form ( Navigation: Budgeting >>inquiry and reports>> budget control>> budget analysis) according to current user.
I think your requirement might be easier to achieve through extending X++ code on the form load compared to XDS.
While getting the SecurityRoles using the odata endpoint, this is the sample example of a SecurityRole returned by the API:
“Description”: “Maintains vendor contact persons and vendor user requests”,
“SecurityRoleName”: “Vendor admin (external)”,
In this, what is the meaning of “ContextString” and from where would I get the List of these ContextString using the odata. Is the meaning of “ContextString” in the data received same as the context string for XDS?
The ContextString value on a role is used by XDS to apply an XDS policy across multiple roles easily. If your XDS policy has the ‘Context String’ value set on it then any role with that same context string value will have the XDS policy applied.
I need to enable and disable the field based on the user role. i.e
Only for the Project Manager role field on a Form will we enable and for the rest, it will be disabled in D365 FO
Can you please guide me on that?
Awaiting your response.
In this case you have a couple different options, but in each case I would recommend utilizing the Deny access type to ensure access is not accidentally given to users you do not want to. I would actually suggest performing this request at the user level instead of the role level as I believe it will be a simpler setup. As otherwise you would have to go to every other role (other than Project Manager) and Deny access to the field. Instead we could:
– Create a role that Deny’s access to whatever field you want to block on your created role
– Then assign this created role to each user that should not have access (you could automate this slightly by using OData and the SecurityUserRole data entity)
Your other option if you wanted to do this at the role level would be to be to create a privilege that Denied access to this field and then assign it to each role in your System except Project Manager
Is it possible to make form level controls enable and disable using XDS.
I would not recommend XDS in this case as XDS was not designed to modify security in this way, XDS was designed to limit which records a user could see not what objects on a form a user could interact with.
Hi Alex, I had a requirement. Based on a parameter value in one table. I have to make some fields enable and disable for some users. Is it possible to do through xds.
I would not recommend XDS in this case as this is really not what XDS was designed for. In your case I think custom development would be required to enabled/disable a field based on a value from another table.
Hi Alex, does commands like doInsert, doUpdate, bypass the XDS policy and perform the insert and update operations?
I have not tested if the doInsert/doUpdate methods would bypass XDS but there are plenty of other ways to bypass/disable XDS:
Hi Alex, Thanks for your prompt reply :), In one of our the scenario the XDS is being bypassed by a doInsert method which is a standard Private method in MS class. Don’t know why it is doing like that.. for normal insert or update scenario XDS is working fine. Anyways, Thanks again for the reply, Alex. 🙂
It looks like the doInsert method is used specifically when you want to bypass the normal Insert method. An excerpt from the documentation: https://docs.microsoft.com/en-us/dynamicsax-2012/developer/doinsert-table-method
My guess would be that by performing the doInsert method instead of the Insert method that it bypasses all checks that would normally be performed.
Hi Alex, I hope you are fine and doing well.
I have implemented warehouse level security using XDS. Its working fine for purchase, sales, movement etc. but I’m facing issue while perform Transfer Orders (Inventory Management > Transfer Orders). Transfer Orders form use InventLocation lookup on From Warehouse and To warehouse, as the warehouses are restricted so it won’t show other warehouses in To Warehouse because we have to move inventory to different warehouses. How can I exclude Transfer Orders form from this security ? or is there any way to void InventLocation restriction on this form?
When you apply XDS, you are basically putting a WHERE statement clause on SQL events that occur to that datasource. It doesn’t matter which form the request comes from, all requests to that datasource will be constrained by the XDS policy. You may be able to override XDS on the Transfer Orders form by utilizing one of these methods:
Thank you so much Alex.
unchecked(uncheck::XDS) worked but only for lookup. when I select a warehouse from lookup it shows error
“The value ‘Warehouse2’ in field ‘To warehouse’ is not found in the related table ‘Warehouses’.”
because it again check warehouse at the time of selection.
How can I deal with it ?
Thanks & Regards,
I am not sure what other logic is happening on that form when you select a warehouse, if you are able to see the warehouses then you are overriding XDS for that particular SQL query but there may be other queries from this datasource that may still be restricted by XDS. You would have to ensure that all queries needed to perform the business process are unrestricted.
Hi Alex, I have a problem when compiling, when assigning the CONSTRAINET TABLE property in Yes of the policy, it gives me error: System table not allowed when the constrained property is Yes.
It is worth mentioning that my table has no relation
I would guess that there is some setup issue with your XDS policy, you need to ensure that the Primary Table parameter and the Constrained Tables on your policy are set like the example below.
Also there should be some relationship between your primary and constrained tables otherwise there would be no way to apply XDS between them.
Thanks for rounding up. This constrained table option can be applied to a system table, that is, an XDS can be applied to a system table.
My XSD works perfectly, the XDS was applied to the UserIinfo system table but not directly, in code I made a join to a new table created (which has the XDS assigned), but in the grid the search no longer works nor the filters of the headers of the grid, any ideas?
I’m going to guess that you mean that the grid filter isn’t filtering any data as you didn’t specify what the actual issue is. You would have to look at the grid filtering logic on whatever form you are currently on and possibly override it to correctly implement your XDS logic.
Here’s some others that have had similar issues:
To be more specific, QuickFilter no longer works for the grid. I already saw the post but for me it is the opposite, it does not bring the data when wanting to filter. 🙁
I think the steps to get this working would be the same, you would have to go into the X++ code and look to see where the filter is being applied and do an analysis on why the data is being filtered out.
Thanks for this post. A good starting point for XDS !
I have a requirement of which I’m not sure what the best way is to solve this. I have a purchaser that should be able to create purch prices/discounts (Trade agreements), but not sales. And I have a sales person where it should work just the other way around.
Thought of 3 options:
1. Code (my least favorite; do not use code if other workable options are available)
2. Roles/Duties/Privileges. Played around with this but can’t seem to get this working.
Using XDS I can prevent the user from creating a purch/sales trade agreement (form priceDiscAdmTable) by querying out the correct journal names. But when I go to lines (from PriceDiscAdm) I will still be able to create all prices/discounts. For sales and purch. The bottleneck here is that I need to filter on the Enum PriceType (field priceDiscAdmTrans.relation). And I can not find a way yo do this using XDS.
Can you share your thoughts on this ?
I think you could potentially do this via security, while you could probably do this via XDS it is not the normal use case for XDS so it would be somewhat complex to set up (as you have found).
I don’t have a lot of background on what forms/datasources control the ability to create purch prices/discounts and where you are making sales. But if these two processes interact with separate datasources and/or menu items/forms this sounds like a great use case for the Deny permission. Where you would grant access to one process but deny the other.
How To Utilize the Deny Permission in Dynamics 365 for Finance & Operations
Thanks for taking the time !
With roles/duties/privileges I have another issue. I can deny access on menu-items etc., but once I’m on the form where I set the price agreements I need to restrict access to creation of records based on an Enum. I uploaded an image: https://ibb.co/4T3WJr4
As you can see I can create sales and purchase prices here based on the Enum PriceType (column relation). What I want is if I select Purchase Price, that I’m not allowed to save the record (generate a warning or whatever). But as stated, this is an Enum and not a data relation like “User is not allowed to create salesorder if customergroup = ‘XXX'”.
I find it very strange that I can’t find a any easy solution for this on google. Sounds to me as requirement that’s not that strange. I’m getting the feeling that I need to use code here. Not very complicated, but I want to avoid code if possible…
Any more thoughts you might have are appreciated !
In this case, you would have to extend the form functionality by using X++. There is no out of the box functionality that will perform the way you are wanting.
It’s not XDS because like you said this is all being done on the same table, and you are not trying to limit a user to only being able to see/interact with certain objects that meet a criteria you are trying to say that a user should not be able to save an object with a certain value.
And its not security based because you only want to restrict access when a certain value is set.
So the only option left to perform this functionality is by extending the code on that grid column’s drop down event.
Not the answer I was hoping for ;o) But I agree with you. Thanks a lot !!
We are implementing Extended Data Security(XDS) on warehouse-user level. In transfer order form we want to have from warehouse to be filtered from user-warehouse mapping table and in to warehouse no filter is required. But as XDS is enabled on InventLocation table, it is showing only filtered locations in from as well as to warehouse.
We want to implement XDS on From warehouse not for To warehouse.
Can you share your thoughts on this ?
I believe this scenario would require custom X++ logic be applied as I don’t see a way to do this another way. You would have to do something like Andre’s answer on this forum post and apply that on the query that executes for the To Warehouse.
Another option would be to populate a temporary table with the values from the InventLocation table and use that as the datasource for the To Warehouse field.
Thank you for your update.
Is there any way we can achieve that without having to write the code everywhere? Also how can we filter the transfer orders on form with that?
No, custom code would be required. The custom code would also be where you can apply any filtering you would like.
Thanks for your great article, I have a requirement here. I have 3 branches in my company and want to show stock, customers and item separately to all these 3 braches. That’s mean all these 3 branches should see thier stock, items and customers.
I think you could do this without XDS and just use normal legal entity separation. Each ‘branch’ in your case would be a separate legal entity and then all of those objects (stock, customers, and items) would separated by legal entity and would only be visible within that legal entity.
I have two policies with their query and each one is assigned to a role by ContextString, but the queries are from the same table, can those two roles be assigned to a user or would it cause conflicts? For example,
Policy 1 with CustGroup = 10 and Policy 2 with CustGroup = 20
Role1 = Policy 1
Role2 = Policy 2
User X = Role1, Role2 (Has both roles)
User Y = Role2 (It only has one role)
If a user is assigned multiple roles with XDS policies applied then all conditions across all roles must be met for the user to have access to this data.
So for example, I set up your scenario described and individually was able to only see customers with a CustGroup = 10 and CustGroup = 20 when each role was assigned by itself. However if I assigned both roles to the same user no data was returned because the results SQL clause was basically ‘WHERE CUSTGROUP = 10 and CUSTGROUP = 20’ which will never return any results.
So how could I resolve that conflict, would it be creating an XSD with combining those two values to be ‘WHERE CUSTGROUP in (10,20)’?
I read something about dynamic policies but did not find something about it.
Correct, you could create one policy that would accept both values. I believe you would set the Value on the policy to 10,20.
I have a similar scenario as one of the users above.
I have restricted Sites for users. (A user will be able to only see the sites assigned to him)
Now in Transfer orders, I can fill my From warehouse, but due to the policy I cannot see the list of Other warehouses. Even if I manually fill it, the system would throw error that it is not found.
Can you please explain in some detail how I can overcome this situation?
I’m going to copy my response from another answer I gave about the same topic:
Thanks for your article. I have a requirement for the transaction table. There’s a custom leave table, where user creates leave transactions. Then these records will be submitted to the workflow. We need users to see records only created by them or if they are the approvers of those records. Your suggestions will be much appreciated.
You can use the currentUserId() method can be used in the query used for an XDS policy. Here is an example:
I have 3 related tables: InventJournalTable, InventJournalTrans, INVENTDIM; I wish to restrict the data for the InventJournalTable.INVENTSITEID and INVENTDIM.INVENTSITEID field by a value. How could I apply it in the XDS, any ideas that could help me? It is necessary to add the relations in the QUERY?
You have to try and find a relation between your tables using something like an ERD diagram (like the one I host on my website), doing a quick look there is no direct tie between InventJournalTable and InventDim but there is one between InventJournalTrans and InventDim
The relations I already have, but the problem is that I want to restrict the INSERT for InventJournalTable and INVENTDIM, I put the relations in the QUERY of the 3 tables, but the XDS only works with InventJournalTable.
That’s because XDS can only ‘restrict/constrain’ one table at a time, remember in an XDS policy you have 2 tables primary and constrained. The primary table sets what values are used to ‘constrain’ the constrained table. So in your case I’m assuming your InventJournalTable is your constrained table and your InventDim is your primary table. If you want to constrain the InventDim, you would have to set up a policy where that table is the constrained table while a separate table is the primary table.
So from what I understand, in my case I would have to create two directives one for InventJournalTable and one for INVENTDIM?
Correct, for your scenario you would have to create two security policies: one to constrain the InventJournalTable and one to constrain the InventDim table.
I have requirement to provide user access transaction specific to the location for that I have applied XDS on Location Dimension Value and created 8 -10 role for different location. But the problem arise when I gave permission a user for two location, then both Roles conflict and user won’t be able to see any transaction. How can we resolve it?
You would have to create a role for each combination of locations you want to assign to the user. You are correct that just assigning multiple roles that already have XDS applied will not work. My suggestion would be to have a base role that gives access to the locations and then use that as a sub role for each of your location combinations you need to set up. You would then apply your XDS to the parent role.
how i get XDS for certain table i mean if i made a policy and added constrained table
how another developer from the table reach to this policy
An XDS security policy is made up of a few components, the primary and constrained tables and the query that joins them together. If another developer would like to reference this security policy they would have to reference the model that the policy was developed under.
If the developer wants to apply this XDS security policy to a user, they would have to associate the policy to a role that’s assigned to a user.
Great post, not many experts on the subject!
I understand XDS only filters records, but here’s an example I don’t understand:
I observed the vendor collaboration roles (VendVendorContact and VendVendorContactExternalAdmin) have Policy context string PolicyForVendorRoles
When using vendor collaboration as external user, the field VendBankAccount.AccountNum, IBAN are disabled, and probably more.
When I go to the Security configuration, and remove the policy context string from both roles, then go back into vendor collaboration, the fields are editable.
I checked the security policy, and of course, there is nothing that relates to these fields in there, since it’s only table level based.
I made a copy of the security policy and removed the VendBankAccount table, applied to my role in security configuration, same result
Can you point me in the right direction as to why these fields edit status would change when policy is added/removed from roles?
I think you may have found an interesting security scenario. XDS ‘should’ not have an impact on what fields are enabled on a particular form as it is simply adding a WHERE clause to any SQL that is executed. However, looking at your scenario I noticed the fields you listed all have one thing in common, they have the Table Permission Framework (AosAuthorization parameter) enabled for them. I need to do some further testing but there may be something going on when a table has an XDS policy and TFP enabled together. Let me do some further testing and get back to you.
Do you happen to know if it’s possible to filter on an extension-field by using a constrained table in the security policy?
We do have a business scenario we want to support based on an extension field. We added a new field on an standard table and also a new relation using extensions, but after build and sync the table doesn’t show up in the properties of the constrained table.
If we create a new table (duplicate the standard table) and add the same field and relation, the new table does show up in the properties.
Any idea’s if it’s possible to use XDS in this case?
This is an interesting scenario! I would think this would be possible by referencing the extension table in the security policy but I have not tried it myself.
Let me check look into this further and get back to you.
You can use a constrained expression instead of a constrained table.
I need to apply security on Main accounts in GL module, i.e., the user will not be able to drill down the transactions of a few Main accounts on the Trial balance if it has role ‘A’. If role ‘B’ is assigned, the user will be allowed to drill down the transactions.
To achieve this, I have secured the data of GeneralJournalAccountEntry based on the security role.
The same role will be provided to Budgeting module users. This security role will behave differently on the Budgeting module, i.e., it will be securing the data based on Organizational units. Now the problem is on a few reports in budgeting. The GeneralJournalAccountEntry is being used and it is also hiding the data based on Security role ‘A’ which I don’t want.
Role A should have access to both GL and the budgeting modules.
Any idea of its possibility?
I think you are trying to have the security roles do too many things, you may have to split up the roles into their respective areas.
For example, you may have to have one role to restrict access to Main Accounts and a separate role to restrict the Budgeting module. This will allow you to assign any combination of these roles to achieve the scenarios you are looking for.
I have developed a solution that works in the same manner like AX2012 have do. The only diference is, my solution works only with Cost Center and Financial Dimensions. That is near the entire System in D365FO, it is fast and easy going.