Security how-to: Only finance users are allowed to see cost prices in Dynamics 365 Finance and Operations
This post is a new blog in the series about “Security how-to“. In this particular post, I will explain how to secure a common scenario where cost amount fields should be hidden for the majority of users. This post will explain how to secure fields, form controls, and an easy way to apply this scenario to the users.
Scenario
For many different reasons, organizations do have the requirement to hide cost amounts. One of the most heard reasons is the fact that workers would make wrong assumptions about margins. The fact is that there are more costs related to running a company than only sales price minus cost price. If salespersons see e.g. a contribution margin of 25% they think they can give away more discount. They forget that salaries need to be paid, the office and warehouse rent should be covered, marketing efforts are also expenses and taxes are inevitable. If these organizations do approach it correctly, they should also hide any margin amounts or ratios.
Another reason would be securing company sensitive data. Some organizations would really like to prevent from leaking information about cost of producing items. For sure you can think of other reasons to secure individual fields.
The challenge
To solve this issue, you need to use table and field permissions. This is not the most difficult part of the steps you need to perform. In both Microsoft Dynamics 365 and AX 2012, you can achieve it, but there are differences.
More challenging will be hiding fields that are not directly bound to a table field. There are many occasions in the application where display methods are used to present data or perform a quick calculation with input from several fields. To be able to secure these, you need to change form control properties.
Continuing this post, I will elaborate on the challenge to hide the cost fields for sales orders and inventory transactions. These are not the sole entities with cost amounts, but a good representation of how to solve it in Microsoft Dynamics.
The number ‘1’ on the screenshots do refer to form controls that are bound to physical table fields. The number ‘2’ on the screenshots are display methods that do show a value based on business logic. How to handle both scenarios will be explained in two separate paragraphs.
Table and field security
When you want to manage the field access, you can achieve it as part of development or configuration. As mentioned above, there are differences between Dynamics 365 F&O and AX2012. I will list them in the next table:
Subject | AX 2012 | Dynamics 365 F&O |
Configuration | Configuration changes do lead to changes in security objects in the AOT | No connection with the development environment. Changes are published on runtime only |
Configuration | Use the Override permissions button on the Security roles form | Use the Permissions nodes on either the Security role or privilege on the Security configuration form |
Configuration | You have to set table and field permissions. | Table permissions can be set to Unset. Field permissions are managed for read and update permissions separately. To hide the field, you need a new Deny permission. |
Development | ‘No access’ can be overridden by other security permissions in case of a combination of roles. | ‘No access’ on table and field permissions will be translated as ‘Deny’ which cannot be overridden by other security permissions for the same user. |
Now we know some differences, we also can conclude that the solution direction for AX2012 and Dynamics 365 will be different. In AX2012, you need to verify all roles and privileges assigned to users who should not see the cost amount fields to set ‘No access’. In Dynamics 365, you can of course do the same, but only a single role would also achieve it as the Deny access level has higher priority above all other grants. I will continue explaining the Dynamics 365 example in this blog. You may have your own preference to start using the client configuration or a security development in Visual Studio. I will share the screenshots for both options. The inventory transactions table is configured in my demo where Deny permissions were set for all amount fields from this table.
The Return cost price on the sales order line is managed via a new privilege and the (table) permissions node. On the field itself the grant is set to No access.
You can find more cost related fields to be added, like cost prices from project or production transactions. Of course, you will choose one of above options for all fields to be secured. In this small demo, I have added the privilege to a security role called (Hide) Cost amounts. When the security role is assigned to a person all secured fields will be hidden. But, as mentioned above, we have a next step to secure display methods. This will be explained in the next paragraph.
Secure form controls
Besides table and field security, you can also set additional security on form controls. The controls do have a property NeededPermission which should have a different value than None. In Dynamics AX 2012, I usually set the NeededPermission value to Manual. The effect was that no business user could see the control, unless it was overridden on a specific privilege or role.
As explained above, in Dynamics 365 we can now rely on the deny permissions. This gives the option for another approach. The NeededPermission can now be set to Read which means that the control will be visible for anyone with at least read permissions. Using a privilege with No access for the form control, it can be managed to remove access to this form.
If you need to be able to manage the access level of form controls, you have to change the NeededPermission property. For existing forms, you can use a form extension to achieve this. You can check the next screenshot how to set the property in Visual Studio.
When the NeededPermission does not have the value None, you can set other permissions on the privilege. First you have to add the form on the Form Control Permissions node of the privilege. Then you are able to add the control name and set the permission to No access.
Note that the form control permission will not be visible via the Security configuration form, but it is certainly effective. On the Sales totals form, we want to hide three fields. As these three fields are part of a separate field group, you can set the NeededPermission property and security on the field group instead of all fields individually.
Next, when the form extensions and security objects are complete, you can test the access for a user without and with the role assigned to a user. You will notice that the fields and form controls with the cost prices are hidden when the role is assigned to a user.
Easy role assignment
When you have read my other blogs, this topic might be familiar to you. I have written several blogs about automatic role assignment in the past. For more background information on the method below, you can read about the automatic role assignment using the next link: How to setup easy automatic role assignment.
Suppose, we would like to have only the users part of the Accountant role being able to view the cost prices, in that scenario we have to assign all users to the (Hide) Cost amounts security role, except the users part of the role(s) which are allowed to view them.
To be able to select all users in the rule, except those based on a condition, you can join tables and use the Not-Exists Join option in table joins of queries. Credits to Kurt Hatlevik who made this feature possible: D365 – To exist or not, that is the question!(part 2) | Kurt Hatlevik
When creating the automatic role assignment rule, the query can look like displayed on the next screenshot.
It would be an option to also exclude the users with the System administrator role as these will anyway bypass any security. If you would like to add more roles, you can separate them with a comma in the Criteria field.
You are not limited to exclude users only as part of certain roles. You can exclude users manually by providing a criteria for the ID field of the User information table. With other table joins, you can also have criteria setup for users part of a Team or User group.
Now when you manually run the Automatic role assignment option or wait for the batch job, you will see users assigned to the (Hide) cost amounts role with the Assignment type Automatic.
When one of the users in the (Hide) Cost amounts role will be assigned to the Accountant role, the next time when the Automatic role assignment job runs, it will remove the role assignment automatically. Also when new users will be added to the system, this role will be added when the user is not an Accountant.
I do hope you liked this post and will add value for you in your daily work as a professional. If you have related questions or feedback, don’t hesitate to use the Comment feature below.
That’s all for now. Till next time!
Hi,
I want discuss this topic
Hi Sheetal,
Thanks for reading my blog. If you have any questions or comments as a discussion, feel free to contribute to this Comments section.
Hi,
Can u please share me pics, as I cannot enlarge UCS shown in your blog.
Thanks
Hi Manish,
It should be possible to click the images to view the full size. I have put the links to the pictures in this reply if that would be better for you.
SecurityHowTo-Cost01.png
SecurityHowTo-Cost02.png
SecurityHowTo-Cost03.png
SecurityHowTo-Cost04.png
SecurityHowTo-Cost05.png
SecurityHowTo-Cost06.png
SecurityHowTo-Cost07.png
SecurityHowTo-Cost08.png
SecurityHowTo-Cost09.png
SecurityHowTo-Cost10.png
Great Post. This help me lot. Thank you very much Andre 🙂
Hi Andre,
Im trying to hide report fields for particular users.
In SSRS Report Tmp Table fields can not be hidden because of Table Type is TempDB. Its working for Table Type is InMemory.
Kindly advice is there solution for this?
Hi Kannadasan,
A possible solution depends on the report data provider and who is running the report. E.g. if it is executed via batch by an admin account, it would not be possible.
Hi Andre,
Thanks for response.
I have tested TempDB reports from User accounts but no luck. Fields are still showing.
For better performance In RDP Class I have extended SrsReportDataProviderPreProcessTempDB and used RecordInsertList in processReport method to write data into database in one call.
Please advice.
Hi Kannadasan,
Can you create a question on the Dynamics Community? Then please also share the coding form your extension. When you created the question, please forward the link.
Thanks Andre. I will do.
Hi Andre,
I was trying to implement this in our FO.
I’m struggling at screenshot: https://dynamicspedia.com/wp-content/uploads/2021/02/SecurityHowTo-Cost09.png
I receive the error message ”
Query filter cannot be specified on a query that are split into multiple queries dues to 1:n fetch mode.” while trying to add the second join (for Security role).
Can you try to setup the query again with the current version of FO?
Has something changed?
Thank you for your help.
Hi Daniel,
I have recreated the query in the PEAP 10.0.25 version. I’m not able to reproduce your issue. It is still working as before. Can you add a screenshot? If this is not possible via the comments, you can go to my Photo gallery and send an image via the “Send your photo” form.
Hi Andre,
sorry for the delay… I haven’t received any mail, maybe it was blocked by my company.
I have upgraded to 10.0.24 in the meantime and you are right it is still working like a charm.
Thank you for this blog post and your help!
Very appreciated.
Regards
Daniel
Hi, wondering if you can help with this issue here with creating a custom role? This link is a description of the issue and screenshot.
https://community.dynamics.com/365/financeandoperations/f/dynamics-365-for-finance-and-operations-forum/462133/trouble-giving-access-to-undo-settlement
Hi Zoe,
There was already an answer provided by someone else.
Hello André,
I have followed all the steps in your blog and i deny cost as you mention however still in transaction screen cost amount still show, if you can guide me would be great
Hi Ahmad,
Thanks for reading the blog and for your question. Can you verify the user will not have the system administrator role assigned? The system administrator role is bypassing all security; also XDS. If this is not the case, then please provide some more information about what exactly you have done in your environment.
Thank you for your reply,
i am doing this on sandbox and assigned hide cost role only to user but still cost amount showing despite that i deny all cost fields under inventtrans and i assigned read only to inventtrans
Hi Ahmed,
Can you share all the details? What exact fields on what form do you want to hide? Did you use the deny option or set read-only? Did you also perform a database sync after the build?
Hi André
I want to hide cost amount field shows in the screenshot you added number 2
which is found in the inventory transaction screen from name inventTrans , control name cost value
Hello André,
After we follow the setup as proposed, when the user post the transaction, the cost is not captured. Have we miss out anything?
Hi Sean,
Did you implement some security and after that the cost is not captured? Can provide more details what exactly you secured, and what posting was done?
Our procurement department issues purchase orders for stocked items, while the finance department issue POs for non-stocked (expenses, fixed asset acquisition etc). I didn’t want purchasing team to have access to the purchase orders for non-stocked items or at least they should not be able to amend those non-stock item Pos, even when they appear on the PO screen. Can this be achieved?
Hi Mullamari,
Yes, this is possible. You can separate data access using eXtensible Data Security (XDS) policies. A policy can be created where all POs are visible, but restrict on CUD actions. Your scenario requires a small development by creating a new security policy. You can read about XDS also on my website: XDS archives. Or look at my Security topics page.
An example with restriction on CUD actions is available here: Examples – Secure by warehouse.