Summary and recommendation
GitLab user management can be run manually, but complexity usually increases with role models, licensing gates, and offboarding dependencies. This guide gives the exact mechanics and where automation has the biggest impact.
GitLab's access model is hierarchical: five standard roles (Guest, Reporter, Developer, Maintainer, Owner) apply at both group and project levels, with roles cascading from group down to subgroup and project.
A role assigned at the group level propagates to every app and project within that group, but can be elevated - never reduced - at the project level. Ultimate plan subscribers can layer custom roles on top of any base role, toggling specific permissions individually, though the set of toggleable permissions remains limited.
Quick facts
| Admin console path | Admin Area > Overview > Users (self-managed: /-/admin/users; GitLab.com group billing: group > Settings > Billing or group > Members) |
| Admin console URL | Official docs |
| SCIM available | Yes |
| SCIM tier required | Premium or Ultimate |
| SSO prerequisite | Yes |
User types and roles
| Role | Permissions | Cannot do | Plan required | Seat cost | Watch out for |
|---|---|---|---|---|---|
| Guest | Can view public/internal projects they are added to, create issues, leave comments, view wiki pages. At group level: view group details and list of projects. | Cannot push code, create branches, merge requests, or access CI/CD pipelines. Cannot view private repository contents unless explicitly added. | Free (all plans) | Billable seat on paid plans for private groups/projects; not billable on public projects or Free tier for GitLab.com | On GitLab.com paid plans, Guest members of private groups consume a billable seat. On Ultimate, Guest role in a private group is billable unless the user is an external user with no other paid-tier memberships. |
| Reporter | All Guest permissions plus: clone repository, view CI/CD pipelines, create/manage issues and labels, view merge requests, access container registry. | Cannot push code, create branches, approve merge requests, or manage project settings. | Free (all plans) | Billable seat on all paid plans | Reporter cannot trigger manual CI/CD jobs or modify pipeline schedules. |
| Developer | All Reporter permissions plus: push to non-protected branches, create/delete branches, create merge requests, manage CI/CD pipelines and jobs, create tags, manage environments. | Cannot push to protected branches (by default), cannot manage group/project members, cannot change project settings or visibility. | Free (all plans) | Billable seat on all paid plans | Protected branch rules can further restrict or expand Developer push/merge access; defaults vary by project configuration. |
| Maintainer | All Developer permissions plus: push to protected branches, manage project members (up to Maintainer), manage project settings, manage CI/CD variables, manage deploy keys, manage integrations. | Cannot transfer or delete the project, cannot manage group-level settings, cannot add members above Maintainer role. | Free (all plans) | Billable seat on all paid plans | Maintainers can add members up to Maintainer level only; adding Owners requires Owner or group-level permissions. |
| Owner | Full control over the group or project: all Maintainer permissions plus transfer/delete project or group, manage group members at all roles, change visibility, manage billing (group owners on SaaS). | At project level, cannot exceed group-level restrictions. On GitLab.com, cannot access instance-level admin settings. | Free (all plans) | Billable seat on all paid plans | On GitLab.com, the Owner role is the highest available at group/project level. There is no instance-level admin for SaaS users. On self-managed, instance Admins are separate from group Owners. |
| Instance Administrator (self-managed only) | Full access to all groups, projects, users, and instance settings via the Admin Area. Can impersonate users, manage all settings, access all repositories. | Not applicable to GitLab.com SaaS. | Self-managed only (all plans) | Billable seat on paid self-managed plans | Admin users bypass all permission checks. Granting admin access should be tightly controlled. Admin users are not automatically Owners of all groups/projects but can access everything via the Admin Area. |
| Minimal Access (group-level) | Can see the group in listings and access the group page. No access to group contents, projects, or subgroups unless explicitly added to them. | Cannot view projects, issues, code, or any group resources beyond the group name/description. | Premium or Ultimate (GitLab.com and self-managed) | Billable seat on paid plans | Intended for users who need SSO access to a top-level group but should only access specific subgroups or projects. Requires Premium or Ultimate. |
| External User | Can only access projects they are explicitly added to. Cannot access internal projects or groups. | Cannot access any internal-visibility resources. Cannot browse the instance's public project list in the same way as regular users. | Free (all plans, self-managed); configurable on GitLab.com via group settings | Billable seat if added to a paid group/project | External users must be explicitly invited to each project or group. On self-managed, admins can mark users as external. On GitLab.com, domain-based external user controls are limited. |
Permission model
- Model type: hybrid
- Description: GitLab uses a hierarchical role-based access control (RBAC) model with five standard roles (Guest, Reporter, Developer, Maintainer, Owner) applied at both group and project levels. Roles cascade from group to subgroup to project but can be elevated at lower levels. Ultimate plan adds custom roles, allowing admins to create roles based on a standard role with specific additional permissions toggled on. Protected branches, protected tags, and CI/CD variable scoping provide additional granular controls layered on top of roles.
- Custom roles: Yes
- Custom roles plan: Ultimate
- Granularity: Role-level granularity at group/project scope; custom roles (Ultimate) allow per-permission toggles on top of a base role; protected resource rules add further per-branch/tag controls.
How to add users
- To add a member to a group (GitLab.com): Navigate to the group > left sidebar > Manage > Members > Invite members.
- Enter the user's GitLab username or email address.
- Select a role (Guest, Reporter, Developer, Maintainer, or Owner).
- Optionally set an access expiration date.
- Click 'Invite' to send the invitation. The user receives an email and must accept.
- To add a member to a project: Navigate to the project > left sidebar > Manage > Members > Invite members, then follow the same steps.
- Self-managed admin creating a new user: Admin Area (/-/admin/users) > New user > fill in required fields > Create user. User receives a password reset email.
Required fields: Username or email address (for invitations), Role selection, For new user creation (self-managed): Name, Username, Email
Watch out for:
- Inviting a user by email who does not have a GitLab account creates a pending invitation; they must sign up and accept before consuming a seat.
- On GitLab.com, adding a member to a private group on a paid plan immediately counts toward billable seats once the invitation is accepted.
- Group-level role assignments propagate to all projects within the group; project-level assignments can only elevate, not reduce, the group-level role.
- On self-managed instances, new users created by admins are sent a password reset link; the admin does not set the password directly by default.
- Domain allowlist (group-level) restricts who can be invited but does not auto-provision users; it only blocks invitations from outside allowed domains.
- Inviting a user already at a higher role via group membership to a project at a lower role has no effect; the higher role takes precedence.
| Bulk option | Availability | Notes |
|---|---|---|
| CSV import | Yes | Group > Settings > Members > Import from CSV (available on GitLab.com and self-managed; imports a CSV with columns: email, role, expiry_date). See: https://docs.gitlab.com/ee/user/group/manage.html#bulk-add-or-invite-members-to-a-group-with-a-csv-file |
| Domain whitelisting | Yes | Automatic domain-based user add |
| IdP provisioning | Yes | Premium or Ultimate (requires Group SSO to be configured first; SCIM supported for Okta, Azure AD/Entra ID, and other SAML-compatible IdPs) |
How to remove or deactivate users
- Can delete users: Yes
- Delete/deactivate behavior: GitLab supports multiple removal states: (1) Deactivate - user cannot log in, does not consume a billable seat, all their data is preserved; can be reactivated. (2) Block - user cannot log in, still consumes a billable seat, data preserved; used for policy violations. (3) Ban - user cannot log in, their contributions are hidden from public view; data preserved. (4) Delete - permanently removes the user account and, optionally, all content they own (issues, MRs, etc.); irreversible. On GitLab.com, group owners can remove members from a group (removing access) but cannot delete the underlying GitLab account; only instance admins (self-managed) or GitLab Support can delete accounts.
- Self-managed (Admin Area): Navigate to Admin Area (/-/admin/users) > find the user > click on their name > click 'Deactivate' from the user detail page, or use the action menu in the user list.
- GitLab.com (group owner removing a member): Navigate to group > Manage > Members > find the member > click the three-dot menu > Remove member. This removes group access but does not deactivate or delete the GitLab.com account.
- To block a user (self-managed admin): Admin Area > Users > select user > Block. The user is immediately signed out.
- To delete a user (self-managed admin): Admin Area > Users > select user > Delete user (deletes account but preserves their contributions attributed to a 'Ghost' user) or Delete user and contributions (removes all owned content).
| Data impact | Behavior |
|---|---|
| Owned records | When a user is deactivated or blocked, all their issues, merge requests, comments, and commits remain intact and attributed to them. When deleted with 'Delete user', their account is removed and contributions are re-attributed to a system 'Ghost' user. When deleted with 'Delete user and contributions', all their issues, MRs, and other owned content are permanently deleted. |
| Shared content | Shared content (comments on others' issues, commits to shared repos) is preserved under all deactivation/blocking actions. Under 'Delete user and contributions', owned issues and MRs are deleted but commits in repositories remain (Git history is not rewritten). |
| Integrations | Deactivating or blocking a user invalidates their personal access tokens and OAuth tokens, which may break integrations or CI/CD pipelines that use those tokens. Service accounts or group access tokens should be used for integrations instead. |
| License freed | Deactivating a user (self-managed) frees the billable seat. Blocking a user does NOT free the billable seat on self-managed. Removing a member from a GitLab.com group frees the seat for that group's subscription. Seat reconciliation on GitLab.com occurs at the next billing cycle or upon manual seat reduction. |
Watch out for:
- Blocking a user on self-managed still counts toward the license seat count; only deactivation frees the seat.
- On GitLab.com, group owners cannot deactivate or delete a user's GitLab.com account - they can only remove the user from the group.
- Deleting a user who is the sole owner of a group or namespace will fail unless ownership is transferred first or the group is also deleted.
- Personal access tokens belonging to a deactivated or blocked user are immediately revoked; any automation using those tokens will break.
- SCIM-provisioned users who are deprovisioned via the IdP are blocked in GitLab, not deleted; their data is preserved.
- Reactivating a deactivated user on self-managed restores their access but they must log in within a configurable period or be auto-deactivated again (if auto-deactivation of dormant users is enabled).
License and seat management
| Seat type | Includes | Cost |
|---|---|---|
| Billable Member (GitLab.com SaaS) | Any user with a role of Guest or higher in a private group or project on a paid plan. Users with only public project access or Free-tier group membership are not billable. | Counted against the group's purchased seat count. Overage is billed at the per-seat rate at true-up. |
| Licensed User (self-managed) | All active, non-deactivated, non-blocked users on the instance. Bot/service accounts and internal users may be excluded depending on configuration. | Counted against the instance license seat count. Exceeding the license triggers a true-up at renewal. |
| Guest (Ultimate, private group) | On Ultimate plan, Guest-role members of private groups are billable. On lower plans, Guest members of private groups are also billable. | Same per-seat rate as other roles; no discount for Guest role. |
| GitLab Duo Pro Add-on Seat | AI-assisted features (code suggestions, GitLab Duo Chat). Must be assigned individually to users who need it. | $19/user/month (as of 2024 pricing) |
- Where to check usage: GitLab.com: Group > Settings > Billing (shows seats in use, seats owed, max seats used). Self-managed: Admin Area > Subscription (/-/admin/subscription) shows license usage, active users, and historical peak.
- How to identify unused seats: GitLab.com: Group > Manage > Members - sort by 'Last activity' to identify inactive members. Self-managed: Admin Area > Users - filter by 'Dormant' or use the built-in dormant user auto-deactivation feature (Admin Area > Settings > General > Account and limit > Dormant users). GitLab also provides a 'Max seats used' metric in billing to track peak consumption.
- Billing notes: GitLab.com uses a 'max seats used' true-up model: if seat usage exceeds the purchased count at any point during the subscription year, the overage is billed at renewal. Removing members mid-year does not generate a refund but reduces future true-up exposure. Self-managed licenses are similarly true-up based at annual renewal. Free tier is limited to 5 users for private groups on GitLab.com (as of current pricing). Seat counts include pending (invited but not yet accepted) members on GitLab.com once the invitation is accepted.
The cost of manual management
GitLab.com uses a max-seats-used true-up model: if your seat count peaks above the purchased amount at any point during the subscription year, the overage is billed at renewal - not in real time. This means a brief onboarding spike can generate unexpected charges months later.
Removing members mid-year reduces future true-up exposure but does not trigger a refund.
SCIM provisioning is gated behind Premium ($29/user/month) or Ultimate ($99/user/month) and requires Group SSO (SAML) to be configured first. On Free, every app and project membership must be managed manually, with no automated deprovisioning path.
Guest-role members of private groups consume a billable seat on all paid plans - there is no seat discount for the Guest role.
What IT admins are saying
Admins consistently flag that blocking a user on self-managed does not free a license seat - only deactivation does. The distinction is non-obvious in the UI and catches teams off guard at renewal.
Group owners on GitLab.com face a harder constraint: they can remove a member from a group but cannot deactivate or delete the underlying GitLab.com account, which requires GitLab Support involvement.
SCIM error messages are widely reported as generic and unhelpful, making attribute mapping failures difficult to diagnose without verbose IdP logs.
The max-seats-used true-up model draws repeated criticism because a single day of overage - common during bulk onboarding - locks in a charge for the full year.
Custom roles on Ultimate are seen as a step forward, but the limited set of toggleable permissions means many teams still cannot avoid over-provisioning.
Common complaints:
- SCIM configuration errors are difficult to diagnose; GitLab's SCIM error messages are often generic and do not indicate which attribute mapping is failing.
- Blocking a user (self-managed) does not free a license seat - only deactivation does - which surprises many admins who expect blocking to release the seat.
- Group owners on GitLab.com cannot fully manage user accounts (deactivate/delete); they can only remove members from the group, requiring GitLab Support involvement for account-level actions.
- The 'max seats used' true-up model means a single day of overage (e.g., during onboarding) can result in unexpected charges at renewal.
- Custom roles (Ultimate only) have a limited set of toggleable permissions; many granular permissions are not yet available as custom role options.
- Minimal Access role (Premium/Ultimate only) is not available on Free tier, making it difficult to structure large group hierarchies without over-provisioning access.
- CSV bulk import for group members is available but lacks support for importing project-level memberships in bulk.
- Domain allowlist for groups restricts invitations but does not enforce SSO or auto-provision users, leading to confusion about its scope.
- Dormant user auto-deactivation (self-managed) can unexpectedly deactivate service accounts or bot users if not properly configured.
- Personal access token revocation upon user deactivation/blocking breaks CI/CD pipelines silently if tokens are not rotated to group or project access tokens beforehand.
The decision
Manual management is viable for small teams on Free or Premium where group structures are stable and turnover is low. The five-role model covers most access patterns without configuration overhead, and group-level assignments propagate to every app and project automatically.
Once headcount grows or offboarding speed becomes a compliance requirement, the manual path creates real risk: there is no dormant-user alert on GitLab.com, seat overages accumulate silently, and removing access requires touching group membership across potentially many groups.
Teams on Premium or Ultimate with an IdP already running SAML should treat SCIM provisioning as the default, not an upgrade - the seat and audit exposure of manual management compounds quickly at scale.
Bottom line
GitLab's role hierarchy is well-structured and covers most access patterns out of the box, but the manual path has two hard edges: the max-seats-used true-up model punishes onboarding spikes retroactively, and group owners on GitLab.com cannot fully manage user accounts without Support involvement.
For any team above a handful of developers, the combination of SAML SSO and SCIM provisioning - available from Premium - is the only reliable way to keep seat counts accurate and offboarding immediate across every app and project in the group.
Automate GitLab workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.