web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

News and Announcements icon
Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Suggested Answer

Best practice for conditional access (check role, duty or privilege?)

(0) ShareShare
ReportReport
Posted on by 2,011

Hi everyone,
 

I'm looking for some advice on the best D365FO security design for the following scenario.
 

Let's assume these users currently have access to a button through their existing roles:
 

UserExisting Role
User1System Admin
User2IT Admin
User3Role1
User4Role2
User5Role3
User6Role2
User7Role3


In the normal scenario, all of these users should continue to have access to the button.


However, when the current record meets a specific condition (for example, ID1 and ID2 are both populated), only some users should still be able to use the button.
 

For example:

UserAccess when IDs are populated
User1
User2
User3
User4
User5
User6
User7


Notice that User4 and User6 both have Role2, but only User6 should retain access. Likewise, User5 and User7 both have Role3, but only User7 should retain access.


To achieve this, we're introducing a new security role that will be assigned only to the users who should retain access in this specific scenario, alongside their existing operational roles. The role will contain a new duty, which in turn contains the privilege required for this button.
 

Since the condition depends on the current record, the logic has to be evaluated in X++.

  public boolean isButtonEnabled()
   {
       boolean ret;

       ret = next isPostRejectionEnabled();

       if (ret && this.isIDsPopulated())
       {
           ret = this.annsHasRejectionAccess();
       }

       return ret;
   }


   public boolean isIDsPopulated()
   {
       return this.Id1 != '' && this.Id2 != '';
   }


   public boolean hasButtonAccess()
   {
       SecurityUserRole securityUserRole;
       SecurityRole     securityRole;

       select firstonly RecId from securityUserRole
           where securityUserRole.User == curUserId()
              && securityUserRole.AssignmentStatus == RoleAssignmentStatus::Enabled
           exists join securityRole
           where securityUserRole.SecurityRole == securityRole.RecId
              && (securityRole.AotName == '-SYSADMIN-'
              || securityRole.AotName  == 'ITAdmin'
              || securityRole.AotName  == 'NewRole');

       return securityUserRole.RecId != 0;
   }

Given this requirement, is there a better D365FO security design than checking the user's roles in hasButtonAccess()? For example, would you check a duty, a privilege, or use another approach?

Categories:
I have the same question (0)
  • Diego Mancassola Profile Picture
    925 Super User 2026 Season 2 on at

    Hi, if i understand, i would avoid checking role names directly.

    Roles and duties are organizational/security-composition elements; they are not the most appropriate authorization boundary for X++ code. A user can receive the same permission through another role, sub-role, or security customization. A direct query against SecurityUserRole would not necessarily reflect the user’s complete effective permissions.

    The recommended design would be:

    Create a dedicated action menu item representing the restricted operation, enable or disable it based on IDs.
    Add that entry point to a dedicated privilege.
    Add the privilege to a duty and to a small supplemental role, if this fits your security structure.
    Assign that role only to the users who may perform the operation when the IDs are populated.
    In X++, check the user’s effective access to the entry point, rather than checking the role, duty, or privilege name.

  • Suggested answer
    André Arnaud de Calavon Profile Picture
    306,636 Super User 2026 Season 2 on at

    Hi ..,

    If the access to a button is available to anyone except when the record has a specific status or condition, then you will need X++ coding to manage the enablement of the button. 

    You can choose to use security to be assigned to users. This is done in the standard application as well. Some items do work based on a role, others based on a privilege. E.g. the access to private addresses is managed using security roles, see: About the private location security in Finance & Operations and Human Resources - Dynamicspedia

    Also the workflow history form is checking for the SysAdmin or IT manager roles to be able to show workflow instances for all users and those who are in an error state.

    In the Financial reporter, the existence of a privilege assigned to the user via security roles is checked.

     

    The role or privilege does not need additional access to the menu item button, you can check in X++ if the user is assigned to a role (as per your example) or if any role has exploded permissions to a privilege.

     

    Instead of hard-coding the security roles, I would choose for a configurable option like the private location security option. You can still choose to have the SysAdmin and IT manager roles hard-coded as they are standard roles. Additional roles can be considered via configuration. Note that you can also choose for privileges instead of roles. 

    Also consider the organization assignment to security roles. That will determine in what legal entities a user has the permission. 

     

    Note that you can also create two menu item buttons. One for the condition is true and another if the condition of the IDs is false. With X++ you can manage the visibility of the menu-items. Then, similar to what Diego mentioned, you can manage access to the menu items with “standard” security. Then only one menu item will be visible on the form at a moment in time, depending on the condition.

     

    Note that the approach to check for ID values is not waterproof. A user could change the value, then use the menu item button. Thereafter revert the value to the original value. Or are these fields read-only?

  • Suggested answer
    Deepak Agarwal Profile Picture
    9,201 Super User 2026 Season 2 on at

    I would avoid checking roles directly in X++. Instead, create a dedicated privilege (e.g. ANNSPostRejectionOveridePrivilege) assign it through a duty and a new security role, and then check whether the user has that privilege when ID1 and ID2 are populated. This keeps the code independent of role names and aligns better with the D365FO security model (Privilege > Duty > Role). If security assignments change later, no code changes are required.

     

    In short, check a dedicated privilege, not role names. A duty check is also acceptable, but privilege is usually the most granular and maintainable approach.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Season of Sharing Community Challenge Winners!

Congratulations to our community stars!

Women in Power Builds Momentum

Expanding mentorship, skilling, and AI innovation

Congratulations to the July Top 10 Community Leaders

These are the community rock stars!

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 310 Super User 2026 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 276 Most Valuable Professional

#3
Anton Venter Profile Picture

Anton Venter 266 Super User 2026 Season 2

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans