Chapter 04Lesson 01~160 minutes

Groups, Subgroups, Namespaces, Membership, Roles, Custom Roles, and Access Governance: Concepts, Architecture, and Mental Model

Build a precise mental model of GitLab namespace hierarchy, membership sources, effective roles, custom-role boundaries, sharing, identity-provider integration, and access governance before changing permissions.

NamespacesInheritanceRolesMembershipCustom rolesGovernance

Learning objectives

  • Explain personal namespaces, top-level groups, subgroups, and projects as a hierarchy of ownership and authorization boundaries.
  • Distinguish direct, inherited, shared, and invited-group membership, then compute the effective role without assuming the role shown on one screen is the whole answer.
  • Relate built-in roles, Planner, Security Manager, Owner, administrator authority, and Ultimate custom roles without treating them as interchangeable.
  • Explain membership expiration, group/project sharing, SAML/SCIM/LDAP boundaries, service identities, and seat/billing implications as separate governance concerns.
  • Inspect membership and namespace state read-only before changing access, and explain why this is foundational to reliable DevOps delivery.
Availability baseline (verified 2026-08-21). Groups, subgroups, built-in roles, direct/inherited membership, membership expiration, group/project sharing, and the group/project Members REST APIs are documented across Free, Premium, and Ultimate on GitLab.com, Self-Managed, and Dedicated. The Planner role was introduced in GitLab 17.7. Security Manager is documented as Beta, introduced in GitLab 18.11 and enabled on GitLab.com; treat its Self-Managed status/version carefully. Custom roles are Ultimate. GitLab.com group SAML SSO and SCIM are Premium/Ultimate; Self-Managed identity-provider capabilities have different configuration and tier boundaries. Exact UI labels, seat rules, role-promotion behavior, and administrator restrictions can vary by version and instance policy.

1. Why access governance becomes difficult before the first pipeline exists

Chapters 01–03 established the platform, credentials, and project boundary. Chapter 04 answers a harder operational question: why can a user still reach a project after you removed the role you thought granted access? GitLab authorization is hierarchical. A project can inherit access from the group that owns it, that group can inherit from an ancestor, and additional access can arrive through group sharing or direct project membership.

That means a single row on a project Members page is not automatically the source of truth. Production access review must identify where a permission originates, which role is effective, and which control plane can actually change it. Authentication from Chapter 02 proves who the identity is; Chapter 04 determines what that identity can do after all membership paths are combined.

2. Namespace hierarchy: where ownership and inheritance begin

Namespace and membership inheritance
flowchart TD
U[User account
personal namespace]
G[Top-level group
platform-team]
S[Subgroup
platform-team/payments]
P[Project
platform-team/payments/api]
M1[Direct member at top group
Reporter]
M2[Direct member at subgroup
Developer]
SH[Invited/shared group
max role cap]
U -->|can own personal projects| U
G --> S --> P
M1 -->|inherits downward| S
M1 -->|inherits downward| P
M2 -->|inherits downward| P
SH -.shared access.-> P

A personal namespace is tied to a user. A top-level group is an organizational namespace. A subgroup has exactly one parent and can carry inherited group membership downward. A project belongs to a namespace. Membership normally flows down the hierarchy; a child does not grant access upward to its parent.

GitLab currently allows subgroups across all tiers and offerings. The documentation permits deep nesting, but recommends much shallower structures for manageability and performance. The operational lesson is more important than the numeric limit: hierarchy should express real ownership boundaries, not become a maze that hides access provenance.

3. Direct, inherited, shared, and effective membership

Direct membership is attached to the group or project you are inspecting. Inherited membership arrives from an ancestor group. Shared/invited-group membership arrives because another group was invited to the resource. A user can possess more than one path simultaneously.

Membership path Where it originates Where to change it Operational trap
Direct group member That group That group membership Removing a project row does nothing if the group still grants access.
Inherited member Ancestor group The ancestor membership A lower child role cannot reduce a higher ancestor role.
Direct project member That project Project membership Creates one-off access that is easy to miss during offboarding.
Invited/shared group A group-to-group or group-to-project share The share and/or source-group membership The user may never have been invited individually to the target.
Effective role Combination of applicable paths Change the actual source path(s) GitLab returns the highest applicable access level for effective membership views.
Key rule: You cannot use a lower role on a subgroup/project to cancel a higher role inherited from a parent. If a user is Maintainer on the parent and Developer on a child project, their effective child access remains Maintainer. To reduce access, change or remove the higher source membership.

4. Built-in roles are permission bundles, not job titles

GitLab roles are permission bundles assigned in a group or project scope. A company title such as “team lead” or “security engineer” does not automatically map to one role. Choose the smallest role that supports the work, then verify the actual permission the workflow needs.

Role / authority Mental model Important boundary
Minimal Access Very limited top-level group presence for selected workflows. Not a general project-working role; availability/behavior can depend on group context.
Guest Collaboration with limited project content/operations. Do not assume repository write access.
Planner Planning-focused role introduced in GitLab 17.7. Newer than the traditional role ladder; verify your Self-Managed version.
Reporter Read/report-oriented project participation. Stronger visibility than Guest but not normal code-write authority.
Security Manager Security-focused built-in role currently documented as Beta. Introduced in 18.11; feature status/version matters.
Developer Normal contributor/code-delivery capabilities subject to protections. Protected branches/environments can still deny actions.
Maintainer Broad project/group operational administration. Powerful; do not hand out merely to solve one blocked action.
Owner Top-level/group ownership and high-impact group administration. Owner is a group role; projects do not use Owner as their normal top project role.
Administrator Instance-level Self-Managed administration. Not a namespace membership role and not applicable as a GitLab.com group role.

