ServiceNow Group Roles: The Group Roles Table, Role Inheritance, and sys_group_has_role
Two things about ServiceNow group roles catch out even experienced admins. The first is that roles travel down the group hierarchy while membership does not, so a role granted on a parent group reaches everybody below it and a ticket assigned to that same parent group reaches almost nobody. The second is that the field built to tell you which group handed a user a role has been deprecated for years and comes back empty. Here is the actual data model, the inheritance rules, and the answers to the questions the empty field leaves behind.
In short
ServiceNow group roles are stored on the sys_group_has_role table, which links a group on sys_user_group to a role on sys_user_role. When a user joins that group, the platform writes a row to sys_user_has_role with inherited set to true, which is how a role reaches a person without anybody granting it to them directly. Roles do cascade down the group hierarchy: a child group inherits the roles of its parent group, and those inherited rows on sys_group_has_role carry inherits set to true along with a granted_by pointing at the group they came from. Group membership behaves the opposite way and never cascades, which is the asymmetry behind most confused access reviews. Three practical traps follow. The granted_by field on sys_user_has_role, together with included_in_role and included_in_role_instance, was deprecated by the Contextual Security: Role Management V2 plugin and is no longer maintained, so it is usually blank. That same plugin, com.glide.role_management.inh_count, de-duplicates the user role table using an inheritance count column rather than writing a second row, which is why removing somebody from one group can correctly leave a role in place. And the business rule that pushes parent roles down to child groups runs as a script that can time out on instances with a lot of groups, so some members silently never receive the role at all. Assigner runs round robin, weighted round robin, load-balanced, skill-based and availability rules as one engine beside the ServiceNow you already run, at $12/user/mo billed yearly, and names the rule behind every assignment so a routing dispute takes seconds. The AI assists your triage, the rules stay yours.
Why it fits
ServiceNow admins and platform owners designing a group and role model, security and audit teams trying to prove where a role came from during an access review, and ITSM leads whose assignment groups have quietly become role-granting groups.
Routing that does not ride on your role model
Roles decide who is allowed to touch a record. They were never meant to decide who should. Most teams end up overloading the role model with routing intent because it is the only structure available, and then cannot change routing without touching access. Assigner keeps the two apart: eligibility for work is a rule you edit in seconds, and it does not require granting anybody a new role.
One place that answers who is eligible for this work
Right now the answer is spread across sys_user_grmember, sys_group_has_role, the parent hierarchy, contained roles, and whichever qualifiers somebody wrote. Assigner keeps eligibility in one rule, shows the candidates it considered, and records which one it picked and why.
Assignment that does not inherit surprises
Because roles cascade and membership does not, an assignment group that looks correctly staffed on paper can resolve to an empty roster. Assigner routes to named people from a defined pool and tells you immediately when that pool is empty, rather than stamping a group and letting the ticket sit.
Side by side
Every path a role takes to a ServiceNow user, and what each one breaks
| How the role reaches the user | Where it is recorded | Does it cascade down the group hierarchy? | How it looks on the user record | The failure it causes |
|---|---|---|---|---|
| Granted directly to the user | sys_user_has_role, inherited is false | Not applicable | A row on the Roles related list with nothing behind it | Nobody can say who asked for it or why. Direct grants are the rows that survive every reorg and fail every access review. |
| Granted to a group the user belongs to | sys_group_has_role, plus a sys_user_has_role row with inherited true | Yes | Inherited role, with the group as the only clue | Adding one person to one group can hand them a role that was defined three levels up the tree and never reviewed. |
| Inherited by a child group from its parent | sys_group_has_role with inherits true and granted_by set to the source group | Yes, this is the mechanism | Indistinguishable from a direct group grant | The propagation runs in a business rule. On instances with a lot of groups it has been reported to time out, leaving some child group members without the role and no error anybody sees. |
| Contained inside another role | The role definition on sys_user_role | Follows whatever granted the containing role | Inherited, with no group behind it at all | A user who belongs to no group still shows roles, so the first hour of the investigation is spent looking for missing membership rows that were never supposed to exist. |
| Granted again by a second group | No new row. The inheritance count on the existing row is incremented | Yes | One row, higher count | Remove the user from one of the two groups and the role correctly stays. To the person running the review it looks like the removal failed. |
| Group membership itself, for comparison | sys_user_grmember | No. Membership never cascades. | The Groups related list | A routing rule aimed at a tidy parent group resolves to only the direct members of the parent group, which is frequently nobody at all. |
Verified in August 2026 against ServiceNow Community developer, platform, sysadmin and HRSD forum threads covering role inheritance, the sys_user_has_role table and the Contextual Security: Role Management plugins. Behavior varies with which role management plugin is active on your instance, so confirm the inheritance count property and the plugin version in your own environment before writing any script that reads or writes sys_user_has_role.
In detail
ServiceNow group roles, table by table
What is the ServiceNow group roles table?
The group roles table is sys_group_has_role. It is a plain many to many join: one column points at a group on sys_user_group, another points at a role on sys_user_role, and a row means that group grants that role. On the group form it surfaces as the Roles related list, which is where most admins meet it without ever learning the table name.
Two other columns matter more than the join itself. inherits marks a row that arrived from a parent group rather than being added by hand, and granted_by records which group it came from. Together they are how you separate roles somebody deliberately gave a group from roles the hierarchy pushed onto it. A filter of granted_by is not empty and inherits is true lists every inherited group role on the instance, which is the fastest way to see how much of your access model is being generated rather than designed.
The companion table is sys_user_has_role, and it is easy to confuse the two. sys_group_has_role holds the design: what a group is entitled to. sys_user_has_role holds the result: what a person actually ended up with, one row per user and role, with an inherited flag that is true when the role arrived through a group or through another role rather than being granted to the person directly. Reports about entitlement should read the group table. Reports about exposure should read the user table.
Do ServiceNow child groups inherit roles from the parent group?
Yes. If a group has a parent, the child group inherits the roles of the parent group, and the members of that child group end up holding those roles. This is the documented and expected behavior, and it is the single most useful thing about the group hierarchy: put the role every network engineer needs on a parent network group, and the eight child groups underneath it stay correct without anybody maintaining eight sets of roles.
It is also where the surprises live, because the inheritance is produced by a business rule rather than resolved at read time. The rows are real rows, written when something changes. Three consequences follow, all of them reported repeatedly in ServiceNow community threads.
First, it can time out. One instance with a large number of groups reported the propagation script hitting a timeout after 296 seconds, with the result that members of child groups did not receive some parent roles. Nothing about that failure is visible on the group form. The parent shows the role, the child shows the relationship, and the user simply does not have the access.
Second, a newly created child group does not always pick up the parent roles. Admins report creating a group, setting the Parent field, and finding no roles inherited. The workarounds that circulate are equally telling: clear the Parent field, save, and set it again, or remove the role from the parent and add it back. Both work by forcing the rule to run again, which is a strong hint that the trigger, not the logic, is what failed.
Third, role management plugins interfere with it. Community answers point at the Contextual Security role management plugins as a cause of inheritance not behaving as expected, and separate threads report inheritance breaking on instances that extended sys_user_group or sys_user_grmember with custom tables. If you have extended either table, treat inheritance as something to test rather than something to assume.
Roles cascade, membership does not, and that gap is where routing breaks
This is the asymmetry worth writing on a whiteboard, because almost nobody expects it and it explains a whole category of ServiceNow problems.
Roles flow down the hierarchy. Membership does not flow at all. Put the itil role on a parent group and every child group inherits it, so every person in every child group can work tickets. Assign an incident to that same parent group and the work is offered to the direct members of the parent group, which on a well designed hierarchy is often nobody, because the parent exists purely as an organizing node.
So the parent group looks, on paper, like the right place to send work. It is the group with the roles. It is the group with the tidy name. It has fifty people underneath it. And a ticket sent there sits untouched over a weekend because the roster resolving behind it is empty. The ServiceNow group membership page covers the membership half of this in detail, including the inconsistency that User Criteria based on a group does include subgroup members, so catalog and knowledge access cascades while assignment stubbornly does not.
The practical rule is to keep the two models apart on purpose. Use the hierarchy for entitlement, where cascading is a feature. Assign work only to leaf groups that have real members, never to organizing parents. And check the assumption directly rather than trusting the org chart: open the parent group, look at the Group Members related list, and count. If the number is zero, nothing you route there will ever be worked.
Why granted_by is empty, and how to find where a role really came from
Sooner or later somebody asks the reasonable question: this user has the itil_admin role, which group gave it to them? There is a field that looks built for exactly that. On sys_user_has_role the granted_by field is a reference to sys_user_group and is meant to name the granting group. On most modern instances it is blank.
The reason is not a bug in your data. granted_by, along with included_in_role and included_in_role_instance, was deprecated by the Contextual Security: Role Management V2 plugin and is not maintained any more. Community answers from ServiceNow practitioners are explicit that these fields are no longer populated by the platform and that granted_by survives mainly for Role Delegation. Teams routinely open a support case about the empty column and are told, in effect, that the column is not coming back.
So reconstruct the answer instead. It takes two queries and no plugin.
Start on sys_group_has_role, filtered to the role in question. That gives every group entitled to it, including the inherited rows, where granted_by is maintained and does tell you which parent the entitlement came from. Then take that group list to sys_user_grmember and filter membership to the user. The intersection is your answer: the groups that both grant the role and contain the person. If the intersection is empty, the role did not come from a group at all, and you are looking at either a direct grant or a role contained inside another role.
Do this as a saved report rather than ad hoc. Access reviews come round on a schedule, and the reconstruction is the same every time.
Inheritance count, de-duplication, and the import that quietly skips rows
If two different groups both grant a user the same role, ServiceNow does not write two rows. The Contextual Security: Role Management V2 plugin, identified as com.glide.role_management.inh_count, exists to prevent duplicate entries in sys_user_has_role for inherited roles, and it does it with an inheritance count column. The second grant increments the count on the row that is already there.
This is correct behavior and it is the answer to a question that generates a lot of support tickets: why did removing this person from a group not remove the role? Because another group still grants it, and the count went from two to one rather than the row disappearing. The role is still legitimately theirs.
The consequence people trip over is on data loads. The system property glide.role_management.use.inh_count controls this behavior, and when it is true the plugin owns the contents of sys_user_has_role. You should not import records into sys_user_has_role while that property is on. The table is derived, not authoritative, and an import fights the code that maintains it. This is what sits behind the "Skipping record for table sys_user_has_role" messages that appear in import and update set logs and look, at first glance, like a permissions problem.
Load the source of truth instead. Import group membership into sys_user_grmember and group entitlements into sys_group_has_role, and let the platform derive the user role rows itself. It is slower to think about and it is the only version that stays correct.
Roles that stay behind after you remove somebody from a group
The expected behavior when a user leaves a group is that the inherited roles that came with that group disappear. Often they do not. Admins report rows persisting on sys_user_has_role with inherited still set to true, long after the membership row is gone.
Check the legitimate explanation first, because it is the common one: another group still grants the role, and the inheritance count simply decremented. Query sys_group_has_role for the role, cross-check the remaining groups for that user, and if you find a second source, there is nothing to fix.
If there is no second source, you are looking at the real failure, which community reports attribute to the out of box Group Member Delete business rule not always clearing inherited roles, particularly where the inherited flag is stuck. The workaround that circulates is a two step: set inherited to false first, then delete the record, because the deletion path behaves differently for a row still marked inherited. ServiceNow support can also run a recalculation available with the Role Management V2 plugin, which audits and corrects inheritance discrepancies across the instance and is the right call if this is widespread rather than a handful of rows.
Whatever the fix, treat orphaned inherited roles as a governance finding rather than a nuisance. Access that outlives the reason for it is exactly what an auditor is looking for, and unlike most audit findings this one has a query you can run in a minute.
Grant roles to groups, and keep role groups separate from work groups
The design guidance is consistent across every serious ServiceNow group model, and it comes in two halves.
The first half: grant roles to groups, not to users. A direct grant on a user is a decision with no owner, no reason attached, and no natural review point. A grant on a group can be explained, because the group has a name, a manager and a purpose. When someone changes teams, the entitlement follows the group change instead of being remembered by whoever happens to know.
The second half is the one teams skip: the groups that grant roles should usually not be the groups that receive work. The moment an assignment group also carries a meaningful role, the roster becomes an access decision. Adding a contractor to the queue so they can pick up tickets for a fortnight also grants whatever the group grants, and quietly stops being reversible when nobody remembers to remove them. Published ServiceNow group best practice recommends a separate security group type for groups whose job is granting roles, kept distinct from process groups that work items. Our page on ServiceNow group types covers how to make that distinction actually enforce something, which requires a reference qualifier, because type on its own gates nothing.
One shortcut deserves a warning. user_admin is the role people reach for when a team lead wants to manage their own roster without a full admin, and it is far broader than it sounds: on any instance where groups grant roles, the ability to edit group membership is the ability to grant those roles. Delegating group management through the Manager field with targeted ACLs is the narrower and safer pattern.
Questions buyers ask
Frequently asked questions
What is the ServiceNow group roles table?
The group roles table is sys_group_has_role. Each row links a group on sys_user_group to a role on sys_user_role and means that group grants that role. It appears on the group form as the Roles related list. The inherits and granted_by columns on the same table distinguish roles added by hand from roles pushed down by a parent group.
What is sys_group_has_role in ServiceNow?
sys_group_has_role is the many to many table joining groups to roles. It records entitlement, meaning what a group is allowed to do. The separate sys_user_has_role table records the result for individual people, with an inherited flag set to true when the role reached them through a group or through another role instead of a direct grant.
Do ServiceNow groups inherit roles from parent groups?
Yes. A child group inherits the roles of its parent group, and members of the child group receive them. Inherited rows on sys_group_has_role carry inherits set to true and a granted_by pointing at the source group. The propagation is done by a business rule, so it can fail quietly on large instances or on newly created child groups.
What is the difference between groups and roles in ServiceNow?
A role is a permission, checked by ACLs to decide what somebody can see and do. A group is a collection of people, used to grant roles in bulk and to own work through assignment groups. Roles answer what you may do, groups answer who you are with. The recommended practice is to grant roles to groups rather than to individual users.
How do I add a role to a group in ServiceNow?
Open the group record in User Administration, then Groups, scroll to the Roles related list, and use Edit to pick the role. The platform writes the row to sys_group_has_role and then propagates it to the current members as inherited rows on sys_user_has_role. On a large group that propagation is asynchronous, so give it a minute before concluding it failed.
How do I add a role to multiple groups in ServiceNow?
Open sys_group_has_role directly as a list, which lets you insert rows for many groups without opening each group form. For a repeatable bulk change, a background script that queries the groups you want and inserts a row per group is safer, because it can be reviewed before it runs. Avoid importing into sys_user_has_role, which the platform maintains itself.
How do I check what roles a user has in ServiceNow?
Open the user record and look at the Roles related list, which shows every role including inherited ones. For an instance wide view, filter sys_user_has_role by user. The inherited column tells you whether the role was granted directly or arrived through a group or a containing role, which is the distinction that matters during an access review.
What is the ServiceNow role inheritance count?
The inheritance count records how many times the same role has been granted to a user through different sources. The Contextual Security: Role Management V2 plugin uses it instead of writing duplicate rows in sys_user_has_role. When a second group grants a role the user already holds, the count increments. When one of those groups is removed, the count decrements and the role correctly remains.
Why does a user still have a role after being removed from the group?
Usually because a second group still grants it, so the inheritance count decremented rather than the row being deleted. If no other group grants it, the out of box Group Member Delete business rule has failed to clear the inherited row. The reported workaround is to set inherited to false and then delete the record.
Can a user have a role in ServiceNow without being in any group?
Yes, and it is common. Roles contain other roles, so a user granted a broad role automatically holds every role inside it, shown as inherited with no group behind it. Direct grants written straight to the user do the same thing. Both are why an empty Groups related list does not mean an empty Roles related list.
What is the ServiceNow group admin role?
There is no role named group admin. The role people mean is user_admin, which allows managing users and groups without full admin rights. Treat it carefully. On an instance where groups grant roles, anyone who can edit group membership can effectively grant those roles, which makes user_admin a privilege escalation path rather than a light delegation.
Why is the granted_by field empty on sys_user_has_role?
Because it was deprecated. The Contextual Security: Role Management V2 plugin retired granted_by along with included_in_role and included_in_role_instance, and the platform no longer maintains them, so the column reads blank. To find the source of a role, query sys_group_has_role for that role and intersect that group list with the memberships recorded for the user on sys_user_grmember.
Keep reading
The rest of the ServiceNow group model, and what happens once a group has been chosen.
- ServiceNow group membership - Why removing a member leaves no history, and why membership never cascades.
- ServiceNow group types - The type field gates nothing on its own. Here is the qualifier that gives it teeth.
- ServiceNow assignment groups - The group record field by field, and the mistake each field tends to cause.
- ServiceNow group manager - The Manager field grants nothing. The ACL pattern that makes delegation real.
- Groups and roles best practices - How to design the group model so access reviews and routing stop fighting.
- ServiceNow Advanced Work Assignment - What it takes to push work past the group and onto a named person.
Stop hand-sorting your incoming work
Let Assigner route it to the right available person by skill, workload, and availability, using rules you control. Nothing sits unassigned and no one gets cherry-picked. Every assignment shows why.