iAccessHandler troubleshooting | User_admin cannot edit or add group members to a group containing a roleIssue Users with the user_admin role unable to add to or edit members of a group containing a role? Start here for troubleshooting tips and examples. To demonstrate, consider the following scenario: Set up a test sys_user_group sntest that contains the sn_templated_snip.template_snippet_reader role.Created a test sys_user testuser_admin and give this user the user_admin role ONLY.Impersonate sntest, and navigate to the sntest group.Notice that sntest sys_user cannot write to the sntest sys_user_group. Please note this behavior extends to roles that contain the sample role. In other words, if the sntest sys_user_group contains the sn_customerservice.esc_fulfiller or the sn_esm_agent role role (which CONTAINS the sn_templated_snip.template_snippet_reader role in its hierarchy), the same applies. Note the IAccessHandler violation in the ACL evaluation.CauseThis is due to a combination of the Application Administration checkbox on the Templated Snippets sys_store_app, as well as the Assignable by field on the affected sys_user_role record, as shown in the below screenshots and explained by the Restrict access to an application product documentation: To clarify, when Application administration is checked, the platform must honor what is in the Assignable by field for a sys_user_role. If assignable_by is empty, and application administration is checked, NO ONE on the platform can grant this role.ResolutionThis can be very tedious to identify especially when there are multiple layers of nesting. Consider a hypothetical scenario with following role inheritance structure: With each layer - (and keep in mind certain roles like sn_hr_core.basic contain at least 5 roles that have their own inheritance chain), the number of checks can become exhausting and it is easy to lose count of what has already been checked. There are in addition two potential criteria that have to be identified in a nested role: The user running into the iAccessHandler violation doesn't have the role itself.One of the roles in the inheritance chain has 'Application administration' checked - but no 'Assignable by' populated, resulting in no one being able to assign the role. We've created a script to simplify this identification: var group_sys = 'GROUP_SYS_HERE'; //always populate this with the group sys_id var user_sys = ''; //populate this if you want to verify whether user passes iAccessHandler checks, otherwise leave it blank! //this version of script is for iAccessHandler identification for roles in group role inheritance chain that may var group = new GlideRecord('sys_user_group'); group.get(group_sys); var output = ''; var final_role_list = []; var roles_without_assignable_by = []; var exclusion_list = []; var grp_role = new GlideRecord('sys_group_has_role'); grp_role.addEncodedQuery('group=' + group.sys_id); grp_role.query(); while(grp_role.next()){ //start checking role hierarchy checkRole(grp_role.role + ''); } gs.info(output); if(final_role_list.length > 0) gs.info('Final role list: ' + final_role_list.join(', ')); if(roles_without_assignable_by.length > 0) gs.info('Roles without Assignable By (any roles in this list cannot be inherited unless App Administration is unchecked for scope OR Assignable by is populated): ' + roles_without_assignable_by.join(', ')); if(user_sys){ var missing_roles = []; var user = new GlideRecord('sys_user'); if(user.get(user_sys)){ for(var roles in final_role_list){ var has_role = new GlideRecord('sys_user_has_role'); has_role.addEncodedQuery('user=' + user.sys_id + '^role.name=' + final_role_list[roles]); has_role.query(); if(!has_role.next() && missing_roles.indexOf(final_role_list[roles]) == -1){ missing_roles.push(final_role_list[roles]); } } if(missing_roles.length > 0) gs.info('User: ' + user.name + ' is missing: ' + missing_roles.join(', ')); else if(roles_without_assignable_by.length >0){ gs.info('User: ' + user.name + ' has all roles needed for iAccessHandler, but will not be able to pass iAccessHandler due to the Roles without Assignable by identified.'); } else gs.info('User: ' + user.name + ' has all roles needed for iAccessHandler.'); } } function checkRole(role_sys){ var role = new GlideRecord('sys_user_role'); role.get(role_sys); if(role.sys_scope.scoped_administration){ output += '\n' + role.name + ' will trigger iAccessHandler, ' + role.sys_scope.getDisplayValue() + ' has Application Administration activated.' + (role.assignable_by ? ' Assignable by: ' + role.assignable_by.getDisplayValue() : ' NOTE Assignable by is empty, role cannot be inherited without this set'); if(role.assignable_by && final_role_list.indexOf(role.assignable_by.getDisplayValue()) == -1){ final_role_list.push(role.assignable_by.getDisplayValue()); } else if(!role.assignable_by && roles_without_assignable_by.indexOf(role.name + '') == -1){ roles_without_assignable_by.push(role.name + ''); } } var contains = new GlideRecord('sys_user_role_contains'); contains.addEncodedQuery('role=' + role.sys_id + '^role.nameNOT IN' + exclusion_list.toString()); contains.query(); exclusion_list.push(role.name + ''); if(contains.getRowCount() > 0){ while(contains.next()){ checkRole(contains.contains + ''); } } else return; } Script Usage I am testing against the scenario depicted in the graphic - I have made an adjustment to the sn_templated_snip.template_snippet_reader so that Assignable by is empty.User Alejandro Prenatt only has the user_admin, snc_internal, and kmf_admin role.I input the group and the user sys ids in the two variables at the beginning of the script and it outputs: sn_hr_core.basic will trigger iAccessHandler, Human Resources: Core has Application Administration activated. Assignable by: sn_hr_core.manager sn_esign.config_manager will trigger iAccessHandler, E-Signature has Application Administration activated. Assignable by: sn_esign.config_manager sn_hr_core.case_writer will trigger iAccessHandler, Human Resources: Core has Application Administration activated. Assignable by: sn_hr_core.manager sn_templated_snip.template_snippet_reader will trigger iAccessHandler, Templated Snippets has Application Administration activated. NOTE Assignable by is empty, role cannot be inherited without this set sn_hr_core.case_reader will trigger iAccessHandler, Human Resources: Core has Application Administration activated. Assignable by: sn_hr_core.manager sn_hr_core.report_creator will trigger iAccessHandler, Human Resources: Core has Application Administration activated. Assignable by: sn_hr_core.manager sn_templated_snip.template_snippet_reader will trigger iAccessHandler, Templated Snippets has Application Administration activated. NOTE Assignable by is empty, role cannot be inherited without this set sn_templated_snip.template_snippet_reader will trigger iAccessHandler, Templated Snippets has Application Administration activated. NOTE Assignable by is empty, role cannot be inherited without this set sn_hr_core.profile_writer will trigger iAccessHandler, Human Resources: Core has Application Administration activated. Assignable by: sn_hr_core.manager sn_hr_core.profile_reader will trigger iAccessHandler, Human Resources: Core has Application Administration activated. Assignable by: sn_hr_core.manager sn_hr_core.kb_writer will trigger iAccessHandler, Human Resources: Core has Application Administration activated. Assignable by: sn_hr_core.manager sn_lc.content_reader will trigger iAccessHandler, Learning Core has Application Administration activated. Assignable by: sn_lc.content_writer sn_kmf.cryptographic_operator will trigger iAccessHandler, ServiceNow Key Management Framework has Application Administration activated. Assignable by: sn_kmf.admin sn_templated_snip.template_snippet_writer will trigger iAccessHandler, Templated Snippets has Application Administration activated. Assignable by: sn_templated_snip.template_snippet_writer sn_templated_snip.template_snippet_reader will trigger iAccessHandler, Templated Snippets has Application Administration activated. NOTE Assignable by is empty, role cannot be inherited without this set sn_doc.reader will trigger iAccessHandler, Document Templates has Application Administration activated. Assignable by: sn_doc.admin *** Script: Final role list: sn_hr_core.manager, sn_esign.config_manager, sn_lc.content_writer, sn_kmf.admin, sn_templated_snip.template_snippet_writer, sn_doc.admin *** Script: Roles without Assignable By (any roles in this list cannot be inherited unless App Administration is unchecked for scope OR Assignable by is populated): sn_templated_snip.template_snippet_reader *** Script: User: Alejandra Prenatt is missing: sn_hr_core.manager, sn_esign.config_manager, sn_lc.content_writer, sn_templated_snip.template_snippet_writer, sn_doc.admin The first script output after the verbose logging titled Script: Final role list: will tell you the full list of roles needed to properly pass iAccessHandler.The second script output tells you of any roles that do NOT have assignable by populated but has the scope checked as Application administration.The 3rd line tells you the delta between what the user has and what the full list of roles needed to properly pass iAccessHandler.