5. Custom roles are additive, Ultimate governance controls

Custom roles let an eligible organization start from a base role and add selected abilities. They are useful when the built-in bundles are too coarse—for example, delegating one administrative capability without making the identity a full Maintainer. Current GitLab documentation places custom roles in Ultimate across GitLab.com, Self-Managed, and Dedicated.

Do not describe a custom role as “Reporter minus permission X.” GitLab custom roles are built around a base access level plus additional abilities; they are not a universal subtractive permission editor. They also inherit through group hierarchy when assigned to group membership.

Free-path rule: this course never requires creating a custom role. Free learners use built-in-role decision exercises and realistic fixtures. Ultimate learners may optionally inspect or create a disposable custom role only in a training namespace they control.

6. Group/project sharing adds another authorization edge

Sharing a project with a group or a group with another group is different from moving the target into that group. GitLab creates an access relationship. The invited group’s eligible members receive access subject to a maximum role on the share; their resulting role is bounded by both that cap and their role in the invited group.

This is operationally convenient for platform teams, auditors, or cross-functional groups, but it creates an access path that an offboarding checklist limited to “direct project members” will miss. Current GitLab documentation also notes that group invitations are Owner-controlled in modern releases.

7. Expiration and identity providers change lifecycle, not the inheritance rule

A membership can carry an access expiration date. Expiration is useful for contractors, temporary incident responders, or short-lived projects, but it is not a substitute for understanding inheritance. If one direct membership expires while another inherited path remains, access can remain.

Identity systems add another layer:

  • SAML SSO authenticates or associates enterprise identity with GitLab access; GitLab.com group SAML is Premium/Ultimate and configured at the top-level group.
  • SCIM automates identity provisioning/deprovisioning from an identity provider; GitLab.com SCIM is tied to the paid group SSO model.
  • SAML group sync can map IdP groups to GitLab groups/roles on supported tiers.
  • LDAP is a Self-Managed identity integration boundary, not a GitLab.com account feature.
  • Service accounts and access tokens are separate non-human access paths from Chapter 02; removing a human membership does not automatically inventory every automation credential.

8. Access governance also has seat and billing consequences

On paid namespaces, who counts as billable and how seats are consumed can depend on user type, role, namespace structure, and current subscription policy. Do not memorize a static seat rule in a long-lived lesson. Instead, treat billable membership as its own observable state and verify current documentation/API for the top-level group before a provisioning or offboarding decision.

The Group Members API exposes a billable-members endpoint for eligible top-level-group owners. Its purpose is different from /members: one answers “who is billable?”, while another answers “who is directly/effectively authorized here?” Production governance needs both questions when subscription cost is material.

9. Read-only inspection: prove the source before changing the role

Start with the web UI at Group → Manage → Members. GitLab surfaces membership source/inheritance information there. Then use APIs that deliberately distinguish direct and effective views:

# Set only non-secret identifiers. glab reuses the authenticated host from Chapter 02.
GROUP_ID="123456"      # synthetic example
PROJECT_ID="789012"    # synthetic example

# Direct members only.
glab api "groups/$GROUP_ID/members"   --paginate --jq '.[] | {id,username,access_level,expires_at}'

# Effective view: direct + inherited + invited paths visible to the caller.
glab api "groups/$GROUP_ID/members/all"   --paginate --jq '.[] | {id,username,access_level,expires_at}'

# Project direct versus effective membership.
glab api "projects/$PROJECT_ID/members"   --paginate --jq '.[] | {id,username,access_level,expires_at}'
glab api "projects/$PROJECT_ID/members/all"   --paginate --jq '.[] | {id,username,access_level,expires_at}' 

The difference between /members and /members/all is intentional evidence. The /all view returns effective access and, when the same user has multiple ancestor paths, represents the highest applicable access level. Do not infer source solely from one numeric role; correlate with group hierarchy and the UI Source column.

10. DevOps connection: authorization is part of the delivery architecture

Merge rights, protected refs, CI/CD variables, runner administration, environments, registries, security findings, and deployment controls all build on GitLab authorization. A sound pipeline cannot compensate for a namespace that grants too many people Maintainer or Owner. Conversely, a least-privilege structure that operators cannot explain is fragile because incident responders will “temporarily” broaden roles when something breaks.

The production target is therefore an explainable access graph: each identity has a named source, smallest useful role, owner, expiration/lifecycle rule, and evidence path.

Knowledge check

A user is Maintainer on a parent group and Developer directly on a project. What is the effective project role?

Why can deleting a direct project membership fail to remove access?

Are custom roles a Free feature that lets you remove individual permissions from Developer?

Does successful SAML authentication prove a user may push to a protected branch?

What question does /groups/:id/members answer that /members/all does not?

Summary

GitLab access is a graph layered on a namespace tree. Personal namespaces, groups, subgroups, projects, direct membership, inheritance, sharing, identity-provider synchronization, and automation identities can all participate. The safest mental model is: identify the resource → enumerate access paths → compute effective role → change the real source → verify independently.

Official references

Next lesson

Operate the model in a disposable hierarchy

Lesson 2 creates a small group/subgroup/project structure, compares direct and effective membership, and safely exercises role/expiration changes with an optional test identity or deterministic fixture.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.