- Source: GL_GroupRole, GL_ProjectRole, GL_InstanceRole
- Destination: GL_GroupRole, GL_ProjectRole, GL_InstanceRole
The traversable GL_HasBaseRole edge models the permission hierarchy within each role scope. A higher role subsumes all permissions of all lower roles — Owner subsumes Maintainer, Maintainer subsumes Developer, and so on. This is modeled as a chain of GL_HasBaseRole edges from each role to the next lower role.
GL_HasBaseRole has several distinct forms:
Within-scope hierarchy — The standard permission chain within group roles, project roles, or instance roles:
- Group:
Owner → Maintainer → Developer → Reporter → Planner → Guest → MinimalAccess - Project: same chain
- Instance:
Administrator → Member → External → Unauthenticated
Instance Admin → Group Owner — The instance Administrator role has GL_HasBaseRole edges to the Owner role in every top-level group, reflecting GitLab's behavior where admins have Owner-level access everywhere.
Instance Admin → Project Owner — The instance Administrator also has Owner in projects owned by user personal namespaces.
In Cypher queries, traversing (user)-[:GL_HasRole|GL_HasBaseRole|GL_InheritRole*1..]->(:GL_ProjectRole {name: "..."}) finds all users with effective access at a given project role level.
graph LR
owner("fa:fa-user-tie GL_GroupRole myorg/Owner")
maint("fa:fa-user-tie GL_GroupRole myorg/Maintainer")
dev("fa:fa-user-tie GL_GroupRole myorg/Developer")
admin("fa:fa-user-tie GL_InstanceRole Administrator")
topOwner("fa:fa-user-tie GL_GroupRole myorg/Owner")
owner -->|GL_HasBaseRole| maint
maint -->|GL_HasBaseRole| dev
admin -->|GL_HasBaseRole| topOwner